在我的Spring Boot JavaFX应用程序中,我具有多个TableViews。允许用户使用默认的拖放功能对列进行重新排序。我也有一个侦听器,用于检测在其中一个TableViews中是否选择了另一行,并采取相应的措施:
/*
* Processing when a selection in a table changes.
*/
getTableView().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
this.detailsController.get().showDetails(newValue);
});
问题是,当拖动列然后将其放下时(在操作的放下部分),此侦听器将被激活。这具有不良的副作用,因为在这种情况下,变量newValue为“ null”(它本身是用于处理的有效值,我只是不想在拖动后删除列时传递该值)。删除列时,有没有办法绕过此侦听器?
我尝试了各种方法来捕获拖放事件,但无济于事...我想我可以在拖动开始时停用监听器,并在完成拖放后重新激活监听器。
这是一些示例代码:
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestDragDrop extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Person> table = new TableView<>();
table.getColumns().add(column("First Name", Person::firstNameProperty));
table.getColumns().add(column("Last Name", Person::lastNameProperty));
table.getColumns().add(column("Email", Person::emailProperty));
table.getItems().addAll(createData());
table.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
System.out.println("===>>> Oops");
} else {
System.out.println("===>>> Hi there " + newValue.getFirstName());
}
});
VBox checkBoxes = new VBox(5);
checkBoxes.getStyleClass().add("controls");
BorderPane root = new BorderPane(table);
root.setTop(checkBoxes);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private static <S, T> TableColumn<S, T> column(String text, Function<S, ObservableValue<T>> property) {
TableColumn<S, T> col = new TableColumn<>(text);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
return col;
}
private List<Person> createData() {
return Arrays.asList(new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]"));
}
public static class Person {
private final StringProperty firstName = new SimpleStringProperty();
private final StringProperty lastName = new SimpleStringProperty();
private final StringProperty email = new SimpleStringProperty();
public Person(String firstName, String lastName, String email) {
setFirstName(firstName);
setLastName(lastName);
setEmail(email);
}
public final StringProperty firstNameProperty() {
return this.firstName;
}
public final String getFirstName() {
return this.firstNameProperty().get();
}
public final void setFirstName(final String firstName) {
this.firstNameProperty().set(firstName);
}
public final StringProperty lastNameProperty() {
return this.lastName;
}
public final String getLastName() {
return this.lastNameProperty().get();
}
public final void setLastName(final String lastName) {
this.lastNameProperty().set(lastName);
}
public final StringProperty emailProperty() {
return this.email;
}
public final String getEmail() {
return this.emailProperty().get();
}
public final void setEmail(final String email) {
this.emailProperty().set(email);
}
}
public static void main(String[] args) {
launch(args);
}
}
在表中选择一行:=== >>> Hi .....输出到控制台。现在,将第一列拖到表中的其他位置:=== >>> Oops输出到控制台。
因此,防止这种情况的一种方法是添加一个缓冲区,以防止在释放列后的一段时间内发生更改。
在我的情况下,我使用50ms作为缓冲区,因为在此时间内,一个人很难完成拖动并单击名称,因为在我的测试中结果达到0.05秒,这很好(没有通过null),但是增加了/根据需要减少
在这里,我初始化了PauseTransition,它将在给定时间后触发
private final PauseTransition bufferReset = new PauseTransition(Duration.millis(50));
private boolean isBuffering = false;
初始化后,将变量设置为翻转回不再缓冲
bufferReset.setOnFinished(event -> isBuffering = false);
下一个代码块是在释放列之后翻转缓冲区变量的地方,并启动计时器以将变量翻转回
Platform.runLater(() -> {
for (Node header : table.lookupAll("TableHeaderRow")) {
if(header instanceof TableHeaderRow) {
header.addEventFilter(MouseEvent.MOUSE_RELEASED, event -> {
isBuffering = true;
bufferReset.play();
});
}
}
});
从那里将代码包装在isBuffering if语句中
if(!isBuffering) {
if (newValue == null) {
System.out.println("===>>> Oops");
} else {
System.out.println("===>>> Hi there " + newValue.getFirstName());
}
}
完整代码(不包括人员类别):
public class TestDragDrop extends Application {
private final PauseTransition bufferReset = new PauseTransition(Duration.millis(50));
private boolean isBuffering = false;
@Override
public void start(Stage primaryStage) {
TableView<Person> table = new TableView<>();
table.getColumns().add(column("First Name", Person::firstNameProperty));
table.getColumns().add(column("Last Name", Person::lastNameProperty));
table.getColumns().add(column("Email", Person::emailProperty));
table.getItems().addAll(createData());
table.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if(!isBuffering) {
if (newValue == null) {
System.out.println("===>>> Oops");
} else {
System.out.println("===>>> Hi there " + newValue.getFirstName());
}
}
});
bufferReset.setOnFinished(event -> isBuffering = false);
Platform.runLater(() -> {
for (Node header : table.lookupAll("TableHeaderRow")) {
if(header instanceof TableHeaderRow) {
header.addEventFilter(MouseEvent.MOUSE_RELEASED, event -> {
isBuffering = true;
bufferReset.play();
});
}
}
});
VBox checkBoxes = new VBox(5);
checkBoxes.getStyleClass().add("controls");
BorderPane root = new BorderPane(table);
root.setTop(checkBoxes);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private static <S, T> TableColumn<S, T> column(String text, Function<S, ObservableValue<T>> property) {
TableColumn<S, T> col = new TableColumn<>(text);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
return col;
}
private List<Person> createData() {
return Arrays.asList(new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]"));
}
public static void main(String[] args) { launch(args); }
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句