JavaFX - TableCell中的RadioButtons,带有添加数据按钮

时间:2016-09-09 14:02:45

标签: javafx radio-button tableview

我目前正在开发一个应用程序,我在TableView中使用RadioButton TableCellRadioButtonCell。为此,我创建了一个自己的RadioButtonCell类。我还有一个"添加新行" -Button让用户添加一些额外的行。点击"添加"按钮第三次,我比行Button更多。我的代码中没有发现错误。

这是第三次点击import java.util.EnumSet; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; import javafx.scene.control.RadioButton; import javafx.scene.control.TableCell; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.HBox; public class RadioButtonCell<S,T extends Enum<T>> extends TableCell<S,T>{ private EnumSet<T> enumeration; public RadioButtonCell(EnumSet<T> enumeration) { this.enumeration = enumeration; } @Override protected void updateItem(T item, boolean empty) { super.updateItem(item, empty); if (!empty) { // GUI HBox hb = new HBox(7); hb.setAlignment(Pos.CENTER); final ToggleGroup group = new ToggleGroup(); // create a radio button for each 'element' of the enumeration for (Enum<T> enumElement : enumeration) { RadioButton radioButton = new RadioButton(enumElement.toString()); radioButton.setUserData(enumElement); radioButton.setToggleGroup(group); hb.getChildren().add(radioButton); if (enumElement.equals(item)) { radioButton.setSelected(true); } } // issue events on change of the selected radio button group.selectedToggleProperty().addListener(new ChangeListener<Toggle>() { @SuppressWarnings("unchecked") @Override public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) { getTableView().edit(getIndex(), getTableColumn()); RadioButtonCell.this.commitEdit((T) newValue.getUserData()); } }); setGraphic(hb); } } } 后的屏幕截图:

part of the tableview

RadioButtonCell:

public class Points {

    private final SimpleObjectProperty<Participation> participation = new SimpleObjectProperty<Participation>(); // radio buttons


    public static enum Participation {
        NONE, HALO, BORDER;

        public String toString() {
            return super.toString().toLowerCase();
        };
    }

    /**
     * Constructor.
     * @param <Participation>
     */
    public Points(Participation p) {

        this.participation.setValue(p);

    public void setParticipation(Participation p){
        participation.set(p);
    }

    public Participation getParticipation(){
        return participation.get();
    }

    public SimpleObjectProperty<Participation> ParticipationProperty() {
        return participation;
    }
}

型号:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<VBox prefHeight="900.0" prefWidth="1250.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="address.view.DataOverviewController">
   <children>
      <SplitPane fx:id="splitPaneVertical" prefHeight="776.0" prefWidth="1200.0" VBox.vgrow="ALWAYS">
         <items>
            <TabPane fx:id="tabPane" stylesheets="@Theme.css">
               <tabs>
                  <Tab text="Points">
                     <content>
                        <SplitPane fx:id="splitPaneHorizontal" dividerPositions="0.949874686716792" orientation="VERTICAL" stylesheets="@Theme.css">
                          <items>
                              <TableView fx:id="pointsDataTable">
                                <columns>                                
                                  <TableColumn fx:id="pointsBackgroundColumn" prefWidth="200.0" resizable="false" text="Background" />                                 
                                </columns>                                            
                              </TableView>
                            <AnchorPane SplitPane.resizableWithParent="false">
                                 <children>
                                    <HBox fx:id="pointsHBoxButton" alignment="CENTER" prefHeight="35.0" prefWidth="1016.0" spacing="20.0" stylesheets="@Theme.css" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                                       <children>
                                          <Button fx:id="pointsAddButton" mnemonicParsing="false" onAction="#handleAddPoints" text="Add" />                     
                                     </children>
                                </HBox>
                             </children>
                          </AnchorPane>
                       </items>
                    </SplitPane>
                 </content>
              </Tab>
           </tabs>
        </TabPane>
     </items>
  </SplitPane>

FXML:

    public class DataOverviewController {
        @FXML
        private TableView<Points> pointsDataTable;

        @FXML
        private TableColumn<Points, Participation> pointsBackgroundColumn;

        @FXML
        private Button pointsButtonAdd;

        public DataOverviewController() {
        }

        @FXML
        private void initialize() {
            // select multipe rows, make rows editable
            pointsDataTable.setEditable(true);
            pointsDataTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
            linesDataTable.setEditable(true);

             pointsBackgroundColumn.setCellFactory((param) -> new RadioButtonCell<Points, Participation>(EnumSet.allOf(Participation.class)));
             pointsBackgroundColumn.setCellValueFactory(new PropertyValueFactory<Points, Participation>("Participation"));
             pointsBackgroundColumn.setOnEditCommit(
                        new EventHandler<CellEditEvent<Points, Participation>>() {
                            @Override
                            public void handle(CellEditEvent<Points, Participation> t) {
                                ((Points) t.getTableView().getItems().get(
                                    t.getTablePosition().getRow())
                                    ).setParticipation(t.getNewValue());
                            }
                        }
                    );

        public void setMainConfig(MainConfig mainConfig) {
            // Add observable list data to the table
            pointsDataTable.setItems(mainConfig.getTableDataPoints());
        }

        @FXML
        private void handleAddPoints() {
            // create new record and add it to the tableview
            Points dataPoints = new Points(0, "Points", "TabFileName.tab",Participation.NONE, false, false, 18, "new");
            pointsDataTable.getItems().add(dataPoints);
        }
    }
}

控制器:

{{1}}

我将代码缩减为重要部分。也许有人可以帮忙? 感谢。

1 个答案:

答案 0 :(得分:1)

可以添加项目以及从TableCell中删除项目。这意味着您需要通过撤消添加项目时对单元格所做的任何更改来处理TableCell变空的情况。否则可能会TableCell看起来好像它们包含一个项目,尽管它们实际上是空的。

updateItem方法应如下所示:

@Override
protected void updateItem(T item, boolean empty) {
    super.updateItem(item, empty);

    if (empty) {
        // modifications to restore the empty state
    } else {
        // customized way of displaying the item
    }
}

此外,我不建议每次更改项目时重新创建Node以显示单元格中的项目,因为这意味着您将有许多不必要的节点创建,这是{{1试图通过重用细胞来避免。将它们存储在字段中并保留以供日后使用。