在MenuItem上单击编辑ListCell

时间:2018-03-31 22:14:16

标签: java listview javafx textfield

我一直致力于与listcell编辑相关的问题。到目前为止,我已经设法为ListCells创建了ContextMenu,但随着我的进步,我遇到了一个问题。我的整个想法是当我点击时,例如菜单按钮编辑我想要编辑所选的ListCell但不是那种编辑,就像listview提供的edit()方法那样。这个是不同的。我尝试创建自定义TextFieldListCell类,以便我可以使用自己的规则验证文本字段,但我还没有成功。

这里是我的listview单元工厂的代码,包含菜单项:

    languages.setEditable(true);
    languages.setCellFactory(ev -> {



        ListCell<String> cell = new ListCell<>();

        ContextMenu contextMenu = new ContextMenu();

        MenuItem editItem = new MenuItem();
        editItem.textProperty().bind(Bindings.format("Edit \"%s\"", cell.itemProperty()));
        editItem.setOnAction(event -> {
            // The LanguageListCell class i want to put here...
        });

        MenuItem addItem = new MenuItem("Add language");
        addItem.setOnAction(event -> {
            String item = "";
            languages.getItems().add(item);
        });


        MenuItem deleteItem = new MenuItem();
        deleteItem.textProperty().bind(Bindings.format("Delete \"%s\"", cell.itemProperty()));
        deleteItem.setOnAction(event -> languages.getItems().remove(cell.getItem()));
        contextMenu.getItems().addAll(addItem, editItem, deleteItem);

        cell.textProperty().bind(cell.itemProperty());

        cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
            if (isNowEmpty) {
                cell.setContextMenu(null);
            } else {
                cell.setContextMenu(contextMenu);
            }
        });
        return cell ;
    });

这是我的自定义TextFieldListCell类的代码:

    public class LanguageListCell extends ListCell<String> 
    {
    private TextField textField;

    public LanguageListCell() 
    {

    }

    @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(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(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();
    }

    }

1 个答案:

答案 0 :(得分:0)

如果有人想知道我的问题的解决方案,请输入完整的代码:

LanguageListCell类

package application;

import java.util.ArrayList;

import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.ContentDisplay;
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.stage.WindowEvent;


   public class LanguageListCell extends ListCell<String> 
   {
    private TextField textField;
    ListCell<String> cell = this;
    int i = 0;
    boolean manually_selected = false;


    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 -> {

            // The LanguageListCell class i want to put here...
            cell.startEdit();
        });

        MenuItem addItem = new MenuItem("Add language");

        addItem.setOnAction(new EventHandler<ActionEvent> () {
            @Override
            public void handle(ActionEvent ev)
            {


                i++;

                String lang = "New Language " + i;



                languages.getItems().add(lang);



                if(i == 10)
                {

                    addItem.setDisable(true);
                }
                languages.getSelectionModel().clearSelection();
                languages.getSelectionModel().select(languages.getItems().size() - 1);
                cell.setItem(languages.getSelectionModel().getSelectedItem());

                manually_selected = true;



            }



        });


        MenuItem deleteItem = new MenuItem();
        deleteItem.textProperty().bind(Bindings.format("Delete \"%s\"", cell.itemProperty()));
        deleteItem.setOnAction(new EventHandler<ActionEvent> () {
            @Override
            public void handle(ActionEvent ev)
            {
                if(languages.getSelectionModel().getSelectedItems().size() - 1 > 0)
                {

                    if(i > 0)
                    {
                        i = (languages.getItems().size() - languages.getSelectionModel().getSelectedItems().size()) - 1;
                    }
                    /*for(String lang: languages.getSelectionModel().getSelectedItems())
                    {
                        languages.getItems().remove(lang);

                    }*/
                    ArrayList<String> delete_data = new ArrayList<String>(languages.getSelectionModel().getSelectedItems());
                    languages.getItems().removeAll(delete_data);

                }
                languages.getItems().remove(cell.getItem());
                if(i > 0) i = 0;
            }

        });

        contextMenu.setOnShowing(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent e) {
                if(languages.getSelectionModel().getSelectedItems().size() - 1 > 0)
                {
                    editItem.setDisable(true);
                    addItem.setDisable(true);
                }
            }
         });

        contextMenu.getItems().addAll(addItem, editItem, deleteItem);

        cell.textProperty().bind(cell.itemProperty());

        cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
            if (isNowEmpty) {
                cell.setContextMenu(null);
            } else {

                cell.setContextMenu(contextMenu);

            }
        });



    }

    public String getString() {
        return getItem() == null ? "" : getItem().toString();
    }

    @Override
    public void startEdit() {
        super.startEdit();

        if (textField == null) {
            createTextField();
        }
        cell.textProperty().unbind();
        setText(null);
        setGraphic(textField);
        textField.selectAll();
        textField.requestFocus();
    }



    @Override
    public void cancelEdit() {
        super.cancelEdit();
        setText((String) getItem());
        setGraphic(null);
        setGraphic(getGraphic());
    }

    @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.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.util.Callback;
import application.LanguageListCell;

public class LanguageCellFactory implements Callback<ListView<String>, 
ListCell<String>> {


@Override

public ListCell<String> call(ListView<String> languages)
{
    return new LanguageListCell(languages);    
}

}

和主要课程

languages.setEditable(true);

languages.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

languages.setCellFactory(new LanguageCellFactory());