java - 我的重写绘制方法没有被调用

标签 java multithreading swing paint

我有一个 JPanel 旨在充当我的游戏的 HUD,自然地,我已经重写了绘制方法来执行我自己的自定义显示,这确实被调用,但仅在调整大小或最大化、最小化框架时,而不是当我的游戏循环告诉它重新绘制()时。这对我来说似乎特别奇怪,因为我的另外两个面板被重新粉刷得很好。

这是我的 HUD 类:

package base;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.BoxLayout;
import javax.swing.JPanel;

public class HUD extends JPanel {

    private Shiphud[] shiphuds;

    public HUD(Ship[] ships) {
        shiphuds = new Shiphud[ships.length];
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i] = new Shiphud(ships[i]);
            this.add(shiphuds[i]);
        }
    }
    @Override
    public void paint(Graphics g) {
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i].repaint();
        }
    }
    public void run() {
            repaint();
    }
    private class Shiphud extends JPanel {

        private Ship ship;

        public Shiphud(Ship ship) {
            this.ship = ship;
        }
        @Override
        public void paint(Graphics g) {
            if (ship != null) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                int fullbar = (int) (this.getWidth() * 0.8);

                g.setColor(Color.GREEN);
                g.fillRoundRect(getWidth() / 10, getHeight() / 10,
                        (int) ((ship.energy / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.blue);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.4),
                        (int) ((ship.fuel / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.YELLOW);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.6),
                        (int) ((ship.ammo / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.MAGENTA);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.8),
                        (int) ((ship.special / 1000) * fullbar), getHeight() / 6, 10, 10);
                System.out.println("here" + System.currentTimeMillis());
            }
        }
    }
}

它与我的其他两个面板一起在我的游戏类更新中被调用

public void update() {
  ...
    display.run();
    display2.run();
    hud.run();
}

由我的 JFrame 调用

public void runFrame() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            gameLoop();
        }
    };
    thread.start();
}
public void gameLoop() {
    while (true) {
        long beginTime = System.nanoTime();
        game.update();
        long timeTaken = System.nanoTime() - beginTime;
        long timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000;  // in milliseconds
        if (timeLeft < 10) {
            timeLeft = 10;   // set a minimum
        }
        try {
            // Provides the necessary delay and also yields control so that other thread can do work.
            Thread.sleep(timeLeft);
        } catch (InterruptedException ex) {
        }
    }
}

我已经尝试解决这个问题很长时间了,但我就是不明白,任何帮助将不胜感激

最佳答案

不要重写 Swing 中的 paint 方法。

改为覆盖paintComponent

然后您不必为子组件调用 paintrepaint - 这将自动完成。

关于java - 我的重写绘制方法没有被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6818443/

相关文章:

java - 终止线程池中的线程

java - 如何确保多个 Guava 缓存不互相锁定?

linux - 如何在 Linux 上使用 clone() 创建一个真正的线程?

java - KeyPressedEvent 到 JTextArea 的 SetText

java thread.sleep 也使 swing ui 进入休眠状态

可滚动表的 Java Swing 布局?

java - 通过java代码清除akamai中缓存的url?

c# - 如何从不同的线程访问控件?

java - 创建 SingleBlockingQueue 同步器

java - 将 Swing 应用程序转换为 JavaFX