【问题标题】:JFrame repaint(); errorJFrame 重绘();错误
【发布时间】:2014-01-24 18:40:47
【问题描述】:

所以,我目前正在制作一个按键盘命令移动的球。我的问题是,当我调用 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);
        }  
    }    
}

【问题讨论】:

  • 您需要在实例上调用 repaint()。即f.repaint()
  • 不要使用 KeyListener。相反,您应该使用Key Bindings。有关更多信息和完整的工作示例,请参阅Motion Using the Keyboard

标签: java swing compiler-errors jframe repaint


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

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

  3. 不需要setSize()到框架,你已经pack()它了。

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

  5. Event Dispatch Thead 运行你的程序,像这样

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

免费赠品

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 执行的操作。您可以从actionPerformed 内部调用repaint()


这是您的代码的简单重构,您可以对其进行测试

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);
        }
    }
}

【讨论】:

  • 好的,谢谢。我会试试看,然后尽快回复你
  • +1 优秀答案,一年两年,将像 MadProgramer 或 HFOE 一样
猜你喜欢
  • 2012-06-18
  • 2023-03-08
  • 2014-06-12
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多