使用来自另一个对象(线程)的数据重新绘制 JPanel [英] Repainting a JPanel with data from another object (thread)

查看:41
本文介绍了使用来自另一个对象(线程)的数据重新绘制 JPanel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临一个问题,即 JPanel 从一个对象中获取数据,该对象具有更新其状态变量的周期.

I'm facing a problem where a JPanel takes data from an object which has a cycle updating its state variables.

场景如下:一个JFrame调用对象的一个​​方法,该方法创建第二个JFrame有一个循环然后更新一个状态变量.第二个 JFrame 访问该变量并应显示在 JPanel 中,但不,GUI 挂起.

The scenario is as follows: a JFrame calls a method of the object, the method creates the second JFrame has a cycle then updating a state variable. The second JFrame access that variable and should be displayed in a JPanel, but no, the GUI hangs.

我将问题简化为具有相同行为的示例,以便轻松测试.

I reduced the problem to an example with the same behavior so it can be easily tested.

感谢您的帮助,谢谢!

Starter.java

public class Starter extends JFrame {

    JButton button = new JButton("Fight!");

    public Starter() {

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                OneClass.getInstance().start();
            }
        });
        add(button);
    }

    public static void main(String[] args) {

        Starter frame = new Starter();

        frame.setTitle("Test");
        frame.setSize(400, 300);
        frame.setVisible(true);

    }
}

OneClass.java

public class OneClass {

    private OneFrame frame;
    private int count;
    private static OneClass instance;

    private OneClass() {
    }

    public static OneClass getInstance() {
        if (instance == null)
            instance = new OneClass();

        return instance;
    }

    public void start() {
        frame = new OneFrame();
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        while (true)
        {
            count++;
            System.out.println(count);

            frame.repaint();            
        }
    }

    public int getCount() {
        return count;
    }
}

OneFrame.java

public class OneFrame extends JFrame {

    private OnePanel panel = new OnePanel();

    public OneFrame() {
        setTitle("Test frame");
        setContentPane(panel);
        setResizable(false);
    }
}

OnePanel.java

public class OnePanel extends JPanel {

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Font ft = new Font("Times New Roman", Font.PLAIN, 20);
        g.setFont(ft);

        g.drawString("Count = " + OneClass.getInstance().getCount(), 20, 20);
    }
}

推荐答案

试试这个:

  public Starter() {

    button.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        new Thread() {
          public void run() {
            OneClass.getInstance().start();
          }
        }.start();
      }
    });
    add(button);
  }

由于您的循环在与 GUI 相同的线程中运行,因此一旦您达到无限循环,它就会挂起.

Since your loop runs in the same Thread as the GUI it will hangs once you reach the infinite loop.

如果您在另一个线程中运行无限循环,那么 GUI 将没有该循环.

If you run your infinite loop inside another thread then the GUI will be free of that loop.

这可能不是最好的线程实现

This may not be the best thread implementation

看看并发教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

现在,由于您使用的是类似单例的类,如果您在线程之前调用 getInstance,那么它可能仍会挂起.

Now since you are using a Singleton like class, if you call the getInstance before the thread then it may still hang.

这篇关于使用来自另一个对象(线程)的数据重新绘制 JPanel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆