1

JPanel が状態変数を更新するサイクルを持つオブジェクトからデータを取得するという問題に直面しています。

シナリオは次のとおりです。JFrame がオブジェクトのメソッドを呼び出し、メソッドが 2 番目の JFrame を作成し、サイクルがあり、状態変数を更新します。2 番目の 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);
    }
}
4

1 に答える 1

3

これを試して:

  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 を呼び出すと、それでもハングする可能性があります。

于 2013-09-27T23:09:12.130 に答える