如何通过反映 entriesList 中的更改来解决编辑条目和新条目的问题

How to fix problems with edit entry and new entry with reflecting changes in entriesList

我对 javafx 略知一二,尽我所能。我在反映“entriesList”中的变化时遇到了某些问题,它基本上是我在时间轴选项卡中显示的“FeedBox”对象的列表.我很难实施 observableList.

我读过使用 Bindings.bindContentBidirectional 绑定“entiesList”和 observableArrayListentries ”。通过更改 "entries",我想将其反映到“entiesList”。不知道这是否是正确的方法。如果您能提出更好的建议,那就太棒了。并且还没有找到正确的方法来更新 observableList 中的“textField”属性以编辑条目。

Here is picture of what I'm trying to do

FeedBox is VBox with date,time and text fields.

控制器class

     public class Controller {

        public static ObservableList<Node> entries;
        @FXML
            VBox entriesList;

    public void initialize(){
            entries = FXCollections.observableArrayList();
            try {

                ConnectionClass connectionClass = new ConnectionClass();
                Connection conn = connectionClass.getConnection();
                Statement statement = conn.createStatement();
                ResultSet list = statement.executeQuery("SELECT * FROM timeline WHERE user='Kiran' ORDER BY ID DESC;" );
                while (list.next()){
                    entries.add(new FeedBox(list.getString("ID"),list.getString("date"),list.getString("time"),list.getString("text")));
                }
                entriesList.getChildren().addAll(entries);
                Bindings.bindContentBidirectional(entries,entriesList.getChildren());


                System.out.println(entriesList.getChildren());
                Bindings.bindContent(entries, entriesList.getChildren());
                statement.close();
                conn.close();
            }catch (SQLException e){
                e.printStackTrace();
                System.out.println("SQLException");
            }

        }
}

FeedBox class

public class FeedBox extends Region {

    private String id;
    private VBox feedbox;
    private Text dateField,timeField;
    private TextArea textField;
    private Button editEntry;

    public FeedBox(String feed_id,String date,String time,String text){
        id = new String(feed_id);
        dateField = new Text(date);
        timeField = new Text(time);
        textField = new TextArea(text);
        editEntry = new Button("Edit");

        dateField.setTextAlignment(TextAlignment.LEFT);
        dateField.setFont(Font.font("Times New Roman Italic",14));
        timeField.setTextAlignment(TextAlignment.LEFT);
        timeField.setFont(Font.font("Times New Roman Italic",14));
        textField.setPrefSize(200,200);
        textField.setEditable(false);
        editEntry.setVisible(false);

        editEntry.addEventHandler(MouseEvent.MOUSE_CLICKED,e ->OnClick_editEntry());

        HBox header = new HBox(15,editEntry,dateField,timeField);
        header.setPadding(new Insets(5,15,5,10));
        header.fillHeightProperty();
        header.setAlignment(Pos.TOP_RIGHT);

        feedbox = new VBox(10,header,textField);
        feedbox.setPadding(new Insets(10,10,10,10));
        feedbox.setPrefSize(700,150);
        feedbox.addEventHandler(MouseEvent.MOUSE_ENTERED,e->setEditEntryVisibility(true));
        feedbox.addEventHandler(MouseEvent.MOUSE_EXITED,e->setEditEntryVisibility(false));
        feedbox.setId(id);

        getChildren().add(feedbox);
    }


    public String toString(){
        return textField.getText();
    }

    public void setEditEntryVisibility(boolean flag){
        editEntry.setVisible(flag);
    }

    public void OnClick_editEntry(){
        try {
            Dialog<ButtonType> editEntryWindow = new Dialog<>();
            editEntryWindow.initOwner(feedbox.getScene().getWindow());
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("/FXMLFiles/EditEntryDialog.fxml"));
            editEntryWindow.getDialogPane().getButtonTypes().add(ButtonType.OK);
            editEntryWindow.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);
            EditEntryController editEntryController = new EditEntryController(this.id,editEntryWindow);
            loader.setController(editEntryController);
            editEntryWindow.getDialogPane().setContent(loader.load());

            Optional<ButtonType> res = editEntryWindow.showAndWait();
            if(res.isPresent() && res.get()==ButtonType.OK){
                editEntryController.OnClick_OKButton(this);
            }

        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public void setTextField(String text){
        textField.setText(text);
    }

NewEntryControllerclass

public void OnClick_OKButton(){
        String TABLE_NAME="timeline";
        String USER_NAME="Kiran";
        String TEXT_DATA=textArea.getText();
        String DATE= LocalDate.now().toString();
        String TIME = formatter.format(LocalTime.now());
        String ID;

        try {
            ConnectionClass connectionClass = new ConnectionClass();
            Connection conn = connectionClass.getConnection();
            Statement statement = conn.createStatement();
            statement.execute("INSERT INTO "+ TABLE_NAME + " (user,date,time,text) VALUES('" + USER_NAME + "','" + DATE + "','"+ TIME + "','" + TEXT_DATA + "')" );
            ResultSet res = statement.executeQuery("SELECT ID FROM timeline WHERE DATE='"+DATE+"' AND TIME='"+TIME+"' AND USER='"+USER_NAME+"';");
            res.next();
            ID = res.getString("ID");
            Controller.entries.add(0,new FeedBox(ID,DATE,TIME,TEXT_DATA));
            System.out.println(Controller.entries);
            statement.close();
            conn.close();
        }catch (SQLException e){
            System.out.println("MySQL db conn error");
            e.printStackTrace();
        }
        System.out.println("NewEntry Window closed with OK button");

    }

EditEntryController class

public void OnClick_OKButton(FeedBox feedBox){
        String TABLE_NAME="timeline";
        String USER_NAME="Kiran";
        String TEXT_DATA = textArea.getText();

        try {
            ConnectionClass connectionClass = new ConnectionClass();
            Connection conn = connectionClass.getConnection();
            Statement statement = conn.createStatement();
            statement.execute("UPDATE timeline SET text=" + "'" + TEXT_DATA + "'" + " WHERE ID=" + id + " AND user=" + "'"+USER_NAME + "';");
            statement.close();
            conn.close();
        }catch (SQLException e){
            System.out.println("MySQL db conn error");
            e.printStackTrace();
        }
        int index=Controller.entries.indexOf(feedBox);
        Controller.entries.add(index,new FeedBox(id,dateText.getText(),timeText.getText(),textArea.getText()));
        Controller.entries.remove(index+1);
        System.out.println("onClick:Button@OKButton");
        System.out.println("EditEntry Dialog closed with OK button");
        System.out.println(Controller.entries);
    }

我也有这个堆栈跟踪;在 NewEntryController 的条目中添加 FeedBox 对象时,它被添加到列表中两次,如下面的堆栈跟踪所示。但是它直接显示在场景中(只显示一次)。

Exception in thread "JavaFX Application Thread" java.lang.UnsupportedOperationException
    at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1058)
    at javafx.base/javafx.collections.ListChangeBuilder.nextRemove(ListChangeBuilder.java:204)
    at javafx.base/javafx.collections.ObservableListBase.nextRemove(ObservableListBase.java:150)
    at javafx.base/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:181)
    at java.base/java.util.AbstractList$Itr.remove(AbstractList.java:387)
    at java.base/java.util.AbstractList.removeRange(AbstractList.java:598)
    at javafx.base/javafx.collections.ModifiableObservableListBase.removeRange(ModifiableObservableListBase.java:121)
    at java.base/java.util.AbstractList$SubList.removeRange(AbstractList.java:811)
    at java.base/java.util.AbstractList.clear(AbstractList.java:243)
    at javafx.base/javafx.collections.ModifiableObservableListBase$SubObservableList.clear(ModifiableObservableListBase.java:350)
    at javafx.base/com.sun.javafx.binding.ContentBinding$ListContentBinding.onChanged(ContentBinding.java:114)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.lambda$new[=14=](VetoableListDecorator.java:76)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    at javafx.base/javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.base/javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.base/javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    at javafx.base/com.sun.javafx.collections.ObservableListWrapper.remove(ObservableListWrapper.java:167)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:168)
    at javafx.base/com.sun.javafx.binding.BidirectionalContentBinding$ListContentBinding.onChanged(BidirectionalContentBinding.java:135)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    at javafx.base/javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.base/javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.base/javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    at javafx.base/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:183)
    at App.EditEntryController.OnClick_OKButton(EditEntryController.java:82)
    at App.FeedBox.OnClick_editEntry(FeedBox.java:102)
    at App.FeedBox.lambda$new[=14=](FeedBox.java:47)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3564)
    at javafx.graphics/javafx.scene.Scene$ClickGenerator.access00(Scene.java:3492)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3860)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.access00(Scene.java:3579)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2588)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent(GlassViewEventHandler.java:434)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:835)
onClick:Button@OKButton
EditEntry Dialog closed with OK button
[hello world, hello world, nice one, hey there, you good?]

控制器class

Bindings.bindContentBidirectional(entriesList.getChildren(),entries);

通过使用 entriesList.getChildren() 作为基础 listentries 作为observableList 修复了所有与编辑和新条目相关的问题。

谢谢@avi 肯定是参数问题

仍然欢迎有关代码优化或任何可以改进的替代实现的建议。