ComboBox刷新JavaFx

时间:2018-02-13 18:27:26

标签: javafx combobox

我有一个包含多个项目的ComboBox,当点击其中一个项目时,应用程序应该从ComboBox中的数据库加载新项目。

我使用Platform.RunLater首先使用combobox.getItems()清除ComboBox的数据.clear();然后从数据库中再次获取数据并更新ComboBox。

第一次从ComboBox中的数据库加载数据时它可以工作但是当单击ComboBox下拉菜单中的项目时,应用程序显示以下错误:

  Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
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.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.Node.fireEvent(Node.java:8863)
at javafx.controls/javafx.scene.control.skin.ComboBoxListViewSkin.lambda$new$7(ComboBoxListViewSkin.java:182)
at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$1(LambdaMultiplePropertyChangeListenerHandler.java:49)
at javafx.base/javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base/javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:106)
at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113)
at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.controls/javafx.scene.control.ComboBoxBase.setValue(ComboBoxBase.java:151)
at javafx.controls/javafx.scene.control.ComboBox.updateValue(ComboBox.java:520)
at javafx.controls/javafx.scene.control.ComboBox.access$200(ComboBox.java:194)
at javafx.controls/javafx.scene.control.ComboBox$3.changed(ComboBox.java:503)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base/javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
at javafx.base/javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113)
at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.controls/javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:105)
at javafx.controls/javafx.scene.control.ComboBox$ComboBoxSelectionModel.lambda$new$0(ComboBox.java:560)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:136)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base/javafx.beans.property.ReadOnlyIntegerPropertyBase.fireValueChangedEvent(ReadOnlyIntegerPropertyBase.java:72)
at javafx.base/javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:102)
at javafx.base/javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:114)
at javafx.base/javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:148)
at javafx.controls/javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:69)
at javafx.controls/javafx.scene.control.ComboBox$ComboBoxSelectionModel$2.onChanged(ComboBox.java:591)
at javafx.base/javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
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.clear(ObservableListWrapper.java:157)
at com.sener.dbgui.controller.ComponentController$1$1.run(ComponentController.java:289)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
... 64 more
Caused by: java.lang.NullPointerException
at com.sener.dbgui.controller.ComponentController.manufacturerAction(ComponentController.java:195)
... 75 more

我使用DataResult解决方案向this提问以从数据库中获取数据。 由于查询数据库的结果是一个唯一的列,我可以从DataResult获取第0列的所有元素。

在初始化视图时调用fillComboBox()方法中的部分代码,并在单击组合框的项目时再次调用:

...
//Load data into dataFromCommonDAO (DataResult Object)
dataFromCommonDAO = newCommonDAOImpl.getDataFromDB(inputsList);

//JavaFX main Thread
Platform.runLater(new Runnable() {

                        public void run() {
                            //First clear all items of ComboBox
                            cmbBox.getItems().clear();

                            cmbBox.setEditable(true);
                            cmbBox.setVisibleRowCount(10);

                            if (cmbBox == cmbManufacturer) {

                                cmbBox.getItems().add("NEW MANUFACTURER");

                            }

                            for (int i = 0; i < dataFromCommonDAO.getNumRows() ; i++ ) {
                                cmbBox.getItems().add(dataFromCommonDAO.getData(0,i).toString());
                            }

                            if (cmbBox == cmbManufacturer && sqlFile.equals("getManufNamesbyPN.txt") ) {
                                cmbBox.getItems().add("SHOW ALL...");
                            }
                        }
                    });

...

如果我不使用getItems()。clear(),除了从数据库获得的新数据外,ComboBox还会显示以前加载的数据。

那么,如何在没有此错误的情况下刷新ComboBox?

1 个答案:

答案 0 :(得分:0)

好的,所以我在Action中遇到问题,应用程序将所选项目与其他String进行比较。 它基本上是ComboBox选择值和固定字符串值之间的字符串比较错误。

发出错误的代码是:

    @FXML
    void manufacturerAction(ActionEvent event) {
        if (cmbManufacturer.getValue().equals("NEW MANUFACTURER")) {

            ...

        }else if (cmbManufacturer.getValue().equals("SHOW ALL...")) {
            //Here is where the update combobox method is called. 
            //It will reload manufacturer ComboBox with all manufacturer from table

            fillComboBox(cmbManufacturer, sqlFileNameManuf);

        }
    }
  ...

更正的代码:

    private String newManufacturer = "NEW MANUFACTURER";
    private String otherManufacturers = "SHOW ALL..";
    ...
    @FXML
    void manufacturerAction(ActionEvent event) {

        if ( newManufacturer.equals(cmbManufacturer.getValue())) {

            ...
        }else if (otherManufacturers.equals(cmbManufacturer.getValue() )) {

            fillComboBox(cmbManufacturer, sqlFileNameManuf);
        }
 ...

这里的问题是,当我基本上只改变了字符串比较中的顺序时,它为什么会出错。 也许这是因为使用组合框项目进行比较

ComboBox.getValue().equals("something") 

虽然无法使用Platform.runLater进行更新,

但我仍然没有得到它。