【问题标题】:How to remove double click editing for ListCell如何删除 ListCell 的双击编辑
【发布时间】:2018-10-02 18:42:57
【问题描述】:

我有一个ListView,其中包含一名员工可以说的语言。它使用在setCellFactory 的帮助下实现的自定义ListCells。我有一个ListCellFactory 类,我为我的自定义ListCell 存储了call。在我的LanguageListCell(我的自定义ListCell 类)中,我有一个ContextMenu,其中我有一个MenuItemMenuItem 触发事件以编辑选定的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);
}
}

【问题讨论】:

    标签: java listview javafx cell


    【解决方案1】:

    如果有人想知道如何解决此问题,我尝试删除 ListCell 的编辑事件并为单元格提供我自己的“编辑”行为,现在它正在工作

    这是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;
            }
        });
    
    }
    }
    

    【讨论】:

    • 无论你想达到什么目的:这是完全错误的!如果您希望编辑具有任何永久效果,则必须使用适当的编辑机制(单元级别的 start/commit/cancelEdit,以及 ListView 上的自定义 editCommitHandler)。
    • 根据您的要求,我不明白您为什么要绕过鼠标手势的标准 ux ..您会混淆您的用户..
    猜你喜欢
    • 2018-09-10
    • 2011-07-23
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2011-03-18
    相关资源
    最近更新 更多