2014-11-04 57 views
0

在下面的代碼中,箭頭鍵用於在etch-a-sketch中繪製一條線(但您必須先調整窗口大小以在正確的時間觸發面板的焦點請求 - 這是針對不同的問題時間,也許)。圖形命令g.drawLine()發生在keyPressed()函數中,repaint()不是顯式調用的,但圖像會在按下箭頭鍵時自動更新。這是爲什麼?我所看到的所有文檔都只是談論JPanel在調整大小或發現大小時自動重新繪製自己。什麼是導致此代碼重新繪製自己?

import java.awt.event.*; 
import java.awt.*; 
import javax.swing.*; 

public class Etch extends JPanel implements KeyListener{ 
    public int xPrev, yPrev, xNew, yNew, inc; 

    public Etch(int start){ 
     xPrev = start; 
     yPrev = start; 
     xNew = start; 
     yNew = start; 
     inc = 10; 
     addKeyListener(this); 


    } 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     this.requestFocusInWindow(); 
    } 


    public static void main(String[] args) 
    { 
     JFrame w = new JFrame("Keyboard"); 
     w.setBounds(100, 100, 600, 600); 
     w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     Etch panel = new Etch(200); 
     panel.setFocusable(true); 
     panel.setBackground(Color.RED); 

     Container c = w.getContentPane(); 
     c.add(panel); 

     w.setResizable(true); 
     w.setVisible(true); 

    } 

    public void keyPressed(KeyEvent e){ 
     int code = e.getKeyCode(); 


     if (code == KeyEvent.VK_UP){ 
      xPrev = xNew; 
      yPrev = yNew; 
      yNew -= inc; 

     } 
     if (code == KeyEvent.VK_DOWN){ 
      xPrev = xNew; 
      yPrev = yNew; 
      yNew += inc; 

     } 
     if (code == KeyEvent.VK_LEFT){ 
      xPrev = xNew; 
      yPrev = yNew; 
      xNew -= inc; 
     } 
     if (code == KeyEvent.VK_RIGHT){ 
      xPrev = xNew; 
      yPrev = yNew; 
      xNew += inc; 
     } 

     Graphics g = this.getGraphics(); 
     g.setColor(Color.BLUE); 
     g.drawLine(xPrev, yPrev, xNew, yNew); 
    } 

    // Not used but required by the KeyListener interface 
    public void keyReleased (KeyEvent e) { } 

    public void keyTyped (KeyEvent e) { } 
} 
+1

'this.requestFocusInWindow();'是'paintComponent'方法中的一個壞主意。繪畫應繪製當前狀態並永不改變組件的狀態 – MadProgrammer 2014-11-04 23:11:59

回答

2
  • this.requestFocusInWindow();paintComponent方法中的一個壞主意。繪畫應繪製當前狀態並永不改變組件的狀態
  • getGraphics不是如何在Swing中完成繪畫。自定義繪畫應該在paintComponent方法的範圍內完成。有關更多詳細信息,請參見Painting in AWT and SwingPerforming Custom Painting
  • 考慮使用密鑰綁定而不是KeyListener,因爲您可以控制觸發按鍵事件所需的焦點級別。有關詳細信息,

記住見How to Use Key Bindings,你不控制Swing中的油漆工藝,油漆週期可以由任何數量的事件,其中大部分你不實際控制的被觸發。嘗試在這個過程中工作,而不是外面。

首先創建一個Listjava.awt.Point。發生關鍵事件時,將每個點添加到List。使用paintComponent遍歷List並繪製Point之間的連線...

+0

感謝您提出有關如何改進代碼的評論。鑑於我發佈的代碼不是實現其目的的好方法,我仍然對它的實際工作方式感到困惑,即在每次箭頭鍵事件之後導致屏幕圖像更新的原因。對圖形對象所做的任何更改都會導致屏幕被重新繪製?這對我來說似乎不太可能,因爲每次按下按鍵時都會重新繪製屏幕。 – 2014-11-05 12:52:46

+0

這是因爲Swing使用被動繪畫alrogtihim,也就是說,只有當RepaintManager認爲它需要時,纔會調用paintComponent方法。這使您可以使用getGraphics繪製最後一個已知的繪製週期結果,這也是當paintComponent再次被調用時它被擦乾淨的原因。繪畫應該在paintComponent方法的範圍內完成,這樣,您就知道何時需要更新屏幕。您的關鍵事件應該調用repaint來發出更新UI的請求 – MadProgrammer 2014-11-05 20:09:55

相關問題