[英]JavaFX/FXML: TableView correctly refreshing in case of editing items, but not in case of removing items (ArrayList->TableView)
我正在做一個更大的項目(和很多同學一起),我正在嘗試展示一個 arrayList (我們在項目中一遍又一遍地使用這種類型,所以我不喜歡將所有這些更改為 ObservableLists 只是為了我相當小的問題)在 TableView 中。
我創建了一個較小的項目只是為了解決問題的核心並向您展示:
在 class editMyGrades(連同同名的 fxml 文件)中,我想在 TableView 中顯示我的 SUBJECT(-> String subjectName),每個都有其 GRADE(-> int 等級)。
初始化父根和 tableView 將 ArrayList 主題轉換為 ObservableList,然后加載到 TableView 中。
我真的很想從理論上理解,為什么更改GRADEs 可以與 tableView 一起使用,但刪除卻不行,並且實際上要知道如何處理它;-)
非常感謝您!
主class:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.ArrayList;
public class Main extends Application {
private static ArrayList<Subject> subjects = new ArrayList<>();
public static ArrayList<Subject> getSubjects () {return subjects;}
// private static ObservableList<Subject> subjects = FXCollections.observableArrayList();
// public static ObservableList<Subject> getSubjects () {return subjects;}
public static void main (String[] args) {
subjects.add(new Subject("computer science", 2));
subjects.add(new Subject("literature", 4));
launch (args);
}
public void start (Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/editMyGrades.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Class 主題:
public class Subject {
private String subjectName;
private int grade;
public Subject (String subjectName, int grade) {
this.subjectName = subjectName;
this.grade = grade;
}
public String getSubjectName () {return subjectName;}
public int getGrade () {return grade;}
public void setGrade (int grade) {this.grade = grade;}
}
控制 class editMyGrades:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import java.util.ArrayList;
public class editMyGrades {
Subject subjectToEdit;
@FXML
private TableView<Subject> tableView;
@FXML
private TableColumn<Subject, String> subjectCol;
@FXML
private TableColumn<Subject, Number> gradeCol;
@FXML
private TextField textField;
@FXML
private Button changeButton;
@FXML
private Button deleteButton;
@FXML
public void initialize() {
subjectCol.setCellValueFactory(new PropertyValueFactory<>("subjectName"));
gradeCol.setCellValueFactory(new PropertyValueFactory<>("grade"));
//tableView.setItems (FXCollections.observableArrayList(Main.getSubjects()));
ObservableList<Subject> subjects = FXCollections.observableArrayList(Main.getSubjects());
tableView.setItems(subjects);
}
@FXML
private void tableViewClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
subjectToEdit = tableView.getSelectionModel().getSelectedItem();
textField.setText ("" + tableView.getSelectionModel().getSelectedItem().getGrade());
}
}
@FXML
private void change(ActionEvent event) {
subjectToEdit.setGrade(Integer.parseInt(textField.getText()));
textField.clear();
tableView.refresh();
}
@FXML
private void delete (ActionEvent event) {
Subject selectedSubject = tableView.getSelectionModel().getSelectedItem();
ArrayList<Subject> subjects = Main.getSubjects();
subjects.remove(selectedSubject);
tableView.refresh();
}
}
編輯MyGrades.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="editMyGrades">
<children>
<Label text="change your grades!" />
<HBox>
<children>
<TableView fx:id="tableView" onMouseClicked="#tableViewClicked" prefHeight="200.0" prefWidth="518.0">
<columns>
<TableColumn fx:id="subjectCol" prefWidth="262.0" text="subject" />
<TableColumn fx:id="gradeCol" minWidth="0.0" prefWidth="146.0" text="grade" />
</columns>
</TableView>
<VBox alignment="CENTER">
<children>
<Button mnemonicParsing="false" onAction="#delete" text="deleteButton" />
</children>
</VBox>
</children>
</HBox>
<TextField fx:id="textField" maxWidth="100.0" />
<Button fx:id="changeButton" mnemonicParsing="false" onAction="#change" text="Change!" />
</children>
</VBox>
使用 JavaFX 時,最好始終使用 FXCollections。
當您對 ArrayList 進行修改時,這些更改不會生成列表更改通知。 您必須從 tableview 獲取 ObservableList 並對其執行操作,因為它是 ArrayList 支持的包裝器(智能列表)。
確實感謝您的解釋,事實上,在我的真正問題中,我使用的是 MVC,但是 Controller object 位於主要位置 - static - 和看起來一樣。 它不能以其他方式完成,為了說明我的問題,我認為 id 不會有所作為。 如果我有一個 static controller object 和列表或只是列表本身(也許我錯了......),現在,在嘗試應用你告訴我的所有內容后,它會以其他方式顯示: 但沒有變化。
只是 fxml 控件 class EditMyGrades:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
public class EditMyGrades {
private ObservableList<Subject> subjects = FXCollections.observableArrayList();
private Subject subjectToEdit;
@FXML
private TableView<Subject> tableView;
@FXML
private TableColumn<Subject, String> subjectCol;
@FXML
private TableColumn<Subject, Number> gradeCol;
@FXML
private TextField textField;
@FXML
private Button changeButton;
@FXML
private Button deleteButton;
@FXML
public void initialize() {
subjectCol.setCellValueFactory(new PropertyValueFactory<>("subjectName"));
gradeCol.setCellValueFactory(new PropertyValueFactory<>("grade"));
subjects.add(new Subject("computer science", 2));
subjects.add(new Subject("literature", 4));
tableView.setItems(subjects);
}
@FXML
private void tableViewClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
subjectToEdit = tableView.getSelectionModel().getSelectedItem();
textField.setText ("" + tableView.getSelectionModel().getSelectedItem().getGrade());
}
}
@FXML
private void change(ActionEvent event) {
subjectToEdit.setGrade(Integer.parseInt(textField.getText()));
textField.clear();
}
@FXML
private void delete (ActionEvent event) {
ObservableList<Subject> subjects = tableView.getItems();
Subject selectedSubject = tableView.getSelectionModel().getSelectedItem();
subjects.remove(selectedSubject);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.