我试图将我的javafx组合框项目绑定到observablelist;当列表更新时,组合框项目也会更新(添加、删除或修改)。我试图将侦听器添加到组合框项目中,但仍然出现“Not on FX application thread”异常。这是我的代码:
模型
{
…
private ObservableList<String> programList = FXCollections.observableArrayList();
…
some code initialize programList from database
…
private ListProperty<String> programListProperty = new SimpleListProperty<>(programList);
…
some code update programList periodically
…
}
控制器呢
{
@FXML ComboBox programComboBox;
model.programListProperty().addListener((v, oldValue, newValue) ->
Platform.runLater(() -> {
programComboBox.getItems().clear();
programComboBo.getItems().add(every item in model.programList);
}));
}
我也试过这种方法,但都不管用
{
@FXML ComboBox programComboBox;
programComboBox.itemsproperty().bind(model.programListProperty());
}
既然你还没有发布一个MCVE,我们只能做这么多来帮助你,这里有一个例子,说明你在努力做什么,我尽了最大努力模仿你已经拥有的东西,你必须看到什么对你不起作用,并纠正它,但这里有一个例子,说明我做了什么,经过测试,对我有效
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
Model model = new Model();
ComboBox<String> comboBox = new ComboBox<>();
comboBox.itemsProperty().bind(model.getProgramListProperty());
VBox vBox = new VBox();
vBox.setAlignment(Pos.CENTER);
vBox.getChildren().add(comboBox);
primaryStage.setScene(new Scene(vBox));
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
}
模范班
public class Model{
private ObservableList<String> programList = FXCollections.observableArrayList();
private ListProperty<String> programListProperty = new SimpleListProperty<>(programList);
Model(){
updateListFromDatabase();
continuousDatabaseUpdate();
}
ListProperty<String> getProgramListProperty() {
return programListProperty;
}
private void continuousDatabaseUpdate() {
new Timer().schedule( //Schedule a timer to fire a task at an interval
new TimerTask() {//Create a new TimerTask that runs a list update
@Override
public void run() {//What its running
//Important my update is wrapped in Platform.runLater so I DON'T block the main thread
Platform.runLater(() -> updateListFromDatabase());
}
},
0,//Delay 0
2/*Number of seconds*/ * 1000/*turn milliseconds into seconds*/);
}
private void updateListFromDatabase(){//Create a list of varying size and changing numbers
programList.clear();//Clear current list
double size = Math.random() * 10 + 1;
for (int i = 0; i < size; i++) {
programList.add(String.valueOf(Math.random() * 20 + 1));//Add random values
}
}
}
这可能不是最佳解决方案,因为我们看不到您在MCVE中尝试做什么,您刚刚发布了一些代码,并希望其他人来填充其余的代码
此外,我不建议在列表中添加侦听器,我会在您与数据库对话时检查列表是否需要更新。下面是我引用的内容
model.programListProperty().addListener((v, oldValue, newValue) ->
Platform.runLater(() -> {
programComboBox.getItems().clear();
programComboBo.getItems().add(every item in model.programList);
}));
否则这就是数据流
检查数据库更改-
VS
检查数据库更改-
除非你的html" target="_blank">数据库在更新时通知你,否则你的方式是有意义的,我怀疑,因为你说“一些代码定期更新程序列表”,这就是为什么MCVE会有帮助
注意:这个解决方案对您的实现做了一些假设,因为您没有提供一个最小的、完整的、可验证的代码示例。
您不需要为此使用绑定。组合框
使用可观察列表
填充其项。这里的关键词是可观察的。这意味着,当基础的列表
更改时,组合框
将“看到”更改并自动更新其显示的项目。
使用setItems()
方法初始化ComboBox
,并将observeList
作为参数传递给它:
comboBox.set项目列表
从那里,每当更新程序列表
时(添加、删除项目等),组合框
将反映更改,而无需您提供任何进一步的代码。
查看以下完整示例:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class ComboBoxListenerExample extends Application {
// This is our ObservableList that will hold our ComboBox items
private ObservableList<String> items = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple interface
VBox root = new VBox(5);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
// Simple ComboBox
ComboBox<String> comboBox = new ComboBox<>();
// Let's "permanently" set our ComboBox items to the "items" ObservableList. This causes the
// ComboBox to "observe" the list for changes
comboBox.setItems(items);
// Create a button that will reload data from our "database"
Button button = new Button("Refresh Data");
// The items.setAll()` method replaces all items in the list with our new list of items
button.setOnAction(event -> items.setAll(reloadDatabase()));
root.getChildren().addAll(comboBox, button);
// Show the Stage
primaryStage.setWidth(300);
primaryStage.setHeight(300);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
// Sample method to simulate reloading the database information
private List<String> reloadDatabase() {
List<String> items = new ArrayList<>();
for (int i = 0; i < 5; i++) {
items.add(getRandomWord());
}
return items;
}
// Just a helper method specific for this example; it simply returns a random word.
// This is used to simulate loading new data from the database
private String getRandomWord() {
List<String> words = Arrays.asList("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Red", "Blue", "Green", "Yellow", "Left", "Right", "Top", "Bottom");
Random random = new Random();
return words.get(random.nextInt(words.size()));
}
}
运行示例时,组合框
为空。每次单击“刷新数据”按钮时,基础的可观察列表
,项
,都会用新的随机项列表进行更新;组合框会立即更改以反映这些更改。
不在JavaFX应用程序线程上:
那么,那个错误消息呢?关于StackOverflow,有很多问题和答案已经解决了这个问题,但这里有一个简短的解释:
我假设您正在后台线程上从数据库加载数据,这很好!但是,您不能从该线程对用户界面进行任何更改或更新。所有用户界面更新都需要在JavaFX应用程序线程上完成。
这非常简单。当您在调用数据库方法时更新
List
时,将该更新包装在一个Platform.run稍后()
调用中:
Platform.runLater(() -> programList.setAll(yourNewList));
这将在JFX应用程序线程上对列表进行更新。问题解决了!
我需要帮助,以获得一个指定的项目列表,并将它们添加到组合框。 我的观察列表包含从数据库接收的值(在特定的只有3列的表中),我想在组合框中只显示一个列值。选择组合框时,其他值在2个文本字段中收费。 代码如下。 导入Accettazioni模型: 重要信息控制器: 现在,逻辑似乎工作正常,但是我的组合框不包含值nomeProperty()。 我该如何解决? 预先感谢
我在使用可观察类制作DropDownList时遇到问题。 下面是可观察类的代码: 这是我的工作下拉列表: 这是我的DropDownList的html: 最后,这是我从observable datasource请求中得到的结果: 我做了一些研究,但找不到任何合适的例子。 我看了看:MVVM小部件绑定和周围玩数据绑定,数据值字段,数据文本字段,但不能得到我想要的结果。 因此,我正在寻找的是一种将常规D
我是FX新手,对Java不太陌生,所以请耐心等待!我有一个简单的应用程序,它使用一个由ObservableList支持的JavaFX TableView。 当我第一次启动应用程序时,我生成了另一个Thread(从Application的start方法)来监听对日志文件的更改并将另一个元素添加到观察列表中,以便在TableView中立即可见该行。我认为在窗口中有一个包含当前大小的Label会很有好处
谢谢你的任何线索!
我有动态文本要绑定到HTML页面上。这是一个Angular 2应用程序。我正在使用这样的东西: 但是我收到一个错误: 无法绑定到“aria-label ”,因为它不是“div”的已知属性。 对此有什么解决方法吗?
我正在用一个库编程,我不知道代码,只知道方法,我不能修改它。我试着制作一个“航班”的表格视图,但我不知道如何为每个航班命名(或ID)。有人能帮我吗?谢谢此处有一些代码: