0

そのため、押された後に新しいユーザー(別のクラスから取得された名前)をリストに追加するボタンがあります。ビルドして実行した後、手動でボタンをクリックしてボタンを押すと、正常に動作します。問題は、別のメソッドを介して ActionEvent メソッドを呼び出すと、System.out.println テキストが出力されますが、新しいエントリがリストに追加されないことです。

助言がありますか?

ボタンを押すと呼び出されるコードは次のとおりです(「<--」でマークされた行は、手動でボタンを押した場合にのみ機能するように見える行です):

public void actionPerformed(ActionEvent e) {

        listModel.insertElementAt(name, index); // <--
        System.out.println("finished running action");
    }

私のコードのより完全なバージョンは次のとおりです。

public void actionPerformed(ActionEvent e) {
        System.out.println("ran action");

        addAuthor();
        System.out.println("authornamefinalfunc name: " + name);

        //Reset the text field.
        employeeName.requestFocusInWindow();
        //employeeName.setText("");

        //Select the new item and make it visible.
        list.setSelectedIndex(index);
        list.ensureIndexIsVisible(index);
        System.out.println("ran action final");
    }
    private void addAuthor()
    {
        String name = Global.s;

        int index = list.getSelectedIndex(); //get selected index
        if (index == -1) { //no selection, so insert at beginning
            index = 0;
        } else {           //add after the selected item
            index++;
        }

        listModel.insertElementAt(name, index);

    }
4

1 に答える 1

0

メソッドはaddAuthor常にイベント ディスパッチ スレッドで呼び出されていますか? JList(および Swing のすべて) は同期化されておらず、スレッド セーフでもないため、Swing 関連の変更/アクションはそのスレッドで実行する必要があります。このaddAuthorメソッドは Swing コンポーネントと対話するため、そのスレッド以外から呼び出してはなりません。これは、そのクラスにある他のメソッドにも当てはまります (main適切に記述されている場合はメソッドを除く)。

イベント ディスパッチ スレッドではないスレッドから 、または Swing コンポーネントと直接やり取りするその他のメソッドを呼び出す必要がある場合はaddAuthor、次のような方法でメソッドを呼び出します (これは、Swing フォームの名前が「myUI」であることを前提としています)。

SwingUtilities.invokeAndWait(new Runnable() {
  @Override public void run() {
    addAuthor();
  }
});

invokeLaterコードを実行し、終了を待たない場合にも使用できます。

コードがどのスレッドから実行されているかわからない場合は、次の経験則を使用してください。

  1. メソッド内にあるコードmain、またはメソッドによって呼び出されるコードmain(深さのレベルに関係なく) は、「メイン」スレッドによって実行されます。
    • たとえば、mainメソッドが を呼び出しfoo()、それが を呼び出しbar()、さらに が を呼び出しますfoobar()。これらすべてのメソッドのすべてのコードは、mainスレッドによって実行されます。
  2. たとえば、のようなものを使用して新しいスレッドを手動で作成するとnew Thread(...).start()、そのコードと、それによって呼び出されるすべてのメソッドのコードが、このスレッドから実行されます。
  3. UI によって呼び出されるすべてのリスナー コード (たとえばActionListener、ボタンを押したときの上記) は、イベント ディスパッチ スレッドのコードによって呼び出されます。

イベント ディスパッチ スレッドで実行されるコードは、Swing コンポーネントと安全にやり取りできる唯一のコードです。したがって、Swing コンポーネントと対話するコードを含むメソッド (自分のメソッドActionListenerや自分のaddAuthorメソッドなど) は、EDT で実行されているコードからのみ呼び出す必要があります。

他のスレッド (上記の 1 と 2) からメソッドを呼び出したい場合は、直接実行できないため、上記で示したメソッドを使用する必要があります。

于 2014-06-17T18:19:31.990 に答える