Ich schreibe ein einfaches Programm, das aus einem Fenster mit 8 Tasten mit verschiedenen Farben besteht, die zu einer VBox
hinzugefügt wurden und dann zur Szene der Programmbühne hinzugefügt werden.NullPointerException bei Verwendung eines hexadezimalen Werts als Parameter einer Methode
für eine Schaltfläche die Farbe zu ändern, ich habe die setRippleColor()
Methode aufzurufen, deren Definition ist die folgende:
public void setRippleColor(Color color) {
((Shape) ((SkinBase) getSkin()).getChildren().get(0)).setFill(color);
}
Das Problem ist, dass, wenn ich diese Methode aufrufen, ein Color
Objekt als Parameter verwendet wird, erhalte ich a NullPointerException
.
Zum Beispiel, wenn ich diesen Code verwenden:
buttonGreen.setRippleColor((Color.web("0x259B24")));
buttonOrange.setRippleColor(Color.web("0xe67e22"));
buttonBlue.setRippleColor(Color.web("0x3498db"));
buttonPurple.setRippleColor(Color.web("0x9b59b6"));
buttonYellow.setRippleColor(Color.web("0xf1c40f"));
buttonRed.setRippleColor(Color.web("0xe74c3c"));
buttonBrown.setRippleColor(Color.web("0x663300"));
buttonGrey.setRippleColor(Color.web("0x222222"));
VBox verticalLayout = new VBox(8);
verticalLayout.getChildren().addAll(buttonGreen,
buttonOrange,
buttonBlue,
buttonPurple,
buttonYellow,
buttonRed,
buttonBrown,
buttonGrey);
die Konsole dies sagen wird:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at CustomButton.setRippleColor(CustomButton.java:166)
at StartingPoint.start(StartingPoint.java:25)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
Als die 166. und 25. Codezeilen der Definition des Verfahrens und die erster Aufruf davon jeweils.
Wenn ich jedoch einen Hexadezimalwert als Farbe verwende, verwende ich eine der Standardfarben der Klasse (Color.GREEN
, zum Beispiel), alles läuft perfekt.
Es ist wichtig zu erwähnen, dass ich nicht die java.awt.Color
Klasse statt javafx.scene.paint.Color
verwende; Die Bibliothek ist nicht das Problem.
UPDATE: Ich habe einige rudimentary Protokollierung, um zu wissen, was null
ist.
Statt Color.web("...")
als Parameter für setRippleColor()
verwenden, habe ich ein paar Color
Objekte, deren Definition ist das, was ich am Anfang waren die setRippleColor()
‚s-Parameter, und ich umringten die Anrufe an die setRippleMethod()
mit folgenden try{} catch{}
:
Color green = Color.web("0x259B24");
try {
buttonGreen.setRippleColor(green);
} catch (NullPointerException exception) {
SkinBase skin = (SkinBase) buttonGreen.getSkin();
ObservableList<Node> children = skin.getChildren();
Shape shape = (Shape) skin.getChildren().get(0);
System.out.println("Color " + green);
System.out.println("Skin: " + skin);
System.out.println("Children: " + children);
System.out.println("Shape: " + shape);
}
Und das ist, was die Konsole ausgibt:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at StartingPoint.start(StartingPoint.java:31)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
so weit wie ich es verstehe, bedeutet dies, dass die Schaltfläche s Kin's Kinder geben null
zurück, aber ich verstehe nicht, warum dies nicht geschieht, wenn ich Color.GREEN
anstelle des Objekts verwende, das im obigen Code gefunden wird.
UPDATE 2: Es stellt sich heraus, dass, wenn ich Color.GREEN
als Parameter für setRippleColor()
verwenden das Ergebnis das gleiche ist, dass wenn ich Color.web("#colorstring")
verwenden, was offensichtlich ist und es keine Erklärung wäre, wenn das nicht war der Fall. Ich weiß nicht warum, aber ich habe die Erinnerung, Color.GREEN
zu verwenden und das Programm ohne Fehler laufen zu lassen.
Die gute Sache ist, dass ich mich jetzt daran erinnern werde, dass jedes Mal, wenn etwas keinen Sinn ergibt, ich den Code erneut ausführen muss und sicherstellen, dass es für mich keinen Sinn ergibt, weil ich nicht genug habe Wissen über das Thema, und nicht weil es nie passiert ist.
Also, das Problem lag daran, dass die Haut der Schaltfläche nicht initialisiert wurde, bevor die setRippleColor()
-Methode aufgerufen wird.
Dies ist, wie ich es gelöst:
hattry{
((Shape) ((SkinBase) getSkin()).getChildren().get(0)).setFill(color);
} catch (NullPointerException exception){
createDefaultSkin();
setRippleColor(color);
}
Wenn die Haut nicht initialisiert wurde, wenn die Methode aufgerufen wird, wird es initialisiert und dann wieder die setRippleColor()
nennt sich.
Loggen Sie sich ein, um zu sehen, was null ist. Es ist entweder die Haut, die Kinderliste der Haut (unwahrscheinlich) oder das erste Kind der Haut (ziemlich unwahrscheinlich). Vielleicht nennst du das irgendwie bevor die Haut initialisiert wird? –
Selbst wenn Sie es schaffen, es zu arbeiten, ist dies ein ziemlich zerbrechliches Design. Die Skin-Implementierungen für Dinge wie Buttons in JavaFX 8 sind nicht Teil der öffentlichen API und könnten (und werden wahrscheinlich) für spätere Java-Versionen in einer binär inkompatiblen Weise geändert werden. Ich denke, du solltest überdenken, was du zu tun versuchst und mit welchen Mitteln du es erreichen willst. Ich weiß nicht genau, was Sie zu tun versuchen, aber normalerweise können Sie CSS verwenden, um Farben auf Schaltflächen zu setzen (zB 'button.setStyle (" - fx-base: palegreen; ");') – jewelsea
Ich denke, in Licht von deinem Kommentar, dass "Color.GREEN" funktioniert, überprüfe auch, dass 'Color.web (...)' nicht null zurückgibt, obwohl ich es kaum glauben kann. –