我想在tableview中添加一个上下文菜单,更具体地说,我想在右键单击表格行上显示上下文菜单。
我尝试使用此代码
final EventHandler click = new EventHandler() {
public void handle(MouseEvent t) {
}
@Override
public void handle(Event arg0) {
}
};
final Context menu = new ContextMenu();
MenuItem item = new MenuItem("Add Image");
item.setOnAction(new EventHandler() {
public void handle(ActionEvent t)
{
}
@Override
public void handle(Event arg0)
{
//some code here
}});
menu.getItems().addAll(item);
EditingCell cellFactory = new EditingCell(click,menu);
TableColumn col = new TableColumn("column1");
col.setCellFactory(cellFactory);
上面的代码在JAVAFX 2.0中正常工作,我正在右键单击上下文菜单,当我用JAVAFX 2.1运行代码时,上下文菜单无效。
我尝试使用showsProperty()方法获取上下文菜单显示属性,它在JAVAFX 2.1中返回false,在JAVAFX 2.0中返回true
此外,我还尝试制作我的自定义cellfactory类,这是我的代码(我从官方的JAVAFX TreeView上下文菜单示例中获取)
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
class TextFieldTreeCellImpl extends TableCell<String,String> {
private TextField textField;
private ContextMenu addMenu = new ContextMenu();
public TextFieldTreeCellImpl() {
MenuItem addMenuItem = new MenuItem("Add Employee");
addMenu.getItems().add(addMenuItem);
addMenuItem.setOnAction(new EventHandler() {
public void handle(Event t) {
}
});
setContextMenu(addMenu);
}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
//setGraphic(getTableCell().getGraphic());
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
//setGraphic(getTreeItem().getGraphic());
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
我将此自定义cellfactory添加为:
final Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new TextFieldTreeCellImpl();
}
};
col.setCellFactory(cellFactory);
在JAVAFX 2.0中仍然可以正常工作,但在JAVAFX 2.1中却没有。
请帮助我,我很难......
答案 0 :(得分:3)
官方TreeView
和TableView
教程都适用于JavaFX 2.1。问题是,您正在混合这些代码示例。当TreeCell
的单元格工厂需要TableColumn
时,您无法返回TableCell
。只需单独使用TableView教程,并将EditingCell替换为具有contextMenu的下一个:
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
class EditingCell extends TableCell<Person, String> {
private TextField textField;
private ContextMenu addMenu = new ContextMenu();
public EditingCell() {
MenuItem addMenuItem = new MenuItem("Print Me");
addMenu.getItems().add(addMenuItem);
addMenuItem.setOnAction(new EventHandler() {
public void handle(Event t) {
// Do something with current row
Person curr = getTableView().getItems().get(getIndex());
System.out.println(curr.getFirstName() + " " + curr.getLastName());
}
});
}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
setContextMenu(addMenu);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
答案 1 :(得分:2)
即使使用setContextMenu()方法,我也没有得到任何响应。
然而,这就是我解决问题的方法
我刚刚注册了一个鼠标事件,并在指定位置(鼠标单击)显示了上下文菜单
this.setContextMenu(menu);
this.getContextMenu().setAutoHide(true);
EventHandler event = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
if (me.getButton() == MouseButton.SECONDARY) {
tableView.getContextMenu().show(tableView, me.getSceneX(), me.getSceneY());
}
}
};
this.addEventHandler(MouseEvent.MOUSE_CLICKED,event);