[这是我的以下代码。在这里我想从另一个类访问文本字段。 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();
}
}
[目标是在不破坏输出的情况下访问 textField 组件。正如我之前提到的,我尝试了一切可能的方法让它发挥作用,但我失败了。那么,是否有任何正确的方法可以正确地做到这一点,请提供,这将非常有帮助。如果有人提供的话,还请添加有关您的代码如何工作的评论。
预先感谢。]
尝试直接从单元格的
TextField
获取文本是错误的方法。 TableView
API 不提供获取特定索引处的单元格的方法。此外,表中的项目数可能多于显示的单元格数。使用文本字段存储应用程序状态将导致信息丢失。
A
TableView
有“模型”支持。该模型是一个公开属性的自定义类。该类本身代表表中的单个项目,显示在单行中。这些属性表示每列中显示的值。编辑单元格的值应该会导致新值被写回模型实例的属性。您可以在需要时通过项目获取新的值。
允许编辑的单元格实现采用两种形式之一。
单元格可以进入和退出编辑状态。编辑时,UI 更改为允许用户输入的控件。该实现通过单元的
startEdit
、cancelEdit
和 commitEdit
API 进行,外部代码对适当的事件做出反应。
单元格“始终在编辑”。这会绕过正常的编辑 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);
}
}
}