Javafx如何从列表中获取单元格(不是值)

时间:2017-10-27 11:26:25

标签: javafx

我希望通过索引从列表中获取单元格(节点,而不是数据)。我需要将其转换为我的自定义单元格并调用其函数。

我发现很多问题都是如何获得价值的,但我对如何获取细胞本身一无所知。我尝试使用listView.getChildrenUnmodifiable().get(index),但这不起作用。

我想要实现的功能是右键单击列表的单元格,然后弹出一个具有'rename'命令的上下文菜单,当我点击commond时,需要调用单元格的startEdit函数。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您应该在单个单元格上设置上下文菜单,而不是在列表视图本身上。这是一个简单的例子:

带有列表视图的Controller类,以及从上下文菜单项调用的方法:

import javafx.fxml.FXML;
import javafx.scene.control.ListView;

public class Controller {

    @FXML
    private ListView<String> listView ;

    public void initialize() {
        for (int i = 1 ; i <= 20 ; i++) {
            listView.getItems().add("Item "+i);
        }
        listView.setCellFactory(lv -> new ListCellWithContextMenu(this));
    }

    public void edit(int index) {
        listView.edit(index);
    }

    public void delete(int index) {
        listView.getItems().remove(index);
    }
}

单元格实现:

import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.cell.TextFieldListCell;

public class ListCellWithContextMenu extends TextFieldListCell<String> {


    private final ContextMenu contextMenu ;

    public ListCellWithContextMenu(Controller controller) {
        contextMenu = new ContextMenu();
        MenuItem delete = new MenuItem("Delete");
        MenuItem edit = new MenuItem("Edit");
        contextMenu.getItems().addAll(edit, delete);

        edit.setOnAction(e -> controller.edit(getIndex()));
        delete.setOnAction(e -> controller.delete(getIndex()));

        setConverter(TextFormatter.IDENTITY_STRING_CONVERTER);

    }

    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setContextMenu(null);
        } else {
            setContextMenu(contextMenu);
        }
    }
}

完整性,FXML文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.ListView?>

<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
    <left>
        <ListView fx:id="listView" editable="true" />
    </left>
</BorderPane>

和应用程序类:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class ListViewWithContextMenu extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(FXMLLoader.load(getClass().getResource("ListViewWithContextMenu.fxml")));
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

答案 1 :(得分:0)

James_D是对的,您可以在单个单元格上注册上下文菜单。 但是在我有很多相对于上下文菜单的代码的情况下,重写然后所有可能会导致其他问题。经过一些尝试我使用另一种方式。

为简单起见,我编写了两个可重用的类来实现直接从列表中索引获取单元格的函数。

如果您认为有用,可以使用以下代码。

  //let your cell extend this class
 public class GetAbleListCell<T> extends ListCell<T>{

    private ListViewHelper<T> libraryListHelper;

    public GetAbleListCell(ListViewHelper<T> libraryListHelper) {
        this.libraryListHelper = libraryListHelper;


    }

    @Override
    public void updateIndex(int i) {
        // TODO Auto-generated method stub
        super.updateIndex(i);

        if(getIndex()>0)
        {
            libraryListHelper.setCell(getIndex(),this);
        }
    }

}
 //helper class 
public class ListViewHelper<T> {

    private ObservableList<GetAbleListCell<T>> list=FXCollections.observableArrayList();


    public GetAbleListCell<T> getCell(int index) {

        return list.get(index);
    }



    public void setCell(int index, GetAbleListCell<T> getAbleListCell) {
        while(list.size()<index+1)
        {
        list.add(null);
        }
        list.set(index, getAbleListCell);

    }

}

例如

this.libraryListHelper=new ListViewHelper();
libraryLV.setCellFactory(param -> new LibraryCell(libraryListHelper));
.........
private void renameCurrentSelectedItems() {
        //get cell directly
        LibraryCell cell=(LibraryCell) libraryListHelper.getCell(libraryLV.getSelectionModel().getSelectedIndex());
        cell.startEdit();
    }

可能包含一些错误,但它适用于我的情况