JFrame repaint();错误

时间:2014-01-24 18:40:47

标签: java swing compiler-errors jframe repaint

所以,我现在正致力于制作一个按键盘命令移动的球。我的问题是,当我调用repaint();时,它会给我一个错误,说明它"无法从类型Component中对非静态方法repaint()进行静态引用。"我做错了什么?

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

public class App extends JFrame{

    JFrame f = new JFrame();
    public static int keyVal = 0, x = 10, y = 10;
    public static void main(String[] args) {
        new App();   
        Ball();
        while(true){
        System.out.println(keyVal);
        try{
            Thread.sleep(50);
        }
        catch(Exception e){}

        }
    }

    public static void Ball(){
        while(true){
            if(keyVal == 65){
            x = x -1;
            }
            else if(keyVal == 68){
            x = x + 1;
            }
        repaint();
        //repaint(x, y, 10, 20);
        }
    }

    public App(){
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Pong");
        f.setSize(30,40);

        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.add(new MyPanel());
        f.pack();
        f.setVisible(true);
    }

    class MyPanel extends JPanel {
        public MyPanel() {
            setBorder(BorderFactory.createLineBorder(Color.black));
        }

        public Dimension getPreferredSize() {
            return new Dimension(500,200);
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);       
            System.out.println("test");
            g.setColor(Color.orange);
            g.fillRect(x, y, 10, 20);
        }  
    }    
}

1 个答案:

答案 0 :(得分:3)

  1. 您的类已经是JFrame子类。无需创建另一个JFrame。取出JFrame f = new JFrame()和所有f.method(..)只需使用method(..)

  2. 请勿使用while(true)Thread.sleep()。你会遇到问题。而是查看How to use a Swing Timer。这是一个简单的example。您还可以找到许多其他示例,只是在如何使用Swing Timer

  3. 进行简单的谷歌搜索
  4. 无需setSize()到框架,您已经pack()了。

  5. 您应该查看How to use Key Bindings。如果不是现在,您会发现使用KeyListener时会出现焦点问题。

  6. Event Dispatch Thead运行您的程序,就像这样

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

  7. 免费赠品

    javax.swing.Timer的简单实现就是这样的

    public App() {
        ...
        Timer timer = new Timer(50, new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                // do something
            }
        });
    }
    

    以下是Timer

    的基本构造
    Timer( int dalay, ActionListener listener )
    

    延迟每次触发事件时延迟的毫秒数。所以在上面的代码中,每50毫秒会发生一些事情。这将实现您尝试使用Thread.sleep所做的事情。您可以在repaint()

    内拨打actionPerformed

    这是您的代码的简单重构,您可以测试

    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.BorderFactory;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class App extends JFrame {
    
        private MyPanel panel = new MyPanel();
        public static int keyVal = 0, x = 10, y = 10;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new App();
                }
            });
        }
    
        public App() {
            Timer timer = new Timer(50, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
    
                        x = x + 5;
    
                    panel.repaint();
                }
            });
            timer.start();
    
            add(panel);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setTitle("Pong");
            pack();
            setLocationRelativeTo(null);
            setVisible(true);
        }
    
        class MyPanel extends JPanel {
    
            public MyPanel() {
                setBorder(BorderFactory.createLineBorder(Color.black));
            }
    
            public Dimension getPreferredSize() {
                return new Dimension(500, 200);
            }
    
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                System.out.println("test");
                g.setColor(Color.orange);
                g.fillRect(x, y, 10, 20);
            }
        }
    }