【问题标题】:Hiding javaFX ColorPicker causes NullPointerException隐藏 javaFX ColorPicker 导致 NullPointerException
【发布时间】:2017-03-30 01:19:02
【问题描述】:

在我的分形图像生成程序中,我允许用户通过显示 javafx.scene.control.ColorPicker 来编辑屏幕图像的颜色,如下面的代码所示。

在顶部,我设置了一个事件处理程序,允许用户隐藏 ColorPicker 和包装它的 GridPane。从某种意义上说,这是可行的,因为预期的行为会发生,但同时 JVM 会抛出 NullPointerException。堆栈跟踪主要是指 javafx 类,而不是我正在执行的类。

我已经玩过代码并搜索了 stackoverflow 及其他内容,但这个让我很难过。

谁能帮我诊断一下原因吗? (代码和堆栈跟踪如下。)

scene.setOnKeyPressed(ev2 -> {
    if (ev2.getCode().equals(KeyCode.ENTER)) {
        System.out.println("\nEnter pressed, panel should hide...");
        huePanel.setVisible(false);     // press Enter to kill panel
        huePanel.getChildren().clear();
        root.getChildren().removeAll(huePanel);
    }
});     

huePanel = new GridPane();
huePanel.setAlignment(Pos.TOP_CENTER);
root.getChildren().addAll(huePanel);
int cl = colours[colourscheme].length;
Rectangle[] squares = new Rectangle[cl];
ColorPicker[] pickers = new ColorPicker[cl];

for (int i = 0; i < cl; i++) {
    int squareSize = width / 20;
    squares[i] = new Rectangle(squareSize, squareSize, colours[colourscheme][i]);
    squares[i].setStroke(BLACK);
    squares[i].setStrokeWidth(2.0);
    GridPane.setRowIndex(squares[i], (i / 8) * 2);
    GridPane.setColumnIndex(squares[i], i % 8);

    pickers[i] = new ColorPicker(colours[colourscheme][i]);
    GridPane.setRowIndex(pickers[i], (i / 8) * 2 + 1);
    GridPane.setColumnIndex(pickers[i], i % 8);

    huePanel.getChildren().addAll(squares[i], pickers[i]);
}
for (int j = 0; j < cl; j++) {
    indexOfColourToModify = j;
    pickers[j].setOnAction(ev1 -> {
            ColorPicker cp = (ColorPicker)(ev1.getSource());
            int k = huePanel.getChildren().indexOf(cp) / 2;     // really (idx-1)/2, as idx is odd
                                                                // due to squares[]
            Color c = cp.getValue();
            colours[colourscheme][k] = c;
            huePanel.requestLayout();
            System.out.println("\ncolours[" + colourscheme + "][" + k + "] set to " + c);
            paintImage(screenImage[screenImageIndex], realMinIts, realMaxIts);
        }
    );
}

================================================ ============================

Enter pressed, panel should hide...
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at com.sun.javafx.scene.control.skin.ComboBoxPopupControl.positionAndShowPopup(ComboBoxPopupControl.java:197)
    at com.sun.javafx.scene.control.skin.ComboBoxPopupControl.show(ComboBoxPopupControl.java:170)
    at com.sun.javafx.scene.control.skin.ColorPickerSkin.show(ColorPickerSkin.java:464)
    at com.sun.javafx.scene.control.skin.ComboBoxBaseSkin.handleControlPropertyChanged(ComboBoxBaseSkin.java:127)
    at com.sun.javafx.scene.control.skin.ColorPickerSkin.handleControlPropertyChanged(ColorPickerSkin.java:470)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
    at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
    at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ReadOnlyBooleanPropertyBase.fireValueChangedEvent(ReadOnlyBooleanPropertyBase.java:72)
    at javafx.beans.property.ReadOnlyBooleanWrapper.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:103)
    at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
    at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
    at javafx.scene.control.ComboBoxBase.setShowing(ComboBoxBase.java:185)
    at javafx.scene.control.ComboBoxBase.show(ComboBoxBase.java:391)
    at com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior.show(ComboBoxBaseBehavior.java:286)
    at com.sun.javafx.scene.control.behavior.ColorPickerBehavior.callAction(ColorPickerBehavior.java:82)
    at com.sun.javafx.scene.control.behavior.BehaviorBase.callActionForEvent(BehaviorBase.java:218)
    at com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior.callActionForEvent(ComboBoxBaseBehavior.java:136)
    at com.sun.javafx.scene.control.behavior.BehaviorBase.lambda$new$74(BehaviorBase.java:135)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$KeyHandler.process(Scene.java:3964)
    at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
    at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
    at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$353(GlassViewEventHandler.java:248)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
    at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
    at com.sun.glass.ui.View.notifyKey(View.java:966)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • 我有一个非常相似的异常,但是当尝试在 TableCell 中使用 CheckComboBox 时。 More details.

标签: java javafx lambda javafx-8


【解决方案1】:

据我所知 - 除了它试图做的事情之外,我从堆栈和您的代码中看不到太多东西:

_popup.show(comboBoxBase.getScene().getWindow(),
                snapPosition(p.getX()),
                snapPosition(p.getY())); 

这可能是由于传播事件。

如果您的 ColorPicker 有焦点,Enter 会对其进行操作,但此时,它已从场景中移除。

试试:

scene.setOnKeyPressed(ev2 -> {
    if (ev2.getCode().equals(KeyCode.ENTER)) {
        System.out.println("\nEnter pressed, panel should hide...");
        huePanel.setVisible(false);     // press Enter to kill panel
        huePanel.getChildren().clear();
        root.getChildren().removeAll(huePanel);
        ev2.consume();
    }
}); 

【讨论】:

    【解决方案2】:

    我发现在 Java 9 (build 9.0.1+11) 下不再抛出这个异常。代码按预期工作。

    所以我猜这是某种 Java/JavaFX 错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      • 1970-01-01
      • 2016-03-07
      相关资源
      最近更新 更多