当我在JavaFX TreeTableView上按鼠标右键时,它将选择我单击的节点。我可以理解为什么在大多数情况下都希望这样做,但并非在所有情况下都希望这样做。
我正在开发一个应用程序,其中树表中有多列,其中一列使用画布小部件来定制图形(波形)。由于各种原因(设置标记,缩放等),必须能够使用鼠标与图形列进行交互。因此,我不希望鼠标按钮选择表中的行(或与表交互)。
我可以通过用放一个addEventFilter()
来MouseEvent.MOUSE_CLICKED
用第一个鼠标按键过滤掉点击event.consume()
。然后,我可以按我想要的方式处理鼠标单击。
但是,当我右键单击该单元格时,表中的选择将更改为该行。我试过将事件过滤器放在单元格,表,行,列上,似乎没有任何东西可以过滤右键单击选择更改。请注意,画布小部件设置为鼠标透明。
这是一个使用标准通讯录示例的示例,除了我用画布小部件替换了电子邮件列。
package sample;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Main extends Application {
private TableView<Person> table = new TableView<Person>();
private ContextMenu menu = new ContextMenu();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
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]")
);
class MyTableCell extends TableCell<Person, String> {
public MyTableCell(ContextMenu menu) {
super();
setContextMenu(menu);
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(item);
setGraphic(null);
}
}
class MySpecialCell extends MyTableCell {
Canvas canvas = new Canvas(200.0, 12.0);
public MySpecialCell() {
super(null);
canvas.setMouseTransparent(true);
addEventFilter(MouseEvent.ANY, e -> e.consume());
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if (! empty) {
canvas.getGraphicsContext2D().strokeText(item, 5.0, 10.0);
setGraphic(canvas);
} else {
setGraphic(null);
}
}
}
@Override
public void start(Stage stage) throws Exception{
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
menu.getItems().add(new MenuItem("Hello World"));
Callback cellFactory = param -> new MyTableCell(menu);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(cellFactory);
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("lastName"));
lastNameCol.setCellFactory(cellFactory);
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email"));
emailCol.setCellFactory(param -> new MySpecialCell());
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}
这是使用Java 8u20。在此示例中,MyTableCell
该类用于前两列中的单元格。它将上下文菜单添加到这些列。该MySpecialCell
班是最后一列和它把一个帆布的表与它的电子邮件文本。它还会落水并过滤ANY
鼠标事件。
如果运行此命令,则会看到如果在前两列中使用鼠标按钮1,则可以更改表中的选择。第三列中的鼠标按钮1不会更改选择。但是,鼠标按钮2(鼠标右键)确实会更改第三列中的选择。
我希望它不会更改选择。有人可以提示我如何在使用列中的鼠标右键时防止更改选择吗?
注意:我尝试让画布处理鼠标输入(实际上不是使鼠标透明并过滤所有鼠标事件),并且在单击鼠标右键时表格仍会更改选择。由于各种原因(实际数据是画布实际上是一堆画布小部件的事实,难以确定鼠标在表中与哪个节点进行交互等),我想在单元格中处理该单元格鼠标输入。
谢谢!
重复我的评论:我认为行为可能是错误而不是功能-我希望使用任何mouseEvent会阻止右键(辅助)与左键(主要)正常动作相同。
被评估为一项功能:缺少的部分是除了mouseEvents之外还使用contextMenuEvents,类似
public MySpecialCell() {
super(null);
canvas.setMouseTransparent(true);
addEventFilter(MouseEvent.ANY, e -> e.consume());
// move Jonathan's code from table to cell level:
// need to consume contextMenuEvents as well
addEventFilter(ContextMenuEvent.ANY, e -> e.consume());
}
返回不同意评估:
如果需要由特殊列上的键盘触发的contextMenu进行触发,则可能仍然需要以下技巧,但是请不要进一步研究。
无论如何,一种快速的解决方法是用自定义实现方式替换默认行为。合作者
像这样的东西(注意:在工作时,它没有经过适当的测试):
class MySpecialCellBehavior extends TableCellBehavior {
public MySpecialCellBehavior(TableCell control) {
super(control);
}
@Override
protected void doSelect(double x, double y, MouseButton button,
int clickCount, boolean shiftDown, boolean shortcutDown) {
// do nothing on secondary button
if (button == MouseButton.SECONDARY) return;
super.doSelect(x, y, button, clickCount, shiftDown, shortcutDown);
}
}
class MySpecialCellSkin extends TableCellSkinBase {
private final TableColumn tableColumn;
public MySpecialCellSkin(TableCell tableCell) {
super(tableCell, new MySpecialCellBehavior(tableCell));
// doesn't make a difference
//consumeMouseEvents(true);
this.tableColumn = tableCell.getTableColumn();
super.init(tableCell);
}
@Override protected BooleanProperty columnVisibleProperty() {
return tableColumn.visibleProperty();
}
@Override protected ReadOnlyDoubleProperty columnWidthProperty() {
return tableColumn.widthProperty();
}
}
class MySpecialCell extends MyTableCell {
Canvas canvas = new Canvas(200.0, 12.0);
public MySpecialCell() {
super(null);
canvas.setMouseTransparent(true);
addEventFilter(MouseEvent.ANY, e -> e.consume());
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if (! empty) {
canvas.getGraphicsContext2D().strokeText(item, 5.0, 10.0);
setGraphic(canvas);
} else {
setGraphic(null);
}
}
// create and return the custom skin
@Override
protected Skin<?> createDefaultSkin() {
return new MySpecialCellSkin(this);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句