在 FXML 中定义 TableView onMousePressed 操作
Defining TableView onMousePressed actions in FXML
我有一个正在处理的 Java 项目,它使用 JavaFX 生成 UI。我不是一个 Java 程序员(一般来说不是一个程序员 - 我是 CS 学生),所以这是一种学习经验,但通常我会在回答我自己的问题时去。不过,我现在遇到了 TableView 的棘手问题,有点迷路了 - 具体来说,我似乎无法设置任何类型的操作来响应与 TableView 的交互。
我项目的当前布局是 Main.java、Controller.java 和 UI.fxml。在 Main 中,pane/scene 在程序启动时从 UI.fxml 加载。 (从技术上讲,该项目包含其他几个代码位,但我只尝试 post 相关的内容。)我在 UI.fxml 中定义了一个 TableView,如下所示:
<TableView fx:id="queueTable">
<columns>
<TableColumn text="Title">
<cellValueFactory>
<PropertyValueFactory property="tableTitle"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Artist">
<cellValueFactory>
<PropertyValueFactory property="tableArtist"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Album">
<cellValueFactory>
<PropertyValueFactory property="tableAlbum"/>
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
同样,我在 UI.fxml 中使用 onAction 定义了几个按钮:
<Button fx:id="buttonQueueAdd" text="Add" onAction="#addMediaToQueue"/>
在我之前的代码中,我能够在生成 TableView 的方法中为选择 TableView 中的项目定义一个事件。但是,现在所有 UI 创建都是通过 FXML 文件完成的。 FXML 文件有一个控制器 class 它引用 (Controller.java),其中为各种按钮定义了所有操作,但我似乎无法让它接受任何属性,如 [=12] =]、setOnMousePressed
等在 TableView 的 FXML 文件中,就像它接受 Button 的 'onAction' 属性一样。
看来我可以通过在 Main class 中定义操作(或在 Controller class 中创建一个在 Main class 中调用的方法来获得解决方法,当创建场景时),但这将不起作用,除非我在我的控制器 class 中使 queueTable
静态......然后打破所有操作 TableView 中项目的功能 - 例如,我无法再向 TableView/the 添加项目 UI 不刷新以显示项目已添加。
似乎最好的解决方案是不在 FXML 中创建 TableView,而是在 FXML 文件之外创建 TableView 及其所有 onMousePressed 事件等,并将它们添加到场景中我的 Main class 的 start
方法。以前就是这样做的,当时效果还可以。然而,这看起来很混乱,并导致我的 UI 元素散布在多个 classes and/or FXML 文件中 - 这是我正在与其他几个学生合作的项目,并且我尽量保持一切 streamlined/organized。我是必须硬着头皮按照 "messy" 的方式去做,还是有更好的选择?
您仍然可以使用 fxml 生成 TableView
,但要向控制器添加 initialize
方法。此方法在创建对象结构后由 FXMLLoader
调用,可用于对对象结构进行修改,而这在 fxml 中是做不到的:
@FXML
private void initialize() {
queueTable.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
...
});
}
如果您需要从 Main
添加此侦听器,您可以向控制器添加一个方法并从用于创建 fxml 的 FXMLLoader
实例获取控制器。
控制器
public void addSelectedIndexListener(ChangeListener<? super Number> listener) {
queueTable.getSelectionModel().selectedIndexProperty().addListener(listener);
}
主要
FXMLLoader loader = new FXMLLoader(fxmlUrl);
myNode = loader.load();
Controller controller = loader.getController();
controller.addSelectedIndexListener((observable, oldValue, newValue) -> {
...
});
注意是一个属性 属性 应该取决于一个属性 的选择模型,你也许可以使用expression binding 来达到想要的效果。
<BorderPane xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<center>
<TableView fx:id="table" BorderPane.alignment="CENTER">
<columns>
<TableColumn text="value">
<cellValueFactory>
<PropertyValueFactory property="value"/>
</cellValueFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Item value="Hello World"/>
<Item value="42"/>
</FXCollections>
</items>
</TableView>
</center>
<left>
<Button mnemonicParsing="false" text="Remove" BorderPane.alignment="CENTER" disable="${table.selectionModel.selectedIndex+0<0}" />
</left>
</BorderPane>
请注意,table.selectionModel.selectedIndex+0<0
部分是一种变通方法,因为 JavaFX 当前不使用 null
-安全相等性检查(table.selectionModel.selectedItem==null
不起作用)并且无法获取用于比较的 0
常量的类型 (table.selectionModel.selectedIndex<0
),因此目前这似乎不是一个好的选择。
我有一个正在处理的 Java 项目,它使用 JavaFX 生成 UI。我不是一个 Java 程序员(一般来说不是一个程序员 - 我是 CS 学生),所以这是一种学习经验,但通常我会在回答我自己的问题时去。不过,我现在遇到了 TableView 的棘手问题,有点迷路了 - 具体来说,我似乎无法设置任何类型的操作来响应与 TableView 的交互。
我项目的当前布局是 Main.java、Controller.java 和 UI.fxml。在 Main 中,pane/scene 在程序启动时从 UI.fxml 加载。 (从技术上讲,该项目包含其他几个代码位,但我只尝试 post 相关的内容。)我在 UI.fxml 中定义了一个 TableView,如下所示:
<TableView fx:id="queueTable">
<columns>
<TableColumn text="Title">
<cellValueFactory>
<PropertyValueFactory property="tableTitle"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Artist">
<cellValueFactory>
<PropertyValueFactory property="tableArtist"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Album">
<cellValueFactory>
<PropertyValueFactory property="tableAlbum"/>
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
同样,我在 UI.fxml 中使用 onAction 定义了几个按钮:
<Button fx:id="buttonQueueAdd" text="Add" onAction="#addMediaToQueue"/>
在我之前的代码中,我能够在生成 TableView 的方法中为选择 TableView 中的项目定义一个事件。但是,现在所有 UI 创建都是通过 FXML 文件完成的。 FXML 文件有一个控制器 class 它引用 (Controller.java),其中为各种按钮定义了所有操作,但我似乎无法让它接受任何属性,如 [=12] =]、setOnMousePressed
等在 TableView 的 FXML 文件中,就像它接受 Button 的 'onAction' 属性一样。
看来我可以通过在 Main class 中定义操作(或在 Controller class 中创建一个在 Main class 中调用的方法来获得解决方法,当创建场景时),但这将不起作用,除非我在我的控制器 class 中使 queueTable
静态......然后打破所有操作 TableView 中项目的功能 - 例如,我无法再向 TableView/the 添加项目 UI 不刷新以显示项目已添加。
似乎最好的解决方案是不在 FXML 中创建 TableView,而是在 FXML 文件之外创建 TableView 及其所有 onMousePressed 事件等,并将它们添加到场景中我的 Main class 的 start
方法。以前就是这样做的,当时效果还可以。然而,这看起来很混乱,并导致我的 UI 元素散布在多个 classes and/or FXML 文件中 - 这是我正在与其他几个学生合作的项目,并且我尽量保持一切 streamlined/organized。我是必须硬着头皮按照 "messy" 的方式去做,还是有更好的选择?
您仍然可以使用 fxml 生成 TableView
,但要向控制器添加 initialize
方法。此方法在创建对象结构后由 FXMLLoader
调用,可用于对对象结构进行修改,而这在 fxml 中是做不到的:
@FXML
private void initialize() {
queueTable.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
...
});
}
如果您需要从 Main
添加此侦听器,您可以向控制器添加一个方法并从用于创建 fxml 的 FXMLLoader
实例获取控制器。
控制器
public void addSelectedIndexListener(ChangeListener<? super Number> listener) {
queueTable.getSelectionModel().selectedIndexProperty().addListener(listener);
}
主要
FXMLLoader loader = new FXMLLoader(fxmlUrl);
myNode = loader.load();
Controller controller = loader.getController();
controller.addSelectedIndexListener((observable, oldValue, newValue) -> {
...
});
注意是一个属性 属性 应该取决于一个属性 的选择模型,你也许可以使用expression binding 来达到想要的效果。
<BorderPane xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<center>
<TableView fx:id="table" BorderPane.alignment="CENTER">
<columns>
<TableColumn text="value">
<cellValueFactory>
<PropertyValueFactory property="value"/>
</cellValueFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Item value="Hello World"/>
<Item value="42"/>
</FXCollections>
</items>
</TableView>
</center>
<left>
<Button mnemonicParsing="false" text="Remove" BorderPane.alignment="CENTER" disable="${table.selectionModel.selectedIndex+0<0}" />
</left>
</BorderPane>
请注意,table.selectionModel.selectedIndex+0<0
部分是一种变通方法,因为 JavaFX 当前不使用 null
-安全相等性检查(table.selectionModel.selectedItem==null
不起作用)并且无法获取用于比较的 0
常量的类型 (table.selectionModel.selectedIndex<0
),因此目前这似乎不是一个好的选择。