来自不同 class 的 JLabel 未被绘制

JLabel from a different class not being drawn

我正在尝试显示另一个 class 的标签。但是,当我将它添加到框架时,它不会显示。我已经尝试通过传入框架从计数器 class 本身绘制它,我认为这不是好的做法(忽略它不起作用的事实)。以及下面代码中的内容。谁能帮我解释一下为什么我的解决方案不显示创建的标签?您很可能会说我是使用 JPanel 的新手。

CookieChaser Class

public class CookieChaser extends JPanel {

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame("Cookie Chaser");
        CookieChaser game = new CookieChaser();
        frame.add(game);
        frame.setSize(1000, 1000);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        counter Score = new counter(frame);
        cookie Cookie = new cookie();
        JLabel item = counter.getLabel();
        frame.add(item);
        frame.setVisible(true);

        while (true) {
            game.repaint();
            Thread.sleep(10);
        }
    }
    @Override
     public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    }
}

计数器Class

public class counter {
    int count;
    static JLabel text;

    public counter(JFrame frame){
        count = 0;
        text = new JLabel(String.valueOf(count));
        text.setLocation(0,0);
        text.setSize(50,50);
    }

    public static JLabel getLabel(){
        return text;
    }

我修改了您的代码以创建以下 Swing GUI。

每当我创建 Swing 游戏或应用程序时,我都会使用模型/视图/控制器模式。这意味着我创建了一个 GUI 模型。 GUI 模型包含我的 GUI 需要的所有字段。接下来,我创建一个 GUI 视图,它从 GUI 模型中读取值。最后,我创建一个或多个 GUI 控制器,它们更新 GUI 模型并刷新/重绘 GUI 视图。

我对您的代码进行了以下更改:

  1. 我创建了一个 GUI 模型。我创建了计数器 class。 Counter class 所做的只是保存一个计数器值。

  2. 我创建了一个 GUI 视图,它使用 GUI 模型。我在视图 class 中创建了 JFrame、JPanel 和 JLabel。您可以使用多个 class 来创建视图。由于这个视图很简单,所以我在一个 class.

  3. 中创建了所有内容
  4. 所有 Swing 应用程序都必须从调用 SwingUtilities invokeLater 方法开始。 invokeLater 方法将 Swing 组件的创建和更新放在 Event Dispatch thread 上。 Oracle 和我坚持所有 Swing 应用程序都以这种方式启动。

  5. 我创建了一个单独的 Animation runnable,以便您可以看到 JLabel 更新。我每秒增加一次计数器。

  6. Animation中的repaint方法class调用SwingUtilities invokeLater方法来保证JLabel的更新是在Event Dispatch线程上完成的。动画循环在单独的线程中运行以保持 GUI 响应。

这是修改后的代码。

package com.ggl.testing;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CookieChaser implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CookieChaser());
    }

    private JLabel counterLabel;

    @Override
    public void run() {
        Counter counter = new Counter();

        JFrame frame = new JFrame("Cookie Chaser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel mainPanel = new JPanel();
        counterLabel = new JLabel(" ");
        mainPanel.add(counterLabel);

        frame.add(mainPanel);
        frame.setSize(300, 200);
        frame.setVisible(true);

        new Thread(new Animation(this, counter)).start();
    }

    public void setCounterLabel(String text) {
        counterLabel.setText(text);
    }

    public class Counter {
        private int counter;

        public int getCounter() {
            return counter;
        }

        public void setCounter(int counter) {
            this.counter = counter;
        }

        public void incrementCounter() {
            this.counter++;
        }
    }

    public class Animation implements Runnable {

        private Counter counter;

        private CookieChaser cookieChaser;

        public Animation(CookieChaser cookieChaser, Counter counter) {
            this.cookieChaser = cookieChaser;
            this.counter = counter;
        }

        @Override
        public void run() {
            while (true) {
                counter.incrementCounter();
                repaint();
                sleep(1000L);
            }
        }

        private void repaint() {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    cookieChaser.setCounterLabel(Integer.toString(counter
                            .getCounter()));
                }
            });
        }

        private void sleep(long duration) {
            try {
                Thread.sleep(duration);
            } catch (InterruptedException e) {

            }
        }
    }
}