在Javafx中如何在运行时从单元工厂获取或访问值?与TableView相关的问题

问题描述 投票:0回答:1

[这是我的以下代码。在这里我想从另一个类访问文本字段。 textField 位于名为 call() 的重写方法下。]

public class URLCellFactory {

    private static final URLCellFactory urlCellFactory = new URLCellFactory();
//  private final TextField textField = new TextField();

    public Callback<TableColumn<SQLManager, String>, TableCell<SQLManager, String>> cell() {
        Callback<TableColumn<SQLManager, String>, TableCell<SQLManager, String>> cellFactory =
                new Callback<TableColumn<SQLManager, String>, TableCell<SQLManager, String>>() {
                    @Override
                    public TableCell<SQLManager, String> call(TableColumn<SQLManager, String> elementsStringTableColumn) {
                        final TableCell<SQLManager, String> cell = new TableCell<SQLManager, String>() {
                            private final TextField textField = new TextField();
                            {
                                urlCellFactory.operateURL(textField);
                            }

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

                        return cell;
                    }
                };
        return cellFactory;
    }

    public void operateURL(TextField textField) {
        textField.setPromptText("Enter value");
        textField.setOnAction((ActionEvent event) -> {
            System.out.println("Something spoken shit");
            textField.setEditable(false);
            //getURL(textField.getText());
        });
    }

// this function should get access from the textField component. Like: textField.getText();
//    public static String getURL() {
//        return ;
//    }
}                       
                    
  

[我尝试将文本字段设为全局、静态和非静态,但它破坏了我的输出。]

public class URLCellFactory {

    private static final URLCellFactory urlCellFactory = new URLCellFactory();
    private TextField textField = new TextField();

    public Callback<TableColumn<SQLManager, String>, TableCell<SQLManager, String>> cell() {
        Callback<TableColumn<SQLManager, String>, TableCell<SQLManager, String>> cellFactory =
                new Callback<TableColumn<SQLManager, String>, TableCell<SQLManager, String>>() {
                    @Override
                    public TableCell<SQLManager, String> call(TableColumn<SQLManager, String> elementsStringTableColumn) {
                        final TableCell<SQLManager, String> cell = new TableCell<SQLManager, String>() {
                            //private final TextField textField = new TextField();
                            {
                                urlCellFactory.operateURL(textField);
                            }
                            @Override
                            public void updateItem(String item, boolean empty) {
                                super.updateItem(item, empty);
                                if (empty) {
                                    setGraphic(null);
                                } else {
                                    setGraphic(textField);
                                }
                            }
                        };

                        return cell;
                    }
                };
        return cellFactory;
    }

    public void operateURL(TextField textField) {
        textField.setPromptText("Enter value");
        textField.setOnAction((ActionEvent event) -> {
            System.out.println("Something spoken shit");
            textField.setEditable(false);
            //getURL(textField.getText());
        });
    }

    public String getURL() {
        return this.textField.getText();
    }
}                    
                      
  

this corrupt my output

[目标是在不破坏输出的情况下访问 textField 组件。正如我之前提到的,我尝试了一切可能的方法让它发挥作用,但我失败了。那么,是否有任何正确的方法可以正确地做到这一点,请提供,这将非常有帮助。如果有人提供的话,还请添加有关您的代码如何工作的评论。
预先感谢。]

java javafx
1个回答
5
投票

尝试直接从单元格的

TextField
获取文本是错误的方法。
TableView
API 不提供获取特定索引处的单元格的方法。此外,表中的项目数可能多于显示的单元格数。使用文本字段存储应用程序状态将导致信息丢失。

A

TableView
有“模型”支持。该模型是一个公开属性的自定义类。该类本身代表表中的单个项目,显示在单行中。这些属性表示每列中显示的值。编辑单元格的值应该会导致新值被写回模型实例的属性。您可以在需要时通过项目获取新的值。

允许编辑的单元格实现采用两种形式之一。

  1. 单元格可以进入和退出编辑状态。编辑时,UI 更改为允许用户输入的控件。该实现通过单元的

    startEdit
    cancelEdit
    commitEdit
    API 进行,外部代码对适当的事件做出反应。

  2. 单元格“始终在编辑”。这会绕过正常的编辑 API,通常会使用双向绑定。

您当前的实现似乎是第二种形式的尝试。但考虑到您似乎还使文本字段在操作处理程序中不可编辑,似乎第一个表单更适合。在这种情况下,您可以使用内置的

TextFieldTableCell
类,而不是编写自己的类。

这是一个带有

TableView
的示例,显示具有名字属性和姓氏属性的
Person
实例。

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.ToolBar;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class Main extends Application {

  /*
   * The TableView is set to editable and its two columns have cell factories
   * that return TextFieldTableCell. Cell selection is enabled.
   * 
   * To start editing the property of a person, select the appropriate cell and
   * hit ENTER or click on an already-selected cell. To commit an edit, press
   * ENTER while the TextField has focused. To cancel, press ESC or deselect the
   * cell.
   * 
   * Press the "Add person" button to add a new row to the (initially empty) 
   * table. You can then edit the first and last name of this person.
   * 
   * Press the "Print people" button to print the people in the table's items 
   * list. This will show you that the properties of the Person objects change
   * when you commit edits via the UI.
   */

  private TableView<Person> table;
  private int printCount;

  @Override
  public void start(Stage primaryStage) {
    table = createPersonTable();

    var addPersonBtn = new Button("Add person");
    addPersonBtn.setOnAction(this::handleAddPerson);

    var printPeopleBtn = new Button("Print people");
    printPeopleBtn.setOnAction(this::handlePrintPeople);

    var root = new BorderPane(table);
    root.setTop(new ToolBar(addPersonBtn, printPeopleBtn));

    primaryStage.setScene(new Scene(root, 600, 400));
    primaryStage.show();
  }

  private TableView<Person> createPersonTable() {
    var table = new TableView<Person>();
    table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN);
    table.getSelectionModel().setCellSelectionEnabled(true);
    table.setEditable(true);

    /*
     * No need to set the onEditCommit handler of the columns because the default handler
     * will set the property for us when the observable returned by the cell-value factory
     * is writable. We are returning StringProperty, which is writable, in both factories below.
     */

    var firstNameCol = new TableColumn<Person, String>("First Name");
    firstNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
    firstNameCol.setCellValueFactory(cdf -> cdf.getValue().firstNameProperty());
    table.getColumns().add(firstNameCol);

    var lastNameCol = new TableColumn<Person, String>("Last Name");
    lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
    lastNameCol.setCellValueFactory(cdf -> cdf.getValue().lastNameProperty());
    table.getColumns().add(lastNameCol);

    return table;
  }

  private void handleAddPerson(ActionEvent e) {
    e.consume();

    table.getItems().add(new Person("FIRSTNAME", "LASTNAME"));

    int row = table.getItems().size() - 1;
    var col = table.getColumns().get(0);
    table.getSelectionModel().select(row, col);
    table.requestFocus();
  }

  private void handlePrintPeople(ActionEvent e) {
    e.consume();

    /*
     * Demonstrates getting the items of the table and querying the properties
     * of those items. Edits committed via the table will be reflected in these items.
     */

    System.out.printf("########## PRINT %02d ##########%n", printCount);
    for (int i = 0; i < table.getItems().size(); i++) {
      var person = table.getItems().get(i);
      System.out.printf(
          "Person %d: First name = '%s', Last name = '%s'%n",
          i, person.getFirstName(), person.getLastName());
    }
    System.out.println();

    printCount++;
  }

  // The model class
  public static class Person {

    private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
    public final void setFirstName(String firstName) { this.firstName.set(firstName); }
    public final String getFirstName() { return firstName.get(); }
    public final StringProperty firstNameProperty() { return firstName; }

    private final StringProperty lastName = new SimpleStringProperty(this, "lastName");
    public final void setLastName(String lastName) { this.lastName.set(lastName); }
    public final String getLastName() { return lastName.get(); }
    public final StringProperty lastNameProperty() { return lastName; }

    public Person() {}

    public Person(String firstName, String lastName) {
      setFirstName(firstName);
      setLastName(lastName);
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.