【发布时间】:2015-04-01 04:18:56
【问题描述】:
我使用这个类为 TreeItem 提供一个用于编辑的文本字段(与问题无关)并在 TreeItem 上设置一个 ContextMenu:
package domain;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public final class TextFieldTreeCellImpl extends TreeCell<MyNode> {
private TextField textField;
private ContextMenu cm = new ContextMenu();
String oldItem = "";
private Connection connection;
String url = "jdbc:sqlserver://localhost:1433;databaseName=HOGENT1415_11";
String user = "sa";
String password = "root";
Statement statement;
public TextFieldTreeCellImpl() throws SQLException {
connection = DriverManager.getConnection(url, user, password);
statement = connection.createStatement();
}
@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().value);
setGraphic(getTreeItem().getGraphic());
}
@Override
public void updateItem(MyNode 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());
MenuItem cmItem1 = new MenuItem("Add continent");
cmItem1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
System.out.println("Geklikt!");
}
});
cm.getItems().add(cmItem1);
setContextMenu(cm);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
String sql = "UPDATE Continents SET Name='" + textField.getText() + "' WHERE ContinentID=" + getItemId();
if (getItem().isCountry()) {
sql = "UPDATE Countries SET Name='" + textField.getText() + "' WHERE CountryID=" + getItemId();
}
if (getItem().isClimateChart()) {
sql = "UPDATE ClimateCharts SET Location='" + textField.getText() + "' WHERE ClimateChartID=" + getItemId();
}
try {
ResultSet result = statement.executeQuery(sql);
} catch (SQLException ex) {
Logger.getLogger(TextFieldTreeCellImpl.class.getName()).log(Level.SEVERE, null, ex);
}
commitEdit(new MyNode(textField.getText(), getType(), getItemId()));
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
private String getType() {
return getItem() == null ? "" : getItem().type;
}
private int getItemId() {
return getItem() == null ? null : getItem().id;
}
}
我使用以下代码在我的 Controller 类中实例化这个类:
selectionTreeView.setEditable(true);
selectionTreeView.setCellFactory(new Callback<TreeView<MyNode>, TreeCell<MyNode>>() {
@Override
public TreeCell<MyNode> call(TreeView<MyNode> p) {
try {
return new TextFieldTreeCellImpl();
} catch (SQLException ex) {
Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
});
但是,当我运行程序并右键单击项目时,一切正常,但如果我继续在其他项目上单击更多,则会继续在上下文菜单中获取项目。
为了缩小范围,每次双击某个项目时都会发生这种情况。
查看截图:
我知道这是因为 ipdateItem 不断被调用,但我该如何防止呢?
【问题讨论】:
标签: javafx treeview contextmenu