2016-12-01 23 views
2

こんにちは、これは、JavaとGUIの両方のデザインの新人として私の最初の質問です。 私は奇妙な状況に出くわしました。 TableViewにはいくつかの情報があり、追加ボタンを使って追加することもできます。 FilterListコンストラクタを追加する前に、削除ボタンが動作していたので、検索結果をIDでフィルタリングすることができます。一旦機能を追加すると、削除ボタンは機能しなくなりました。私は個人的に、deleteButtonClickedクラスがフィルタ機能を追加することによって、テーブルが正しく検出されていないと考えています。しかし、私が両方を守ろうとする限り、どちらか一方が通常動作を停止します。私は現在、Delete Buttonクラスを使用せずに、製品をnullにするだけで動作させようとしています。JavaFX GUI - なぜ削除ボタン機能がTableViewで動作しないのですか?

TableView関数はコードの最上部にあり、削除ボタンと関数は下部にあります。

package application; 

import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.collections.transformation.FilteredList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableColumn.CellEditEvent; 
import javafx.scene.control.TableView; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.control.cell.TextFieldTableCell; 
import javafx.scene.layout.HBox; 
import javafx.scene.text.FontWeight; 
import javafx.scene.text.Text; 

public class MainApp extends Application { 



    TableView<Product> table = new TableView<>(); 


    public static void main(String[] args) { 
     launch(args); 
    }   

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     BorderPane root = new BorderPane(); 

     BorderPane leftPane = new BorderPane(); 

     FilteredList<Product> filterList = new FilteredList<>(productData); 

     table.setEditable(true); 
     //table.setItems(productData); // DELETE BUTTON WORKS WHEN THIS ONE IS ONLY SET 
     table.setItems(filterList); // DELETE BUTTON DOESN'T WORK WHEN 
            // THIS IS SET BUT, IS NEEDED TO FILTER SEARCH FUNCTIONS 

     TableColumn<Product, String> idNumberCol = new TableColumn<>("ID Number"); 
     idNumberCol.setMinWidth(50); 
     idNumberCol.setCellValueFactory(new PropertyValueFactory<>("idNumber")); 

     idNumberCol.setCellFactory(TextFieldTableCell.<Product>forTableColumn()); 
     idNumberCol.setOnEditCommit(
     (CellEditEvent<Product, String> t) -> { 
     ((Product) t.getTableView().getItems().get(
      t.getTablePosition().getRow()) 
      ).setIdNumber(t.getNewValue()); 
}); 

     TableColumn<Product, String> desCol = new TableColumn<>("Description"); 
     desCol.setMinWidth(150); 
     desCol.setCellValueFactory(new PropertyValueFactory<>("description")); 

     desCol.setCellFactory(TextFieldTableCell.<Product>forTableColumn()); 
     desCol.setOnEditCommit(
     (CellEditEvent<Product, String> t) -> { 
     ((Product) t.getTableView().getItems().get(
      t.getTablePosition().getRow()) 
      ).setDescription(t.getNewValue()); 
}); 

     TableColumn<Product, String> expCol = new TableColumn<>("Expiration"); 
     expCol.setMinWidth(100); 
     expCol.setCellValueFactory(new PropertyValueFactory<>("expiration")); 

     expCol.setCellFactory(TextFieldTableCell.<Product>forTableColumn()); 
     expCol.setOnEditCommit(
     (CellEditEvent<Product, String> t) -> { 
     ((Product) t.getTableView().getItems().get(
      t.getTablePosition().getRow()) 
      ).setExpiration(t.getNewValue()); 
}); 


     table.getColumns().addAll(idNumberCol, desCol, expCol); 


     VBox leftVbox = new VBox(); 
     leftVbox.setPadding(new Insets(10, 20, 20, 20)); 
     leftVbox.setSpacing(10); 
     leftVbox.getChildren().addAll(table); 

     BorderPane topPane = new BorderPane(); 

     HBox topHbox = new HBox(); //Create HBox 
     topHbox.setPadding(new Insets(20, 20, 10, 20)); // Set padding and spacing for the hbox 
     topHbox.setSpacing(10); // The hbox will appropriately space out more 

     Text txtSearch = new Text("Search: "); 
     topHbox.getChildren().add(txtSearch); 
     txtSearch.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

     TextField txt = new TextField(""); // Create new TextField 
     txt.setPrefWidth(250); 
     txt.setPromptText("Search A Product ID"); // Sets up hint text inside the TextField 
     topHbox.getChildren().add(txt); // Add the TextField to the second hbox 

     HBox rightHbox = new HBox(); //Create HBox 
     rightHbox.setPadding(new Insets(20, 20, 10, 20)); // Set padding and spacing for the hbox 
     rightHbox.setSpacing(10); // The hbox will appropriately space out more 

     Text txtDetails = new Text("Product Details"); 
     rightHbox.getChildren().add(txtDetails); 
     txtDetails.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20)); 

     txt.textProperty().addListener((obsVal, oldValue, newValue) -> { 
     filterList.setPredicate(product -> product.getIdNumber().contains(newValue)); 
     }); 


     BorderPane rightPane = new BorderPane(); 

     VBox rightVbox = new VBox(); 
     rightVbox.setPadding(new Insets(20, 10, 10, 20)); 
     rightVbox.setSpacing(30); 
     rightVbox.setAlignment(Pos.TOP_LEFT); 

     Text txtId = new Text("ID: "); 
     rightVbox.getChildren().add(txtId); 
     txtId.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

     Text txtDes = new Text("Description: "); 
     rightVbox.getChildren().add(txtDes); 
     txtDes.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

     Text txtExp = new Text("Expiration: "); 
     rightVbox.getChildren().add(txtExp); 
     txtExp.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

     Text txtStatus = new Text("Status: "); 
     rightVbox.getChildren().add(txtStatus); 
     txtStatus.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

     Text txtEnter = new Text("Entered By: "); 
     rightVbox.getChildren().add(txtEnter); 
     txtEnter.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

     //EMPTY PLACE HOLDER INFORMATION TO POPULATE THE DATA 
     Label lblId; 
     Label lblDes; 
     Label lblExp; 
     Label lblStatus; 
     Label lblEnter; 

     HBox bottomHbox2 = new HBox(); 
     bottomHbox2.setPadding(new Insets(20, 20, 20, 20)); 
     bottomHbox2.setSpacing(10); 
     bottomHbox2.setAlignment(Pos.BOTTOM_RIGHT); 


     Button btnNew = new Button("Add..."); 
     bottomHbox2.getChildren().add(btnNew); 
     btnNew.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 

      Stage secondStage = new Stage(); 

      BorderPane dialogPane = new BorderPane(); 

      VBox dialogVbox = new VBox(); 
      dialogVbox.setPadding(new Insets(20, 10, 20, 20)); 
      dialogVbox.setSpacing(20);  

      TextField addId = new TextField(); 
      addId.setPromptText("ID Number"); 
      addId.setMinWidth(50); 
      //addId.setMaxWidth(idNumberCol.getPrefWidth()); 

      TextField addDes = new TextField(); 
      addDes.setPromptText("Description"); 
      addDes.setMinWidth(100); 
      //addDes.setMaxWidth(desCol.getPrefWidth()); 

      TextField addExp = new TextField(); 
      addExp.setPromptText("Expiration Date"); 
      addExp.setMinWidth(50); 
      //addExp.setMaxWidth(expCol.getPrefWidth()); 

      dialogVbox.getChildren().addAll(addId, addDes, addExp); 

      VBox dialogVbox2 = new VBox(); 
      dialogVbox2.setPadding(new Insets(20, 20, 20, 10)); 
      dialogVbox2.setSpacing(20);  

      Text txtIdLabel = new Text("ID: "); 
      dialogVbox2.getChildren().add(txtIdLabel); 
      txtIdLabel.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

      Text txtDesLabel = new Text("Description: "); 
      dialogVbox2.getChildren().add(txtDesLabel); 
      txtDesLabel.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

      Text txtExpLabel = new Text("Expiration: "); 
      dialogVbox2.getChildren().add(txtExpLabel); 
      txtExpLabel.setFont(Font.font("Tahoma", FontWeight.NORMAL, 16)); 

      HBox addHbox = new HBox(); 
      addHbox.setPadding(new Insets(20, 10, 50, 20)); 
      addHbox.setSpacing(10); 
      addHbox.setAlignment(Pos.BOTTOM_RIGHT); 

      Button btnAdd = new Button("Add Product"); 
      addHbox.getChildren().add(btnAdd); 

      btnAdd.setOnAction((ActionEvent e) -> { 
      productData.add(new Product(
        addId.getText(), 
        addDes.getText(), 
        addExp.getText())); 
      addId.clear(); 
      addDes.clear(); 
      addExp.clear(); 
     }); 

       Button btnClose = new Button("Close"); 
     addHbox.getChildren().add(btnClose); 

     btnClose.setOnAction(new EventHandler<ActionEvent>(){ 

       @Override 
       public void handle(ActionEvent arg0) { 
        secondStage.close(); 
       } 

      }); 

      dialogPane.setCenter(dialogVbox); 
      dialogPane.setLeft(dialogVbox2); 
      dialogPane.setBottom(addHbox); 

      Scene scene2 = new Scene(dialogPane, 400, 200); 

      secondStage.setTitle("Add New Product"); 
      secondStage.setScene(scene2); 
      secondStage.show(); 

       //Set position of second window, related to primary window. 
       secondStage.setX(primaryStage.getX() + 250); 
       secondStage.setY(primaryStage.getY() + 100); 

       secondStage.show(); 
      } 
     }); 

     // DELETE BUTTON & EVENT HANDLER 
     Button btnDelete = new Button("Delete"); 
     bottomHbox2.getChildren().add(btnDelete); 

     btnDelete.setOnAction(new EventHandler<ActionEvent>(){ 

       @Override 
       public void handle(ActionEvent arg0) { 
        deleteButtonClicked(); 
       } 

      }); 


     Button btnSave = new Button("Save & Exit"); 
     bottomHbox2.getChildren().add(btnSave); 

     btnSave.setOnAction(new EventHandler<ActionEvent>(){ 

       @Override 
       public void handle(ActionEvent arg0) { 
        primaryStage.close(); 
       } 

      }); 

     rightVbox.getChildren().add(bottomHbox2); 

     topPane.setLeft(topHbox); 
     topPane.setCenter(rightHbox); 
     leftPane.setLeft(leftVbox); 
     rightPane.setLeft(rightVbox); 
     //rightPane.setCenter(bottomHbox2); 

     root.setTop(topPane); 
     root.setLeft(leftPane); 
     root.setCenter(rightPane); 

     Scene scene = new Scene(root, 650, 500); 
     primaryStage.setTitle("Perishables Application"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    // DELETE BUTTON FUNCTION 
    public void deleteButtonClicked() { 
     ObservableList<Product> productSelected, productData; 
     productData = table.getItems(); 
     productSelected = table.getSelectionModel().getSelectedItems(); 

     productSelected.forEach(productData::remove); 
    } 

    public ObservableList<Product> productData = FXCollections.observableArrayList(
    new Product("001", "Cereal", "1/1/2017"), 
    new Product("002", "Dog Food", "3/3/2017"), 
    new Product("003", "Juice", "1/1/2018") 
    ); 


} 

ご意見をいただければ幸いです。読んでくれてありがとう。あなたが削除するとき、ObservableListないFilteredListからデータを削除したい

productSelected.forEach(this.productData::remove); 
          | 

言及

答えて

1

あなたはこのエラーを持っている:

Exception in thread "JavaFX Application Thread" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractCollection.remove(AbstractCollection.java:293) at application.MainApp.deleteButtonClicked(MainApp.java:297) at application.MainApp$2.handle(MainApp.java:255) at application.MainApp$2.handle(MainApp.java:1)

はとproductSelected.forEach(productData::remove);を交換してみてくださいそれらはObservableListから自動的に削除されます電子FilteredList<Product>


あなたは最小限のコードで、あなたの方法を書きたい場合は:

// DELETE BUTTON FUNCTION 
    public void deleteButtonClicked() { 
    table.getSelectionModel().getSelectedItems().forEach(this.productData::remove); 
    } 
+0

うわー、あまりにも非常にシンプルなソリューションを働いて、その、ありがとうございました。 「これ」を実行しました。現在のオブジェクトを直接参照するため、動作しますか? この状況でなぜ必要なのかを簡単に説明してください。私が説明したように、これまでにそれがなくてもうまくいきました。それが私を混乱させました。再度、感謝します。 – BecauseTurtles

+0

@BecauseTurtlesあなたのコードの前に '.getItems()'を使って 'FilteredList 'を取得し、その中から項目を削除しようとしていますが、 'FilteredList 'はもともと 'ObservableList'の項目を持っています。 'ObservableList'から項目を削除したいとします。それは自動的に 'FilteredList 'から削除されます。私は外側の 'ObservableList'を参照するのに' this'を使用しています。 – GOXR3PLUS

関連する問題