2016-09-09 15 views
0

私は現在TableViewRadioButtonを含む)を1つのTableCellに含むアプリケーションで作業しています。そのために、自分でRadioButtonCellクラスを作成しました。私はまた、 "新しい行の追加"ボタンを追加して、ユーザーがいくつかの行を追加できるようにしました。 3回目に「追加」ボタンをクリックすると、行よりもRadioButtonCellが多くなります。私は自分のコードで間違いを見つけません。ここでJavaFX - TableCellのラジオボタンとデータの追加ボタン

三度目Buttonをクリックした後、スクリーンショット:

part of the tableview

RadioButtonCell:

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); 
     } 
    } 
} 

モデル:

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; 
    } 
} 

はFXML:

<?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> 

コントローラー:

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

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の再作成はお勧めしません。 TableViewが細胞を再利用することによって回避しようとしているものである不要なノード創造の多く。フィールドに保管し、後で使用できるように保管してください。

関連する問題