【问题标题】:JavaFX/FXML: TableView correctly refreshing in case of editing items, but not in case of removing items (ArrayList->TableView)JavaFX/FXML:TableView 在编辑项目的情况下正确刷新,但在删除项目的情况下(ArrayList->TableView)
【发布时间】:2021-04-14 04:58:11
【问题描述】:

我正在做一个更大的项目(和很多同学一起),我正在尝试显示一个 arrayList(我们在项目中反复使用的类型,所以我不会我不喜欢在 TableView 中将所有这些更改为 ObservableLists 只是为了我相当小的问题。

我创建了一个较小的项目,只是为了了解问题的核心并向您展示:

在 editMyGrades 类(连同同名的 fxml 文件)中,我想在 TableView 中显示我的 SUBJECT(-> String subjectName),每个都有其 GRADE(-> int 等级)。

初始化父根和tableView,ArrayList的subject被转化为ObservableList,加载到TableView中。

我真的很想从理论上理解,为什么 changeing GRADEs 与 tableView 一起工作,但 removing 却不行,并且想知道实际该怎么做;- )

非常感谢您!

主类:

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

课程主题:

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


}

控制类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();
    }

}

editingMyGrades.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>

【问题讨论】:

  • 只略读代码(它不是 Minimal :) - a)在一般情况下调用 table.refresh 是错误的,如果它似乎需要它是一个指示接线/设置有问题! b)不要使用静态范围! c)java命名约定,请
  • 错误是您从 Main 的列表中删除了主题(请参阅最后一条评论 - 静态范围是错误的 :) - 您应该将其从表的项目中删除
  • 谢谢!我总是尝试遵循从老师那里学到的惯例。我应该在哪里使用其他名称?
  • 类名必须以大写字母开头
  • 创建数据模型并将其传递给控制器​​。例如,参见stackoverflow.com/questions/32342864/applying-mvc-with-javafx

标签: java javafx arraylist tableview observablelist


【解决方案1】:

使用 JavaFX 时,最好始终使用 FXCollections。

当您对 ArrayList 进行修改时,这些更改不会生成列表更改通知。您必须从 tableview 获取 ObservableList 并对其执行操作,因为它是 ArrayList 支持的包装器(智能列表)。

【讨论】:

    【解决方案2】:

    非常感谢您的解释!事实上,在我真正的问题中,我使用的是 MVC,但是 Controller 对象位于 main - static - 中,并且看起来,它不能以其他方式完成。为了说明我的问题,我认为 id 不会有什么不同,如果我有一个带有列表的静态控制器对象或只是列表本身(也许我错了......)。 现在,尝试应用您告诉我的所有内容后,情况正好相反:tableView 显示删除,但没有更改。

    只是 fxml 控件类 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);
        }
    
    }
    

    【讨论】:

    • hmm .. 这是问题的答案还是修改?如果是前者,请澄清它解决了什么/如何解决,如果后者编辑问题
    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2017-12-11
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多