buo*_*oto 1 java listview javafx event-handling
在我的 JavaFX 应用程序中,我将 ListView 与自定义单元格一起使用。我想以不同于单击项目下方空白区域的方式处理列表项单击。我已经在整个 ListView 上设置了一个事件侦听器,但我无法确定单击了哪些项目(getSelectedItem()是null,可能是因为我的自定义单元格代码中的错误)。以下情况如何正确处理?
我的组件如下所示:
<fx:root type="javafx.scene.layout.VBox">
<Label fx:id="dayname" text="${controller.day.name}" />
<ListView fx:id="appointmentsListView" items="${controller.day.events}"
onMouseClicked="#handleAppointmentsClick" />
</fx:root>
Run Code Online (Sandbox Code Playgroud)
ListView 有自定义单元工厂,在组件构造函数中设置:
public class DayComponent extends VBox {
@FXML
private ListView<Appointment> appointmentsListView;
public DayComponent() throws IOException {
// ...
appointmentsListView.setCellFactory(l -> new AppointmentCell());
}
@FXML
public void handleAppointmentsClick(MouseEvent event) {
System.out.println(appointmentsListView.getSelectionModel()
.getSelectedItem()); // null in every case
}
}
Run Code Online (Sandbox Code Playgroud)
自定义单元格代码:
public class AppointmentCell extends ListCell<Appointment> {
@Override
protected void updateItem(Appointment item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setGraphic(new AppointmentLabel(item));
} else {
setGraphic(null);
}
}
}
Run Code Online (Sandbox Code Playgroud)
一种相当干净的方法是向列表视图中的单元格注册鼠标侦听器,以处理非空单元格上的点击。如果单元格非空,则消耗鼠标事件。在列表视图本身上注册第二个鼠标侦听器,以处理对空单元格的点击(如果列表视图为空,则在列表视图的占位符上)。这需要两个处理程序,但至少以合理的方式分离“空”和“非空”功能。
这是一个简单的例子:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ListViewMouseHandlerExample extends Application {
private int count = 0 ;
@Override
public void start(Stage primaryStage) {
ListView<String> listView = new ListView<>();
Button addButton = new Button("Add");
addButton.setOnAction(e -> listView.getItems().add("Item " + (++count)));
Button deleteButton = new Button("Delete");
deleteButton.setOnAction(e -> listView.getItems().remove(listView.getSelectionModel().getSelectedIndex()));
deleteButton.disableProperty().bind(listView.getSelectionModel().selectedItemProperty().isNull());
listView.setCellFactory(lv -> {
ListCell<String> cell = new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(item);
}
};
cell.setOnMouseClicked(e -> {
if (!cell.isEmpty()) {
System.out.println("You clicked on " + cell.getItem());
e.consume();
}
});
return cell;
});
listView.setOnMouseClicked(e -> {
System.out.println("You clicked on an empty cell");
});
BorderPane root = new BorderPane(listView);
ButtonBar buttons = new ButtonBar();
buttons.getButtons().addAll(addButton, deleteButton);
root.setBottom(buttons);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4439 次 |
| 最近记录: |