在我的分形图像生成程序中,我允许用户通过显示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)
答案 0 :(得分:0)
根据我的猜测 - 我没有从堆栈和你的代码中看到太多,除了它试图:
_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();
}
});
答案 1 :(得分:0)
我发现在Java 9(build 9.0.1 + 11)下不再抛出此异常。代码按预期工作。
所以我猜这是某种Java / JavaFX错误。