2

num0ボタンをランダムに押すと発生する .setText クラッシュの問題を修正しようとしています。

  • しかし、使用することでしか解決できないようです new Thread(new Runnable() { __overwrite__swing__textfields___ });が、その場合はアクセスできませんJTextField

したがってRunnableOutput、送信して適用するクラスを作成しましたが、それも失敗しています。例:

RunnableOutput.java

package ui;

import java.awt.ComponentOrientation;
import javax.swing.*;

/**
 * JTextField - Wrapper for thread-safe 
 * 
 * @author root
 */
public class RunnableOutput implements Runnable {
  private JTextField outputArea;
  private String messageToAppend;

  // initialze outputArea and message
  public RunnableOutput(JTextField output, String message) {
    outputArea = output;
    messageToAppend = message;
  }

  @Override
  public void run() {
    outputArea.setText(messageToAppend);
  }

}

Menu.java:

public static JTextField nameTextField0 = new JTextField(20);
public void IPpanel(JPanel configPanel) { 

  JPanel Numlock = new JPanel(new GridLayout(0,12));
  JButton num0 = new JButton("0"); 
  num0.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {

      // Fails: 
      // was expecting this should fixed it but indeed still not
      SwingUtilities.invokeLater(
        new RunnableOutput(nameTextField0, "Unit test: 0"));       

      // Fails: 
      // wont work few times works but when randomly i press the 
      // button it fails
      // Same result with: SwingUtilities.invokeAndWait();
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          nameTextField0.setText("Unit test: 1");
        }
      });

      // Works: does not freez but does not change/apply the values
      new Thread(new Runnable() {
        Menu.nameTextField0.setText("Unit test: 2");
      });        

    }
  });
  Numlock.add(num0); 

  configPanel.setLayout(new GridLayout(0,1));
  configPanel.add(Numlock);

}

ファローアップ:

  • ポリモーフィズムを使用し、それらすべてを修正します
4

1 に答える 1

0

1)コード行を追加する必要があります

revalidate()
repaint();

JComponentsすでに表示されているものに追加する場合Container

JComponents2)既に表示されているものへの追加/削除Containerは で行う必要があり、 /EventDispatschTreadにラップする必要がありますinvokeLaterinvokeAndWait

3) ラッピングすることをお勧めします (イベントはメソッドとして宣言されますThread Safe) setText()、呼び出された fromに、またはappend()invokeLaterRunnable#ThreadExecutorutil.Timer

4) SwingTimer (EDT で保証された出力) または Runnable#Thread (invokeLater / invokeAndWait にラップする必要があります) を使用します。

5) Swing GUI の場合は、SwingWorker を使用する方が良いでしょう。Runnable#Thread with/or Executor/util.Timer の方が良いかもしれません。

6) EDTをブロックしない

7) SSCCEで質問をより早く編集するためのアドバイスとして

編集

   new Thread(new Runnable() {

        public void run() {

            final RunnableOutput a = new RunnableOutput();

            if (SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        a.setText(nameTextField0, text);
                    }
                });
            } else {
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {

                        @Override
                        public void run() {
                            a.setText(nameTextField0, text);
                        }
                    });
                } catch (InterruptedException ex) {
                    Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }).start();
于 2012-04-13T10:29:03.087 に答える