首页 文章

使用FXML(JavaFX)的按钮表

提问于
浏览
1

我正在学习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
}    

}

现在我收到的错误是:

package tableView不存在标识符';'预期

我使用Netbeasn作为ide .

1 回答

  • 1

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

    @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 JavadocsTableView Javadocs中详细了解有关单元机制的更多信息 . tutorial for ListViewTableView也可能有所帮助 .

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

相关问题