让我们考虑一个示例代码:
SimpleIntegerProperty simpleIntegerProperty = new SimpleIntegerProperty(0);
simpleIntegerProperty.addListener((observable, oldValue, newValue) -> {
// execution code when the event is fired.
});
当我使用setValue()
方法设置新值时,如果 oldValue 和 newValue 相同,则不会触发该事件。只有当它们不同时。
一个例子:
ListView<Element>
绑定ObservableList<Element>
。Procedure
是一个不同的类。它对元素执行一些操作,并且还包含SimpleIntegerPorperty
-currentlyChosenElementIndex
以指示当前所选元素的索引。在处理当前元素时,我希望ListView
显示这一点。现在,在此过程中,GUI 被阻止ListView
,并且在进行时在 上选择当前元素。程序结束后,应用程序重置currentlyChosenElementIndex
为零,这是我遇到问题的索引。当程序开始时,第一个元素没有被选中,因为应用程序setValue()
与之前的元素相同。
有什么办法可以改变吗?
如果您的Procedure
的currentlyChosenElementIndex
表示当前正在被处理,然后将具有它等于元素的索引0
时没有元件当前正在处理的基本叶处于不一致的状态应用程序。表示索引的东西的通常约定是-1
用来表示“无值”。所以我认为初始化currentlyChosenElementIndex
为-1
,并-1
在程序完成时将其重置为更有意义。(这也会与选择模型的选择索引一致,当什么都没有选择时。)
这确实意味着您在使用该值时必须小心,以避免出现任何ArrayIndexOutOfBoundsException
s - 即您必须检查特殊值并单独处理它。
这是一个 SSCCE:
import java.util.List;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ProcessListElements extends Application {
private int count = 0 ;
@Override
public void start(Stage primaryStage) {
ListView<String> listView = new ListView<>();
for (int i = 0 ; i < 10 ; i++) addElement(listView.getItems());
Procedure procedure = new Procedure();
Button startProcessButton = new Button("Start Process");
Button addItemButton = new Button("Add item");
Button deleteItemButton = new Button("Delete item");
TextArea log = new TextArea();
startProcessButton.setOnAction(e -> {
log.clear();
listView.requestFocus();
new Thread(() -> procedure.process(listView.getItems())).start();
});
addItemButton.setOnAction(e -> addElement(listView.getItems()));
deleteItemButton.setOnAction(e -> listView.getItems().remove(listView.getSelectionModel().getSelectedIndex()));
deleteItemButton.disableProperty().bind(listView.getSelectionModel().selectedItemProperty().isNull());
HBox controls = new HBox(5, startProcessButton, addItemButton, deleteItemButton);
controls.setAlignment(Pos.CENTER);
controls.setPadding(new Insets(5));
BorderPane root = new BorderPane(listView, null, log, controls, null);
procedure.currentlyChosenElementIndexProperty().addListener((obs, oldIndex, newIndex) -> {
Platform.runLater(() ->
listView.getSelectionModel().clearAndSelect(newIndex.intValue()));
});
procedure.currentlyChosenElementIndexProperty().addListener((obs, oldIndex, newIndex) -> {
Platform.runLater(() -> {
controls.setDisable(newIndex.intValue() != Procedure.NO_ELEMENT);
});
});
procedure.currentlyChosenElementIndexProperty().addListener((obs, oldIndex, newIndex) -> {
if (oldIndex.intValue() != Procedure.NO_ELEMENT) {
log.appendText("Processing of element "+oldIndex.intValue()+" complete\n");
}
if (newIndex.intValue() != Procedure.NO_ELEMENT) {
log.appendText("Processing element "+newIndex.intValue()+" started\n");
}
});
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private void addElement(List<String> list) {
count++ ;
list.add("Item "+count);
}
public static class Procedure {
private static final int NO_ELEMENT = - 1;
private final ReadOnlyIntegerWrapper currentlyChosenElementIndex = new ReadOnlyIntegerWrapper(NO_ELEMENT);
public void process(List<?> items) {
if (Platform.isFxApplicationThread()) {
throw new IllegalStateException("This method blocks and must not be executed on the FX Application Thread");
}
try {
for (int i = 0 ; i < items.size(); i++) {
currentlyChosenElementIndex.set(i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
currentlyChosenElementIndex.set(NO_ELEMENT);
}
public final ReadOnlyIntegerProperty currentlyChosenElementIndexProperty() {
return this.currentlyChosenElementIndex.getReadOnlyProperty();
}
public final int getCurrentlyChosenElementIndex() {
return this.currentlyChosenElementIndexProperty().get();
}
}
public static void main(String[] args) {
launch(args);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句