我正在学习JavaFX和FXML。我正在使用Oracle网站上提供的教程。
特别是,我正在使用FXML地址簿的Oracle示例作为起点(https://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm#CACFEHBI)开发应用程序。我现在要做的是添加一个列,其中包含与电话簿的每个条目相关联的按钮。例如,单击的按钮在另一个表上显示有关该名称条目的更多数据。我想用FXML做这件事。在网上搜索我发现了一些关于如何创建按钮列的资源,但它们看起来有点令人困惑,似乎他们没有使用FXML,这正是我所需要的。
有人可以建议我一些教程或提示吗?
编辑:我按照本教程(https://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm#CACFEHBI)开始工作。我想要做的部分内容在此处描述:JavaFX table- how to add components?。但是,这个例子并没有使用fxml。我想要做的是混合代码。 所以,我有一个fxml文件(取自上面链接的oracle教程),声明这个表,这样:
<TableView fx:id="tableView" GridPane.columnIndex="0"
GridPane.rowIndex="0">
<columns>
<TableColumn fx:id="Names_column" text="Table" prefWidth="100">
<cellValueFactory><PropertyValueFactory property="name" />
</cellValueFactory>
<cellFactory>
<FormattedTableCellFactory alignment="center">
</FormattedTableCellFactory>
</cellFactory>
</TableColumn>
<TableColumn text="Color" prefWidth="100">
<cellValueFactory><PropertyValueFactory property="color" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Button" prefWidth="100">
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<ColTab name="Table 1" color="1" />
<ColTab name="Table 2" color="2" />
<ColTab name="Table 3" color"1" />
</FXCollections>
</items>
</TableView>
然后,我看了另一个例子(JavaFX table- how to add components?)。在这个例子中,一切都只使用Java,但出于我的目的,我需要使用fxml。 在我的.java主文件中,我这样做了:
TableColumn<ColTab, ColTab> btnCol = new TableColumn<>("pulsanti");
btnCol.setMinWidth(150);
btnCol.setCellValueFactory(new Callback<CellDataFeatures<ColTab, ColTab>, ObservableValue<ColTab>>() {
@Override public ObservableValue<ColTab> call(CellDataFeatures<ColTab, ColTab> features) {
return new ReadOnlyObjectWrapper(features.getValue());
}
});
btnCol.setCellFactory(new Callback<TableColumn<ColTab, ColTab>, TableCell<ColTab, ColTab>>() {
@Override public TableCell<ColTab, ColTab> call(TableColumn<ColTab, ColTab> btnCol) {
return new TableCell<ColTab, ColTab>() {
final Button button = new Button(); {
button.setMinWidth(130);
}
@Override public void updateItem(final ColTab ColTab, boolean empty) {
super.updateItem(ColTab, empty);
if (ColTab != null) {
button.setText("Do something");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
//do something
}
});
}
}
};
}
});
//table.getColumns().addAll(firstNameCol, lastNameCol, emailCol, btnCol);
此代码是从我链接的第二个示例中复制的,实际上对我来说并不太清楚。我看到它创建了一个新列并设置了一些属性。最后一行代码(注释掉)将此列和其他一些列添加到一个表中,该表先前在原始.java文件中声明,并且我没有声明,因为我已经在表中声明了fxml文件。现在我正在寻找一种方法来集成我在.java文件中定义的这一列,在我在.fxml文件中声明的表中。 我知道我所说的可能看起来很混乱,但我对JavaFX和fxml并不熟悉,并不是所有的细节都清楚。
EDIT2: 我的控制器代码如下所示:
public class FXMLDocumentController implements Initializable {
@FXML
private TableView<ColTab> tableView;
tableView.getColumns().add(btnCol);
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
现在我收到一条错误消息:
包tableView不存在
预期的标识符
&#39 ;;&#39;预期
我使用Netbeasn作为ide。
答案 0 :(得分:1)
您可以将复制的代码放入控制器的initialize
方法中。您已经在桌面上定义了fx:id=tableView
属性,因此我假设您有
@FXML
private TableView<ColTab> tableView ;
在控制器中。只需使用
将额外的列添加到表视图中tableView.getColumns().add(btnCol);
要了解如何配置此列,您需要了解表中显示的数据与数据的视图之间存在分离(即向用户呈现数据)。在JavaFX中,对于复杂的UI控件(如表,树和列表),数据视图由单元格表示。您在列上设置的单元工厂告诉JavaFX如何从单元格中显示的数据创建TableCell
- 它本质上是一个在需要时创建TableCell
的函数。首次创建单元格时,以及数据更改时,都会调用单元格的updateItem(..)
方法。
updateItem(...)
方法中的逻辑不太正确。首先,您需要通过调用单元格的setGraphic(...)
方法实际显示单元格中的按钮。其次,您需要处理单元格为空的情况(即该项为空)。所以我会做这样的事情:
btnCol.setCellFactory(new Callback<TableColumn<ColTab, ColTab>, TableCell<ColTab, ColTab>>() {
@Override public TableCell<ColTab, ColTab> call(TableColumn<ColTab, ColTab> btnCol) {
final Button button = new Button();
button.setMinWidth(130);
TableCell<ColTab, ColTab> cell = new TableCell<ColTab, ColTab>() {
@Override public void updateItem(final ColTab ColTab, boolean empty) {
super.updateItem(ColTab, empty);
if (ColTab == null) {
setGraphic(null);
} else {
button.setText("Do something");
setGraphic(button);
}
}
};
button.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
ColTab currentItem = cell.getItem();
//do something with current item...
}
});
return cell ;
}
});
您可以在Cell
Javadocs和TableView
Javadocs中详细了解有关细胞机制的信息。 tutorial for ListView
和TableView
也可以提供帮助。
单元格值工厂告诉表格如何从该行的数据中获取特定单元格的数据。在这种情况下,这有点微妙。该按钮取决于整行的数据(因为它将在其动作处理程序中需要这些数据),因此它只返回行数据对象周围的包装器。上面链接的TableColumn
Javadocs和表格教程谈到了这一点。