2014-01-24 75 views
0

所以,我一直在學習Java,而且我還很新,所以請耐心等待。我最新的目標是圖形程序,這是一個關於鍵盤控制的測試。出於某種原因,該程序不會顯示矩形。通常paint()是獨立運行的,但是由於某種原因,它不是。我查看了我在網上做過的其他程序和其他程序,但我仍然無法弄清楚。Java JFrame矩形

import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import javax.swing.JFrame; 

public class App extends JFrame{ 

    public static int keyVal = 0; 
    public static void main(String[] args) { 
     new App(); 
     while(true){ 
      System.out.println(keyVal); 
      Wait.ms(50); 
     } 
    } 

    public App(){ 
     JFrame f = new JFrame(); 

     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setTitle("Pong"); 
     f.setSize(300,400); 

     f.setLocationRelativeTo(null); 

     f.addKeyListener(new KeyListener(){ 
      public void keyPressed(KeyEvent e){ 
       keyVal = e.getKeyCode(); 
      } 

      public void keyReleased(KeyEvent e){ 
       keyVal = 0; 
      } 

      public void keyTyped(KeyEvent e){} 
     }); 

     f.setVisible(true); 
    } 

    public void paint(Graphics g){ 
     g.setColor(Color.orange); 
     while(true){ 
      g.drawRect(20, 20, 100, 60); 
     } 
    } 

} 
+1

第1步 - 從來沒有把一個',而(真)'在'paint'功能 - 它永遠不會結束,你的用戶界面將鎖定。 – Krease

+0

感謝您的提示!雖然可悲,但它仍然無法正常工作。 :/ –

+0

對不起,沒有時間進一步研究 - 我掃描了一下,發現了一個明顯的問題,並認爲即使我沒有解決問題,我也可能至少有一點幫助。 – Krease

回答

2
  1. 一個不上頂級容器,如JFrame油漆,因爲他們已經攜帶繪畫部件的負載,而不是雙緩衝。
  2. 改爲使用自定義JPanel來繪製並覆蓋其paintComponent方法並致電super.paintCompoent。然後將該面板添加到框架。

    public class MyPanel extends JPanel { 
        @Override 
        protected void paintComponent(Graphics g) { 
         super.paintComponent(g); 
        } 
    
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(300, 300); 
        } 
    } 
    
  3. 在代碼還要注意上面,我推翻了getPreferredSize()方法。這是你在JPanel上繪畫時想要做的。原因是沒有設置首選大小,所以你需要設置它。這也應該使用,所以你不必設置一個大小的框架,它擁有它。相反,只需致電frame.pack(),並且JPanel的首選尺寸將得到尊重。

  4. 請勿在Swing應用中使用KeyListener。相反,使用Key Bindings,您可能會遇到焦點問題,其中包括使用KeyListener。關於如何使用簡單的密鑰綁定,您可以看到一個示例Here
  5. 你也應該運行在事件指派線程你的揮杆應用這樣

    public static void main(String[] args) { 
        SwingUtilities.invokeLater(new Runnable(){ 
         @Override 
         public void run() { 
          new MyApp(); 
         } 
        }); 
    } 
    
  6. 不要在您的paintComponent方法使用while。你會遇到問題。如果你想要重複繪製某些東西,比如動畫,你可以使用javax.swing.Timer進行研究。你可以看到一個例子here或任何數量的SO帖子,你可以找到一個簡單的搜索如何使用擺動計時器。

  7. 此外,您的App類已經是JFrame sublcass。沒有必要在構造函數中創建另一個JFrame。只需將組件添加到它,像這樣

    public App() { 
        add(new MyPanel(), BorderLayout.CENTER); 
        add(new JButton("Button"), BorderLayout.SOUTH); 
    }