【问题标题】:How to add Linked list of objects to TableView using javafx/scene builder?如何使用 javafx/scene builder 将对象的链接列表添加到 TableView?
【发布时间】:2019-10-17 15:36:27
【问题描述】:

我正在开发一个相当简单的 javafx 应用程序,它有几个不同的场景,我的第一个场景是将 Show 对象添加到通用链表中,然后在第二个场景中添加其中一个节目的表演。对象(例如在节目中添加日场或晚间表演 Annie)

我已经创建了第一个场景并且可以将 Show 对象添加到链接列表中,但是我无法使用创建的节目填充第二个场景中的 tableview 以供用户选择和添加表演

这是我添加的显示控制器的样子:

public class AddShowController {

    @FXML private TextField titleField;
    @FXML private TextField cirField,stlField, balField;
    @FXML private Slider runTimeSlider;
    @FXML private DatePicker startDatePicker, endDatePicker;
    TheLinkedList<Show> showList = new TheLinkedList<>();

    private static AddShowController instance;

    public AddShowController() {
        instance = this;
    }

    public static AddShowController getInstance(){
        return instance;
    }

    public void addShowButtonPushed (ActionEvent e){

        showList.addElement(new Show (titleField.getText(),
                                (int) runTimeSlider.getValue(),
                                startDatePicker.getValue().toString(),
                                endDatePicker.getValue().toString(),
                                cirField.getText(),
                                stlField.getText(),
                                balField.getText()));
}

如您所见,我已尝试创建控制器实例,以便可以从添加性能控制器访问链接列表,但没有任何乐趣。

这是添加性能控制器:


public class AddPerfController {

    @FXML private ChoiceBox perfTimeChoiceBox;

    @FXML private TableView<Show> showTable;
    @FXML private TableColumn<Show, String> titleColumn;
    @FXML private TableColumn<Show, String> runTimeColumn;
    @FXML private TableColumn<Show, String> startDateColumn;
    @FXML private TableColumn<Show, String> endDateColumn;
    @FXML private TableColumn<Show, String> cirTicketPriceColumn;
    @FXML private TableColumn<Show, String> stlTicketPriceColumn;
    @FXML private TableColumn<Show, String> balTicketPriceColumn;

    private ObservableList<Show> showData = FXCollections.observableList(AddShowController.getInstance().showList);

    public void initialize() {
        perfTimeChoiceBox.getItems().addAll("Matinee","Evening");
        perfTimeChoiceBox.setValue("Matinee");

        titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));
        runTimeColumn.setCellValueFactory(new PropertyValueFactory<>("runningTime"));
        startDateColumn.setCellValueFactory(new PropertyValueFactory<>("startDate"));
        endDateColumn.setCellValueFactory(new PropertyValueFactory<>("endDate"));
        cirTicketPriceColumn.setCellValueFactory(new PropertyValueFactory<>("cirTicketPrice"));
        stlTicketPriceColumn.setCellValueFactory(new PropertyValueFactory<>("stlTicketPrice"));
        balTicketPriceColumn.setCellValueFactory(new PropertyValueFactory<>("balTicketPrice"));

        showData.add(new Show("Annie", 100,"12/12/2019", "14/12/2019","10","15", "20"));
        showTable.setItems(showData);

    }

【问题讨论】:

  • 不知道,如果TheLinkedList 正确实施。然而,作为与TableView 一起使用的ObservableList 的后备列表,这是一个糟糕的选择。在表的更新过程中,插入/删除元素时获得的任何性能都会丢失很多,因为这确实是通过索引访问...
  • 我必须使用链表进行分配,但不需要使用 tableview,我只需要在单独的场景中让用户可以选择显示对象,你建议我使用什么代替?
  • 取决于是否需要在模型中使用TheLinkedList。在某些情况下,只需使用不同的支持列表将其复制到ObservableList 就可以解决问题:showTable.getItems().setAll(theList); 顺便说一句,您可能看不到差异,除非您的列表变得非常大。无论如何,您需要创建一个minimal reproducible example:确保我们知道哪个 sn-ps 以哪个顺序被调用。目前,如果您做出几个假设,例如,您的代码似乎还可以。仅创建一个实例AddShowController(或子类型)。 (一般情况下最好避免使用static来传递数据)...

标签: java javafx linked-list tableview scenebuilder


【解决方案1】:

我们不确定这是你想要做的,但看看逻辑
我们使用的是模型视图控制器,因为我们的数据在数据库中
这就是我们填充名为 ctable 的表格的方式,而不是创意

    private void ReadFromChild() throws SQLException{

ObservableList<ChildModel> TableData = FXCollections.observableArrayList();
    stmnt = conn.createStatement();

    ResultSet rs = stmnt.executeQuery("SELECT * FROM Child WHERE cMonth ='"+strMONTH+"'AND cYear ='"+strYEAR+"'" );//works);
    while (rs.next()){// Add data to observableArrayList TableData to select a table ROW

    TableData.add(new ChildModel(rs.getString("CID"),rs.getString("cDisplayDate"),rs.getString("cTitle")));
    displayDATE = rs.getString("cDisplayDate");
    }
    PropertyValueFactory<ChildModel, String> IDCellValueFactory = new PropertyValueFactory<>("CID");
    colID.setCellValueFactory(IDCellValueFactory);
    PropertyValueFactory<ChildModel, String> DateCellValueFactory = new PropertyValueFactory<>("cDisplayDate");
    colDD.setCellValueFactory(DateCellValueFactory);
    PropertyValueFactory<ChildModel, String> TypeCellValueFactory = new PropertyValueFactory<>("cTitle");
    colTitle.setCellValueFactory(TypeCellValueFactory);

    Collections.sort(TableData, (p2, p1)-> p1.getCID().compareToIgnoreCase(p2.getCID()));
    // Line of Code above Sorts Database Columns based on VARIABLE in ChildModel
    // Change p2,p1 to sort Ascending or Descending
    if(TableData.size() < 15) {// Format TableView to display Vertical ScrollBar
        ctable.setPrefWidth(746);// 19 is the off set
    }else {
        ctable.setPrefWidth(765);
    }   ctable.setItems(TableData);
    stmnt.close();  
}

好的,当我们点击表格中的一行时,我们会转到另一个控制器,这里是该控制器的代码

    private void toDetailView() throws IOException{
    stage = (Stage)childTVPane.getScene().getWindow();// pane you are ON
    detailviewPane = FXMLLoader.load(getClass().getResource("detailview.fxml"));// pane you are GOING TO
    Scene scene = new Scene(detailviewPane);// pane you are GOING TO
    scene.getStylesheets().add(getClass().getResource("diary.css").toExternalForm());
    stage.setScene(scene);
    stage.setTitle("Diary Entry for "+displayDATE); 
    stage.show();
    stage.sizeToScene();
    stage.centerOnScreen(); 
}

private void showTableDataDetails(ChildModel info) throws IOException{
    if (info != null) {
       info =  (ChildModel) ctable.getSelectionModel().getSelectedItem();
       String str = info.getCID();
       strID = Integer.valueOf(str);
       toDetailView();
    }
}

@Override
public void initialize(URL url, ResourceBundle rb) {

    ctable.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends ChildModel>
        observable,ChildModel oldValue, ChildModel newValue) -> {
        try {
            showTableDataDetails((ChildModel) newValue); // When a row of the table is Selected call
            // Proper Construction                   // showTableDataDetails method
        } catch (IOException ex) {
            Logger.getLogger(ParentTableViewController.class.getName()).log(Level.SEVERE, null, ex);
        }
    });
}  

【讨论】:

  • 请使用 java 命名约定(因为您已经不止一次被问到 - 为什么不让您的答案尽可能可读;)
【解决方案2】:

这不是最好的解决方案,但它解决了我的问题,只是想更新这个问题。

我将 LinkedList 移至 Main 类,并将其设为 public static 以便从两个控制器访问它

public static TheLinkedList<Show> showList = new TheLinkedList<>();

为了使用 ObservableList,我在 TheLinkedList 类中使用以下方法将 LinkedList 转换为 arrayList

    public  Show[] getShowList(){
        Show[] newShows = new Show[counter];

        sample.Node temp = Main.showList.getHead();
        for(int i = 0; i<counter;i++ ){
            newShows[i] = (Show)temp.getData();
            temp = temp.getNext();
        }
        return newShows;
    }
    public void initialize() {
    showData = FXCollections.observableArrayList((Main.showList.getShowList()));
     (column data) .......
    showTable.setItems(showData);

}

【讨论】:

  • 绝对是最糟糕的选择 - 正如 fabian 已经指出的那样:不要使用全局静态字段在控制器之间传递值,永远不会!你越早开始就越好。有关更合适的选项,请参阅stackoverflow.com/questions/14187963/…
猜你喜欢
  • 1970-01-01
  • 2016-11-28
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 2014-03-27
相关资源
最近更新 更多