【问题标题】:Repainting a JPanel with data from another object (thread)使用来自另一个对象(线程)的数据重新绘制 JPanel
【发布时间】:2013-09-27 22:59:37
【问题描述】:

我遇到了一个问题,即 JPanel 从一个对象中获取数据,该对象有一个循环更新其状态变量。

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

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

感谢您的帮助,谢谢!

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

【问题讨论】:

  • 无限循环和 GUI 在同一个线程中运行,您必须创建另一个线程来运行无限循环的逻辑。这就是它挂起的原因。
  • 是的...是我想的,你有我的想法,我会试试

标签: java multithreading swing repaint


【解决方案1】:

试试这个:

  public Starter() {

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

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

如果您在另一个线程中运行无限循环,那么 GUI 将摆脱该循环。

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

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

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

【讨论】:

  • 谢谢!我正在用循环做类似的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
相关资源
最近更新 更多