2014-04-27 5 views
1

나는 자바 스윙 응용 프로그램에서 일하고 있어요 및 키를 누를 때 난 내 JPanel을 업데이트 할 수 없습니다 ...키를 누를 때 JPanel을 다시 그립니다. (자바)

이는 JFrame의

import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

public class PixelDraw { 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGUI(); 
     } 
    }); 
} 

private static void createAndShowGUI() { 
    //System.out.println("Created GUI on EDT? "+ 
    //SwingUtilities.isEventDispatchThread()); 

    JFrame f = new JFrame("Swing Paint Demo"); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.add(new DrawingPanel()); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
} 
} 

입니다 그리고이게 내 패널 : 그래서

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.BorderFactory; 
import javax.swing.JPanel; 


public class DrawingPanel extends JPanel implements KeyListener { 

    private static final long serialVersionUID = 1L; 

    private int scale = 5; 
    private int bits = 8 * scale; 
    private int cols = 32; 

    //Selection rectangle: 
    private int sX = 0; 
    private int sY = 0; 
    private int sWidth = 1; 
    private int sHeight = 1; 

    private Color BackFill = new Color(140, 140, 140); 
    private Color BackBorder = new Color(70, 70, 70); 

    public DrawingPanel() { 
     //setBorder(BorderFactory.createLineBorder(Color.red)); 

     addKeyListener(this); 

     addMouseListener(new MouseAdapter() { 
      public void mousePressed(MouseEvent e) { 
       //On Click: 

      } 
     }); 

     addMouseMotionListener(new MouseAdapter() { 
      public void mouseDragged(MouseEvent e) { 
       //On Dragg: 
      } 
     }); 

    } 

    public void keyPressed(KeyEvent evt) { 
     int keyCode = evt.getKeyCode(); 

     if (keyCode == KeyEvent.VK_LEFT) { 
      sY = (sY == 0) ? sY : sY-1; 
      if (evt.isControlDown()) { 
       sWidth = (sY == 0) ? sWidth : sWidth+1; 
      } 
     } 

     else if (keyCode == KeyEvent.VK_RIGHT) { 
      sY = (sY == cols) ? sY : sY+1; 
      if (evt.isControlDown()) { 
       sWidth = (sY == cols) ? sWidth : sWidth+1; 
      } 
     } 

     else if (keyCode == KeyEvent.VK_UP) { 
      sX = (sX == 0) ? sX : sX-1; 
      if (evt.isControlDown()) { 
       sWidth = (sY == 0) ? sWidth : sHeight+1; 
      } 
     } 
     else if (keyCode == KeyEvent.VK_DOWN){ 
      sX = (sX == cols) ? sX : sX+1; 
      if (evt.isControlDown()) { 
       sWidth = (sY == cols) ? sWidth : sHeight+1; 
      } 
     } 

     this.repaint(); 
    } 

    public void keyReleased(KeyEvent evt) { 
    } 

    public void keyTyped(KeyEvent evt) { 
    } 

    public Dimension getPreferredSize() { 
     return new Dimension(800, 800); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g);  

     //paint Background 
     for(int x = 0; x <= (cols-1) * bits; x += bits) { 
      for(int y = 0; y <= (cols-1) * bits; y += bits){ 
       g.setColor(BackBorder); 
       g.fillRect(x, y, bits, bits); 
       g.setColor(BackFill); 
       g.fillRect(x+(1*scale), y+(1*scale), bits-(1*scale), bits-(1*scale)); 
      } 
     } 

     //paint selection 
     g.setColor(Color.red); 
     g.drawRect(sX*bits, sY*bits, (sWidth*bits)+(scale-1), (sHeight*bits)+(scale-1)); 
    } 
} 

, 무엇이해야 할 것은 ... 화살표를 누르면 (선택 등) 빨간색 사각형을 이동 ... 또는 Ctrl + 화살표를 누르면 선택을 성장이다

답변

4

KeyListeners에 공통적 인 문제, 즉 구성 요소가 집중되지 않는 문제가 있습니다. KeyListener가 기능하려면, 청취 한 컴퍼넌트는 포커스 가능하고 유저 포커스를 가질 필요가 있습니다. 어느 쪽도 당신의 어플리케이션에는 적용되지 않습니다.

신속한 해결 방법은 setFocusable(true)을 통해 JPanel에 포커스를 맞춘 다음 requestFocusInWindow()을 통해 포커스를 얻는 것입니다.

public DrawingPanel() { 
    addKeyListener(this); 
    setFocusable(true); 
    requestFocusInWindow(); 
} 

그러나이 같은하는 JButton 또는 텍스트 구성 요소와 같은 다른 구성 요소, 즉시 실패합니다, 당신의 GUI에 추가 초점을 훔치고있다. 더 나은 장기적인 솔루션은 키 바인딩을 사용하는 것입니다.


편집

the Key Bindings Tutorial를 확인하시기 바랍니다. 또한이 사이트에서 키 바인딩이 포함 된 게시물을 검색하면 몇 가지 OK 예제가 표시됩니다. For example.

+0

나는이 프로젝트를 몇 시간 전에 시작했으나 많은 기능을 추가하여 아마도 올바른 방법으로 모든 것을 수행하는 것은 나쁜 생각이 아니 었습니다 ... "키를 사용하는 좋은 방법에 대한 자습서를 연결할 수 있습니까? 바인딩 "? :) – XandruDavid

+0

@XandruDavid : 내 기쁨! 내 대답을 편집하십시오. –

+1

+1 @XandruDavid,'나는 그것에 추가 할 기능이 너무 많아서 올바른 방법으로 모든 것을하는 것은 나쁜 생각이 아닙니다 ... '- 나는 그 태도를 좋아합니다. 튜토리얼의 "흔적"링크를보고 스윙에 대한 다른 흥미로운 주제를 찾아보십시오. – camickr