首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使ListView可选但不可编辑

如何使ListView可选但不可编辑
EN

Stack Overflow用户
提问于 2017-03-24 00:42:38
回答 3查看 878关注 0票数 2

因此,我正在编写javafx应用程序,我需要能够从列表视图中选择单元格(用于复制粘贴),但我不想使其可编辑,我的意思是,除非我想要更改内容(例如,允许通过按钮)。

因此,我有以下代码:

代码语言:javascript
运行
复制
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        List<String> contacts = new ArrayList<>(Arrays.asList("968787522","3424234234","2343234324"));
        ListView<String> contactsList = new ListView();
        contactsList.setItems(FXCollections.observableArrayList(contacts));
        //this gives me the ability to edit the row as text field but I want this text field to not be editable
        contactsList.setCellFactory(TextFieldListCell.forListView());
        StackPane pane = new StackPane();
        pane.getChildren().add(contactsList);
        primaryStage.setScene(new Scene(pane, 300, 275));
        primaryStage.show();    }


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

如果我将'contactsList‘设置为不可编辑,则无法编辑,也不能选择。

如您所见(下图),我正在编辑单元格,但我希望能够选择文本(而不是项),但我不希望能够删除字符(文本可以选择,但不能编辑)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-26 23:18:12

因此,经过大量的研究和API阅读,我想出了一个解决方案。这正是我想做的。这是一个演示,如果有人需要的话;)所以,每次我们想选择行的内容时,我们都需要选择行,获取textField并将编辑设置为true或false (每次)。因此,在我制作的演示中,我放置了一个按钮,这样您就可以将编辑切换为true或false,以确保它正在工作,以及如何工作。

干杯。

我评论了一些代码,以便更好地理解,如果您对此有任何疑问,请告诉我。

代码语言:javascript
运行
复制
package sample;

import com.sun.javafx.scene.control.skin.VirtualFlow;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class Main extends Application {
private boolean editable = false;

public static  IndexedCell getCell(final Control control, final int index) {
    return getVirtualFlow(control).getCell(index);
}

public static VirtualFlow<?> getVirtualFlow(Control control) {
    Group group = new Group();
    Scene scene = new Scene(group);
    Stage stage = new Stage();

    if(control.getScene() == null) {
        group.getChildren().setAll(control);
        stage.setScene(scene);
        stage.show();
    }

    VirtualFlow<?>flow = (VirtualFlow<?>) control.lookup("#virtual-flow");
    return flow;
}

public void setEditable(ListView contactsList){
        //this needs to be done since we need to run our code after the text field was rendered
        //so we need to invoke our code after this happens, if not it will throw a null pointer...
        Platform.runLater(() -> {
            //this is one of the most important guys because javafx api says that
            //TextFieldListCell.forListView() allows editing of the cell content when the cell is double-clicked,
            // or when {@link ListView#edit(int)} is called.
            int rowIndex = contactsList.getSelectionModel().getSelectedIndex();
            contactsList.edit(rowIndex);
            ListCell rootCell = (ListCell) getCell(contactsList, rowIndex);
            TextField textField = (TextField) rootCell.getGraphic();
            textField.setEditable(editable);
        });
}

@Override
public void start(Stage primaryStage) throws Exception{
    List<String> contacts = new ArrayList<>(Arrays.asList("968787522","3424234234","2343234324"));
    ListView<String> contactsList = new ListView();
    contactsList.setItems(FXCollections.observableArrayList(contacts));
    contactsList.setEditable(true);

    //this gives me the ability to edit the row as text field but I want this text field to not be editable
    contactsList.setCellFactory(TextFieldListCell.forListView());
    contactsList.setOnEditStart(e -> {
        setEditable(contactsList);
    });

    StackPane pane = new StackPane();
    Button editBtn = new Button("Toggle edit");
    editBtn.setOnAction(event -> {
        editable = !editable;
        editBtn.setText("Editing = " + editable);
        //to cancel any editing that might be occuring
        contactsList.getSelectionModel().clearSelection();
    });
    pane.getChildren().addAll(contactsList,editBtn);
    primaryStage.setScene(new Scene(pane, 300, 275));
    primaryStage.show();
}

public static void main(String[] args) {
    launch(args);
}
}
票数 1
EN

Stack Overflow用户

发布于 2017-03-24 08:25:08

如果我正确地理解了您,就没有必要将listview设置为“不可编辑”,因为默认行为应该足以满足您的需要。看一看这段代码,例如:

代码语言:javascript
运行
复制
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class NewFXMain extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView listView = new ListView();
        listView.getItems().addAll("one","two","three","four");

        listView.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                System.out.println(listView.getSelectionModel().getSelectedItem());
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(listView);
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("ListView Example");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

我没有改变ListView的可编辑属性,但是我可以选择每一项,而不需要编辑它(在改变其值的意义上)。您可以很容易地将一个EventHandler添加到ListView中,以执行您想要执行的任何操作。您还可以通过操作EventHandler向ListView的每个单元格添加一个CellFactory,如下所示:How to handle ListView item clicked action?

票数 0
EN

Stack Overflow用户

发布于 2017-08-03 07:16:26

下面是对我有用的东西:

代码语言:javascript
运行
复制
    TableView<DataBean> table = new TableView<>();
    table.setItems(...); // list of some DataBean objects with dataBeanField proprty
    table.setEditable(true);

    TableColumn<DataBean, String> column = new TableColumn<>("SomeData");
    column.setCellValueFactory(new PropertyValueFactory<DataBean, String>("dataBeanField"));
    column.setCellFactory(new Callback<TableColumn<DataBean, String>, TableCell<DataBean, String>>() {
        @Override
        public TableCell<DataBean, String> call(TableColumn<DataBean, String> param) {
            return new TextFieldTableCell<>(new DefaultStringConverter() {
                private String defaultValue = "";

                @Override
                public String fromString(String newValue) {
                    return super.fromString(defaultValue);
                }

                @Override
                public String toString(String value) {
                    return defaultValue = super.toString(value);
                }
            });
        }
    });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42989477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档