有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

未绘制来自不同类的java JLabel

我想展示另一个班级的标签。但是,当我将其添加到框架中时,它将不会显示。我试图通过传递框架从计数器类本身提取它,我认为这不是好的实践(忽略它不起作用的事实)。以及下面代码中的内容。有人能帮我解释一下为什么我的解决方案不会显示创建的标签吗?你很可能知道,我对使用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);
    }
}

柜台

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

共 (1) 个答案

  1. # 1 楼答案

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

    enter image description here

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

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

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

    2. 我创建了一个GUI视图,它使用GUI模型。我在view类中创建了JFrame、JPanel和JLabel。可以使用多个类来创建视图。因为这个视图很简单,所以我在一个类中创建了所有内容

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

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

    5. Animation类中的repaint方法调用SwingUtilities invokeLater方法,以确保在事件调度线程上完成JLabel更新。动画循环在单独的线程中运行,以保持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) {
    
                }
            }
        }
    }