【问题标题】:Table with buttons using FXML (JavaFX)使用 FXML (JavaFX) 的带有按钮的表格
【发布时间】:2015-01-12 17:42:10
【问题描述】:

我正在学习 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 真的很陌生,并不是所有的细节我都清楚。

编辑2: 我的控制器代码如下所示:

public class FXMLDocumentController implements Initializable {

@FXML
private TableView<ColTab> tableView;    
tableView.getColumns().add(btnCol); 


@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
}    

}

现在我收到一条错误消息:

包tableView不存在

需要标识符

';'预计

我正在使用 Netbeasn 作为 ide。

【问题讨论】:

  • 你不能完全用 FXML 做到这一点;您至少需要一些 Java 用于单元工厂。
  • 好的...没有人有关于如何做到这一点的教程?我是 Java 和 FXML 的新手,但我想学习!
  • 如何发布一些代码作为您想要做的简单示例(尽可能),然后也许有人可以从那里帮助您。但是你需要一个单元工厂来满足你的需求,虽然你可以在 FXML 中使用它,但它必须用 Java 编写——无论是在控制器中还是在独立类中。
  • 我发布了一个我所做的示例。我希望它很清楚......

标签: java button javafx fxml


【解决方案1】:

您可以将复制的代码放入控制器的initialize 方法中。你已经在你的表上定义了一个fx:id=tableView 属性,所以我假设你有

@FXML
private TableView<ColTab> tableView ;

在控制器中。只需将额外的列添加到表格视图中

tableView.getColumns().add(btnCol);

要了解此列是如何配置的,您需要了解表格中显示的数据与数据的视图之间存在分隔(即向用户展示数据)。在 JavaFX 中,对于复杂的 UI 控件,例如表格、树和列表,数据的视图由一个单元格表示。您在列上设置的单元格工厂告诉 JavaFX 如何根据单元格中显示的数据创建 TableCell - 它本质上是一个在需要时创建 TableCells 的函数。单元格的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 JavadocsTableView Javadocs 中阅读有关单元机制的更多信息。 tutorial for ListViewTableView 也可能有帮助。

单元格值工厂告诉表格如何从该行的数据中获取特定单元格的数据。在这种情况下,这有点微妙。该按钮取决于整行的数据(因为它需要在其操作处理程序中使用这些数据),因此它只返回行数据对象的包装器。 TableColumn Javadocs 和上面链接的表格教程谈到了这一点。

【讨论】:

  • 感谢您的回复,James_D!我编辑了问题,为控制器添加了我的代码。现在,我收到一条错误消息:包 tableView 不存在。
  • 该代码需要放在一个方法中,并且在btnCol 在范围内并已初始化的某个位置(例如在您执行TableColumn&lt;ColTab, ColTab&gt; btnCol = new TableColumn&lt;&gt;(...); 之后)
猜你喜欢
  • 2019-10-27
  • 2015-07-21
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
相关资源
最近更新 更多