我有ListView
一个员工可以说的语言。它使用在ListCells
的帮助下实施的自定义setCellFactory
。我有一个ListCellFactory
课程,我为自定义call
存储了ListCell
。在我的LanguageListCell
(我的自定义ListCell
课程)中,我有ContextMenu
我有一个MenuItem
。 MenuItem
会触发一个事件来编辑选定的ListCell
。我在项目中遇到的唯一问题是进行双击编辑。每当我点击多次(未选择Cell
时)或一次(当选择Cell
时),startEdit
就会被调用。我想要完成的是删除这个双击编辑。但是我设法写成代码会导致太多问题。例如,当我单击用于编辑的TextField
时,将调用cancelEdit
方法。而且,基本上,我甚至无法点击TextField
而不删除它。
请参阅我的代码以供参考
这是LanguageListCell
类
package application;
import javafx.beans.binding.Bindings;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
public class LanguageListCell extends ListCell<String> {
private TextField textField;
LanguageListCell cell = this;
int i = 0;
public LanguageListCell(ListView<String> languages) {
ContextMenu contextMenu = new ContextMenu();
cell.setEditable(true);
MenuItem editItem = new MenuItem();
editItem.textProperty().bind(Bindings.format("Edit \"%s\"", cell.itemProperty()));
editItem.setOnAction(event -> {
languages.edit(cell.getIndex());
//cell.startEdit();
});
contextMenu.getItems().add(editItem);
cell.textProperty().bind(cell.itemProperty());
cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
if (isNowEmpty) {
cell.setContextMenu(null);
} else {
if (getString() != "Add") {
cell.setContextMenu(contextMenu);
}
}
});
//This is what I have tried but i get the issue with cancelEdit
//where when I press the TextField it cancels the editing
cell.addEventFilter(MouseEvent.MOUSE_PRESSED, (MouseEvent e) -> {
if (e.getButton().equals(MouseButton.PRIMARY)) {
if (cell.isSelected() && e.getClickCount() >= 1) {
languages.getSelectionModel().clearSelection();
languages.getSelectionModel().select(cell.getItem());
e.consume();
}
if (e.getClickCount() > 1) {
e.consume();
}
}
});
}
public String getString() {
return getItem() == null ? "" : getItem().toString();
}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
textField.requestFocus();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setGraphic(null);
setText(getItem());
textField = null;
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
cell.textProperty().unbind();
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(getGraphic());
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
if (textField.getText().trim() != "" && textField.getText().trim().length() > 3) {
commitEdit(textField.getText());
setGraphic(null);
setGraphic(getGraphic());
}
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
}
这是LanguageCellFactory
类
package application;
import javafx.beans.binding.Bindings;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.Pane;
import javafx.util.Callback;
import application.LanguageListCell;
public class LanguageCellFactory implements Callback<ListView<String>, ListCell<String>> {
public LanguageCellFactory()
{
}
@Override
public ListCell<String> call(ListView<String> languages)
{
return new LanguageListCell(languages);
}
}
这是Main
类
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.ListView;
import java.util.ArrayList;
import application.LanguageCellFactory;
public class Main extends Application {
private ListView<String> languages;
private Stage stage;
@Override
public void init()
{
}
public void start(Stage primaryStage) {
try {
Pane root = new Pane();
Scene scene = new Scene(root,800,600);
ArrayList<String> list_items = new ArrayList<String>();
list_items.add("Russian");
list_items.add("English");
languages = new ListView<String>();
languages.relocate(150, 62);
languages.getItems().addAll(list_items);
root.getChildren().add(languages);
//languages.setEditable(true);
languages.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
languages.setCellFactory(new LanguageCellFactory());
primaryStage.setScene(scene);
primaryStage.setTitle("First JavaFX App");
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:-1)
如果有人想知道如何解决此问题,我尝试删除了ListCell
的编辑事件,并提供了我自己的&#34;编辑&#34;细胞的行为,现在它正在运作
以下是LanguageListCell
类
package application;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
public class LanguageListCell extends ListCell<String> {
private TextField textField;
LanguageListCell cell = this;
int i = 0;
private boolean textfield_state = false;
ContextMenu contextMenu = new ContextMenu();
MenuItem editItem = new MenuItem();
public LanguageListCell(ListView<String> languages) {
editItem.textProperty().bind(Bindings.format("Edit \"%s\"", cell.itemProperty()));
contextMenu.getItems().add(editItem);
cell.textProperty().bind(cell.itemProperty());
cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
if (isNowEmpty) {
cell.setContextMenu(null);
} else {
if (getString() != "Add") {
cell.setContextMenu(contextMenu);
}
}
});
}
public String getString() {
return getItem() == null ? "" : getItem().toString();
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
cell.textProperty().unbind();
//String thecellValue = getString();
if (empty) {
setText(null);
setGraphic(null);
} else {
if (textfield_state) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(getGraphic());
editItem.setOnAction(event -> {
textfield_state = true;
if(textField == null)
{
createTextField();
}
setText(null);
setGraphic(textField);
textField.requestFocus();
textField.selectAll();
});
}
}
}
private void createTextField() {
textField = new TextField(getString());
String CellValue = getString();
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
if (textField.getText().trim() != "" && textField.getText().trim().length() > 3) {
setText(textField.getText().trim());
setGraphic(null);
}
} else if (t.getCode() == KeyCode.ESCAPE) {
//cancelEdit();
setGraphic(null);
setText(CellValue);
textField = null;
}
}
});
textField.focusedProperty().addListener((obs, isNotFocused, isFocused) -> {
if(isFocused)
{
LanguageListCell parent = (LanguageListCell) textField.getParent();
ListView<String> list = parent.getListView();
list.getSelectionModel().clearSelection();
list.getSelectionModel().select(parent.getIndex());
}
else
{
setGraphic(null);
setText(CellValue);
textField = null;
}
});
}
}