2

JavaFX を使用してユニバーサル チャット アプリケーションを作成しています。SceneBuilder を使用して listView を作成し、ObservableList以下のようにモデル化しました。

public static ObservableList<String>  members = FXCollections.observableArrayList();

@FXML public static Button send;
@FXML static  ListView names;
@FXML static HTMLEditor outmsg;
@FXML static HTMLEditor showBox;

static void updateRemove(String newuser) {

 //   showBox.setHtmlText(showBox.getHtmlText()+newuser+"<br>  has left room");
    System.out.println(newuser+"has left room");
    members.remove(newuser);
    System.out.println("helloji update remove");


}
@FXML public void sendAction(ActionEvent event)
{


 LoginController.instance.c.sendMessage(outmsg.getHtmlText());


}
public  static void updateList(String name)
{
   // showBox.setHtmlText(showBox.getHtmlText()+"<br> new user entered in room");
    System.out.println("new user enterd"+name);
    System.out.println("beginning update list");
    members.add(name);
    System.out.println(members);
    System.out.println("add user request fullfilled");


}
 public  static void initList(Vector<String> name)
{
    System.out.println("list initializing");
    members.setAll(name);
      System.out.println(members);
    System.out.println("list initialized");

    System.out.println("public room created");


}
public static void showMessage(String msg)
{

   // showBox.setHtmlText(showBox.getHtmlText()+""+msg);
        System.out.println("showing msg   "+msg);
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO



     names.setItems(members);
    // showBox.setHtmlText(showBox.getHtmlText()+"<br> welcome "+Client.username);
         System.out.println("welcome  "+Client.username);

     System.out.println(names.getItems());

}    

}

ただし、そのupdateRemove()メソッドが呼び出されると、例外がスローされます。

java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source)
    at javafx.scene.Parent$1.onProposedChange(Unknown Source)
    at com.sun.javafx.collections.VetoableObservableList.setAll(Unknown Source)
    at com.sun.javafx.collections.ObservableListWrapper.setAll(Unknown Source)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(Unknown Source)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(Unknown Source)
    at com.sun.javafx.scene.control.skin.SkinBase$4.changed(Unknown Source)
    at javafx.beans.value.WeakChangeListener.changed(Unknown Source)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(Unknown Source)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(Unknown Source)
    at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(Unknown Source)
    at javafx.beans.property.StringPropertyBase.markInvalid(Unknown Source)
    at javafx.beans.property.StringPropertyBase.set(Unknown Source)
    at javafx.beans.property.StringPropertyBase.set(Unknown Source)
    at javafx.beans.property.StringProperty.setValue(Unknown Source)
    at javafx.scene.control.Labeled.setText(Unknown Source)
    at com.sun.javafx.scene.control.skin.ListViewSkin$12.updateItem(Unknown Source)
    at javafx.scene.control.ListCell.updateItem(Unknown Source)
    at javafx.scene.control.ListCell.access$000(Unknown Source)
    at javafx.scene.control.ListCell$5.onChanged(Unknown Source)
    at com.sun.javafx.scene.control.WeakListChangeListener.onChanged(Unknown Source)
    at com.sun.javafx.collections.ObservableListWrapper.callObservers(Unknown Source)
    at com.sun.javafx.collections.ObservableListWrapper.remove(Unknown Source)
    at com.sun.javafx.collections.ObservableListWrapper.remove(Unknown Source)
    at truechatter.RoomController.updateRemove(RoomController.java:45)
    at truechatter.Client.run(Client.java:78)

whileinitList()メソッドは正常に動作します。なんで?

4

1 に答える 1

3

UI は GUI スレッドによってのみ更新できます。

使用する:

// create JavaFX scene
Platform.runLater(new Runnable() {
    public void run() {
        members.add(name);
    }
});

initialize() メソッドが機能する理由は、おそらく FX アプリケーション スレッドから既に呼び出されているためです。

javadocリンクから:

public static void runLater(java.lang.Runnable runnable)

指定された Runnable を JavaFX アプリケーション スレッドで将来の不特定の時点で実行します。任意のスレッドから呼び出すことができるこのメソッドは、Runnable をイベント キューにポストし、すぐに呼び出し元に戻ります。Runnables は、ポストされた順序で実行されます。runLater メソッドに渡された runnable は、runLater への後続の呼び出しに渡された Runnable の前に実行されます。

于 2012-12-12T08:14:15.933 に答える