2014-01-24 76 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); 
    }