Repainting a JPanel with data from another object (thread)

不羁的心 提交于 2019-12-11 12:49:18

问题


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

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.

I appreciate any help, thanks!

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

回答1:


Try this:

  public Starter() {

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

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

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

Take a look to concurrency tutorials: http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

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



来源:https://stackoverflow.com/questions/19061351/repainting-a-jpanel-with-data-from-another-object-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!