2014-02-06 151 views
1

我正在爲我的java課程進行keylistener練習,但過去一週一直在卡住。我很欣賞任何有用的建議。這次演習是:使用Java中的keylistener在GUI中使用箭頭鍵繪製線條

「寫繪製使用箭頭鍵線段程序的 線從幀的中心開始,向華東,華北, 西,或南畫時,右箭頭鍵,上箭頭鍵,左箭頭鍵, 或單擊向下箭頭鍵。「

經過調試我想通了KeyListener的工作,以獲得對drawComponent(圖形克)點 ,但是當我按下 向下或向右只汲取,只有工作的第一對夫婦倍。這裏是我的代碼:

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

@SuppressWarnings("serial") 
public class EventProgrammingExercise8 extends JFrame { 

    JPanel contentPane; 
    LinePanel lines; 
    public static final int SIZE_OF_FRAME = 500; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        EventProgrammingExercise8 frame = new EventProgrammingExercise8(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public EventProgrammingExercise8() { 
     setTitle("EventExercise8"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(SIZE_OF_FRAME, SIZE_OF_FRAME); 
     contentPane = new JPanel(); 
     lines = new LinePanel(); 
     contentPane.add(lines); 
     setContentPane(contentPane); 
     contentPane.setOpaque(true); 
     lines.setOpaque(true); 

     lines.setFocusable(true); 
     lines.addKeyListener(new ArrowListener()); 
    } 

    private class LinePanel extends JPanel { 

     private int x; 
     private int y; 
     private int x2; 
     private int y2; 

     public LinePanel() { 
      x = getWidth()/2; 
      y = getHeight()/2; 
      x2 = x; 
      y2 = y; 
     } 

     protected void paintComponent(Graphics g) { 
      g.drawLine(x, y, x2, y2); 
      x = x2; 
      y = y2; 
     } 

     public void drawEast() { 
      x2 += 5; 
      repaint(); 
     } 

     public void drawWest() { 
      x2 -= 5; 
      repaint(); 
     } 

     public void drawNorth() { 
      y2 -= 5; 
      repaint(); 
     } 

     public void drawSouth() { 
      y2 += 5; 
      repaint(); 
     } 

    } 

    private class ArrowListener extends KeyAdapter { 

     public void keyPressed(KeyEvent e) { 
      int key = e.getKeyCode(); 
      if (key == KeyEvent.VK_RIGHT) { 
       lines.drawEast(); 
      } else if (key == KeyEvent.VK_LEFT) { 
       lines.drawWest(); 
      } else if (key == KeyEvent.VK_UP) { 
       lines.drawNorth(); 
      } else { 
       lines.drawSouth(); 
      } 
     } 

    } 

} 

謝謝。

+0

就個人而言,我會使用[鍵綁定API](http://docs.oracle.com/javase/tutorial/uiswing/ misc/keybinding.html),從長遠來看這是一個更安全的賭注,但你可能有理由不這樣做... – MadProgrammer

+0

謝謝。我聽說過關鍵綁定,但沒有看到它們被使用。通常我們只應該使用我們在課堂上看到的技巧。我會進一步看看鍵綁定雖然.. –

回答

1

有幾件事情我跳出...

public LinePanel() { 
    x = getWidth()/2; 
    y = getHeight()/2; 

這將是一個問題,因爲當時你構建類,它的大小是0x0

除了事實,你沒有所謂的super.paintComponent打破了油漆鏈,你似乎認爲這幅畫是accumaltive ...

protected void paintComponent(Graphics g) { 
    g.drawLine(x, y, x2, y2); 
    x = x2; 
    y = y2; 
} 

繪畫在Swing是破壞性的。也就是說,您預計將擦除Graphics上下文並從頭重新生成輸出。該工作paintComponent是清除Graphics方面準備好畫,但你不叫super.paintComponent,打破了油漆鏈和打開自己註冊了一些非常醜陋的油漆文物

一個框架調用setSize(SIZE_OF_FRAME, SIZE_OF_FRAME);是危險的,因爲它不保證框架邊框的插入,這將減少可供您查看的區域。

這....

contentPane = new JPanel(); 
lines = new LinePanel(); 
contentPane.add(lines); 
setContentPane(contentPane); 

不是必需的,它只是增加了混亂到您的代碼。這也是一個很好的暗示,你的代碼出了什麼問題。

JPanel默認使用FlowLayout。 A FlowLayout使用該組件的首選大小來確定如何最好地佈置組件。組件的默認首選大小0x0

您可以使用...

lines = new LinePanel(); 
add(lines); 

代替或設置contentPane使用BorderLayout這將有助於...

嘗試增加lines.setBorder(new LineBorder(Color.RED));看到添加你得到什麼...

奇怪的是,在我的測試中,你的KeyListener工作正常...

基本上...

  • 重寫LinePanelgetPreferredSize方法,並返回你想用面板的大小。
  • 使用java.util.List來維護需要着色的Point的列表。
  • 在你的paintComponent方法中,使用PointList來實際呈現你的線條。這將會有點棘手,因爲你需要兩分和List可能包含奇點數,但是可行的。
  • 通過使用首選大小或其他方法(如使用ComponentListener和監控componentResized方法來計算開始Point這會變得棘手,因爲您的組件可能會在首次創建併發布到屏幕上,你會想要忽略未來的事件,一旦你有你的第一點)
+0

非常有幫助,謝謝! –

+0

我很高興它有幫助;) – MadProgrammer