仅在最小化最大化屏幕时才调用paintComponent()

时间:2014-10-23 04:15:29

标签: java swing paintcomponent repaint event-dispatch-thread

我正在尝试开发一个我需要绘制网格的游戏。为此,我使用的是由paintComponent(Graphics g)方法调用的repaint()方法。

问题是重绘方法在无限的While循环内部,除非我最小化并最大化屏幕,否则它永远不会调用paintComponent()方法。之后它工作正常并在while循环中完美地调用paintComponent()

简而言之,我需要通过最小化 - 最大化屏幕来触发它。

有人可以帮帮我吗?

在代码中你可以看到3个类,即Frame.java,MenuHandler.java& Screen.java。代码从Frame类中的main方法开始,并在Screen扩展JPanel时将Screen类添加到自身。但是,仅当用户在菜单上选择“创建地图”时,控件才会进入Screen类。然后MenuHandler类将控件传递给Screen类,其中在createMap方法中调用run方法,并在此run方法中调用repaint方法。     包所以;

public class Screen extends JPanel implements Runnable {
    Frame frame;

    public Screen(Frame frame) {
        this.frame = frame;
    }

    public void createMap() {

        thread.start();
    }

    public void paintComponent(Graphics g) {
        g.setColor(Color.BLUE);

    }

    @Override
    public void run() {

        System.out.println("Success******");

        long lastFrame = System.currentTimeMillis();

        int frames = 0;
        running = true;
        scene = 0;

        // the map grid would be refreshed every 2 ms so that we don't get the
        // flickering effect
        while (running) {

            frames++;

            if (System.currentTimeMillis() - 1000 >= lastFrame) {
                fps = frames;
                frames = 0;
                lastFrame = System.currentTimeMillis();
            }

            // to draw stuff all the time on the screen : goes around 2 millions
            // frames per second. Which is of no use.
            repaint();

            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.exit(0);
    }
}

run方法中的计时器代码:

 public void run() {

    System.out.println("Success");

    long lastFrame = System.currentTimeMillis();

    int frames = 0;
    running = true;
    scene = 0;

    // the map grid would be refreshed every 2 ms so that we don't get the
    // flickering effect
    while (running) {

        frames++;

        if (System.currentTimeMillis() - 1000 >= lastFrame) {
            fps = frames;
            frames = 0;
            lastFrame = System.currentTimeMillis();
        }
        System.out.println("before repaint");
        // to draw stuff all the time on the screen : goes around 2 millions
        // frames per second. Which is of no use.
        ActionListener taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                repaint();
            }
        };

        new Timer(200, taskPerformer).start();
        System.out.println("after repaint");

        try {
            Thread.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    System.exit(0);
 }

1 个答案:

答案 0 :(得分:2)

我想出了这个问题。我只需要添加一行来触发paintComponent方法,而不是通过最小化窗口来实现它。

Frame是我的顶级容器,我正在向框架中添加Screen组件(将JPanel扩展并具有paintComponent的实现)。所以在添加时,我早些时候正在做

frame.add(screen);

我将其更改为:

frame.getContentPane().add(screen);
frame.getContentPane().validate();

添加后调用validate方法为我做了。我不知道它是否有意义,但是这是唯一对我有用的线。

希望它有所帮助。