将 CSS 应用于 FXML 中的堆叠图表
Applying CSS to stack charts in FXML
我正在尝试在 FXML 中实现一组类似于 的堆叠图表。我相当缺乏经验,无法找到在 FXML Controller 中设置 CSS 的完整示例。尝试自己调整代码导致了 java.lang.NullPointerException
异常和/或 `loadStylesheetUnPrivileged' 消息,并且代码没有 运行,或者 运行s 没有任何更改CSS。 SceneBuilder 能够显示透明预览,但在 运行 运行程序时不起作用。
FXML:
<AnchorPane fx:id="graphpane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Graph1Controller">
<children>
<StackPane fx:id="stackpane" prefHeight="150.0" prefWidth="200.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
<children>
<LineChart fx:id="M1chart" legendVisible="false" prefHeight="388.0" prefWidth="573.0" style=".chart-plot-background{-fx-background-color: transparent;} .default-color0.chart-series-line{-fx-stroke: #006564;}" stylesheets="@..css/M1chart.css" title="Recent Lap Times">
<xAxis>
<NumberAxis fx:id="M1xAxis" forceZeroInRange="false" minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
</xAxis>
<yAxis>
<NumberAxis fx:id="M1yAxis" autoRanging="false" label="Laptime (s)" side="LEFT" upperBound="240.0" />
</yAxis>
</LineChart>
<LineChart fx:id="M2chart" legendVisible="false" prefHeight="388.0" prefWidth="573.0" style=".chart-plot-background{-fx-background-color: transparent;} .default-color0.chart-series-line{-fx-stroke: #FFCE44;}" stylesheets="@..css/M2chart.css" title="Recent Lap Times">
<xAxis>
<NumberAxis fx:id="M2xAxis" forceZeroInRange="false" minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
</xAxis>
<yAxis>
<NumberAxis fx:id="M2yAxis" autoRanging="false" label="Laptime (s)" side="LEFT" upperBound="240.0" />
</yAxis>
</LineChart>
<LineChart fx:id="L1chart" legendVisible="false" prefHeight="388.0" prefWidth="573.0" style=".chart-plot-background{-fx-background-color: transparent;} .default-color0.chart-series-line{-fx-stroke: #832C40;}" stylesheets="@..css/L1chart.css" title="Recent Lap Times">
<xAxis>
<NumberAxis fx:id="L1xAxis" forceZeroInRange="false" minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
</xAxis>
<yAxis>
<NumberAxis fx:id="L1yAxis" autoRanging="false" label="Laptime (s)" side="LEFT" upperBound="240.0" />
</yAxis>
</LineChart>
</children>
</StackPane>
</children>
</AnchorPane>
我要加载3张CSS张,每一张都在同一个文件夹(css),文件夹和Java源放在同一个目录下文件,每个文件的结构类似于:
CSS:
.chart-plot-background{
-fx-background-color: transparent;
}
.default-color0.chart-series-line{
-fx-stroke: #832C40;
}
在主要class中,我尝试遵循Roland's answer in this thread,但它似乎不起作用。
主要:
public void start(Stage primaryStage) throws IOException {
//First FXML Controller code omitted
//Second FXML Controller code starts here
Stage stage2 = new Stage();
FXMLLoader loader2 = new FXMLLoader();
String fxmlDocPath2 = "(filepath)\Graph1.fxml"; //actual filepath replaced with placeholder for this post
FileInputStream fxmlStream2 = new FileInputStream(fxmlDocPath2);
AnchorPane root2 = (AnchorPane) loader2.load(fxmlStream2);
Scene scene2 = new Scene(root2);
scene2.getStylesheets().add(getClass().getResource("css/M1chart.css").toExternalForm());
scene2.getStylesheets().add(getClass().getResource("css/M2chart.css").toExternalForm());
scene2.getStylesheets().add(getClass().getResource("css/L1chart.css").toExternalForm());
stage2.setScene(scene2);
stage2.setTitle("TEST");
stage2.setX(primaryStage.getX() + 550);
stage2.setY(primaryStage.getY());
stage2.show();
//Second FXML Controller code ends
}
运行 这段代码给出了以下错误:
null/..css/M1chart.css
null/..css/M2chart.css
null/..css/L1chart.css
Oct 10, 2018 10:45:22 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "..css/M1chart.css" not found.
Oct 10, 2018 10:45:22 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "..css/M2chart.css" not found.
Oct 10, 2018 10:45:22 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "..css/L1chart.css" not found.
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at application.Core.start(Core.java:71)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(Unknown Source)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(Unknown Source)
... 1 more
Exception running application application.Core
我不确定我错过了什么导致 css 路径中出现 null 并且代码失败,有人可以帮忙吗?
There are 3 CSS sheets I want to load, each of which is in the same folder (css), the folder placed in the same directory as the Java source files
您应该将 css/fxml 文件移动到单独的资源文件夹中 - 如果某些构建工具与源文件位于同一文件夹中,则它们甚至不会将您的资源复制到输出目录。
假设您的项目结构是这样的:
YourApplicationRoot
|--res //resource root
| |-fxml
| | |-Main.fxml
| |-css
| |-styles.css
|--src //source root
|-application
|-Core.java //main class is here
首先,不要在 FXML 中使用内联样式 (style="some rules here"
) - 它很难维护。
接下来,你真的不需要 3 个单独的 CSS 文件,你可以将所有 css 样式放入一个文件 (styles.css
) 并使用自定义样式 类 将它们分开:
/* These styles will only be applied to a chart with class `m1chart` */
.m1chart .chart-plot-background{
-fx-background-color: transparent;
}
.m1chart .default-color0.chart-series-line{
-fx-stroke: red;
}
/* These styles will only be applied to a chart with class `m2chart` */
.m2chart .chart-plot-background{
-fx-background-color: transparent;
}
.m2chart .default-color0.chart-series-line{
-fx-stroke: blue;
}
/* These styles will only be applied to a chart with class `l1chart` */
.l1chart .chart-plot-background{
-fx-background-color: transparent;
}
.l1chart .default-color0.chart-series-line{
-fx-stroke: green;
}
现在,您有两种方法可以将 css 应用于您的应用程序 - 来自 fxml
和来自代码:
要从 fxml
应用 styles.css
,只需将 stylesheets
属性添加到根节点并将 styleClass
属性添加到每个要设置样式的 LineChart
:
/* Main.fxml, irrelevant parts are omitted */
<AnchorPane stylesheets="@../css/styles.css">
...
<LineChart styleClass="m1chart">
...
</LineChart>
<LineChart styleClass="m2chart">
...
</LineChart>
<LineChart styleClass="l1chart">
...
</LineChart>
...
</AnchorPane>
不要忘记从 LineChart
个节点中删除 style
和 stylesheets
属性。
直接从代码应用 styles.css
(请注意,如果您使用此方法,您的 css 样式将不会在 SceneBuilder 中可见):
//in Core.java start() method
yourScene.getStylesheets().add(getClass().getResource("/css/styles.css").toExternalForm());
//in your fxml controller
M1chart.getStyleClass().add("m1chart");
M2chart.getStyleClass().add("m2chart");
L1chart.getStyleClass().add("l1chart");
我正在尝试在 FXML 中实现一组类似于 java.lang.NullPointerException
异常和/或 `loadStylesheetUnPrivileged' 消息,并且代码没有 运行,或者 运行s 没有任何更改CSS。 SceneBuilder 能够显示透明预览,但在 运行 运行程序时不起作用。
FXML:
<AnchorPane fx:id="graphpane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Graph1Controller">
<children>
<StackPane fx:id="stackpane" prefHeight="150.0" prefWidth="200.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
<children>
<LineChart fx:id="M1chart" legendVisible="false" prefHeight="388.0" prefWidth="573.0" style=".chart-plot-background{-fx-background-color: transparent;} .default-color0.chart-series-line{-fx-stroke: #006564;}" stylesheets="@..css/M1chart.css" title="Recent Lap Times">
<xAxis>
<NumberAxis fx:id="M1xAxis" forceZeroInRange="false" minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
</xAxis>
<yAxis>
<NumberAxis fx:id="M1yAxis" autoRanging="false" label="Laptime (s)" side="LEFT" upperBound="240.0" />
</yAxis>
</LineChart>
<LineChart fx:id="M2chart" legendVisible="false" prefHeight="388.0" prefWidth="573.0" style=".chart-plot-background{-fx-background-color: transparent;} .default-color0.chart-series-line{-fx-stroke: #FFCE44;}" stylesheets="@..css/M2chart.css" title="Recent Lap Times">
<xAxis>
<NumberAxis fx:id="M2xAxis" forceZeroInRange="false" minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
</xAxis>
<yAxis>
<NumberAxis fx:id="M2yAxis" autoRanging="false" label="Laptime (s)" side="LEFT" upperBound="240.0" />
</yAxis>
</LineChart>
<LineChart fx:id="L1chart" legendVisible="false" prefHeight="388.0" prefWidth="573.0" style=".chart-plot-background{-fx-background-color: transparent;} .default-color0.chart-series-line{-fx-stroke: #832C40;}" stylesheets="@..css/L1chart.css" title="Recent Lap Times">
<xAxis>
<NumberAxis fx:id="L1xAxis" forceZeroInRange="false" minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
</xAxis>
<yAxis>
<NumberAxis fx:id="L1yAxis" autoRanging="false" label="Laptime (s)" side="LEFT" upperBound="240.0" />
</yAxis>
</LineChart>
</children>
</StackPane>
</children>
</AnchorPane>
我要加载3张CSS张,每一张都在同一个文件夹(css),文件夹和Java源放在同一个目录下文件,每个文件的结构类似于:
CSS:
.chart-plot-background{
-fx-background-color: transparent;
}
.default-color0.chart-series-line{
-fx-stroke: #832C40;
}
在主要class中,我尝试遵循Roland's answer in this thread,但它似乎不起作用。
主要:
public void start(Stage primaryStage) throws IOException {
//First FXML Controller code omitted
//Second FXML Controller code starts here
Stage stage2 = new Stage();
FXMLLoader loader2 = new FXMLLoader();
String fxmlDocPath2 = "(filepath)\Graph1.fxml"; //actual filepath replaced with placeholder for this post
FileInputStream fxmlStream2 = new FileInputStream(fxmlDocPath2);
AnchorPane root2 = (AnchorPane) loader2.load(fxmlStream2);
Scene scene2 = new Scene(root2);
scene2.getStylesheets().add(getClass().getResource("css/M1chart.css").toExternalForm());
scene2.getStylesheets().add(getClass().getResource("css/M2chart.css").toExternalForm());
scene2.getStylesheets().add(getClass().getResource("css/L1chart.css").toExternalForm());
stage2.setScene(scene2);
stage2.setTitle("TEST");
stage2.setX(primaryStage.getX() + 550);
stage2.setY(primaryStage.getY());
stage2.show();
//Second FXML Controller code ends
}
运行 这段代码给出了以下错误:
null/..css/M1chart.css
null/..css/M2chart.css
null/..css/L1chart.css
Oct 10, 2018 10:45:22 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "..css/M1chart.css" not found.
Oct 10, 2018 10:45:22 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "..css/M2chart.css" not found.
Oct 10, 2018 10:45:22 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "..css/L1chart.css" not found.
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at application.Core.start(Core.java:71)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(Unknown Source)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(Unknown Source)
... 1 more
Exception running application application.Core
我不确定我错过了什么导致 css 路径中出现 null 并且代码失败,有人可以帮忙吗?
There are 3 CSS sheets I want to load, each of which is in the same folder (css), the folder placed in the same directory as the Java source files
您应该将 css/fxml 文件移动到单独的资源文件夹中 - 如果某些构建工具与源文件位于同一文件夹中,则它们甚至不会将您的资源复制到输出目录。
假设您的项目结构是这样的:
YourApplicationRoot
|--res //resource root
| |-fxml
| | |-Main.fxml
| |-css
| |-styles.css
|--src //source root
|-application
|-Core.java //main class is here
首先,不要在 FXML 中使用内联样式 (style="some rules here"
) - 它很难维护。
接下来,你真的不需要 3 个单独的 CSS 文件,你可以将所有 css 样式放入一个文件 (styles.css
) 并使用自定义样式 类 将它们分开:
/* These styles will only be applied to a chart with class `m1chart` */
.m1chart .chart-plot-background{
-fx-background-color: transparent;
}
.m1chart .default-color0.chart-series-line{
-fx-stroke: red;
}
/* These styles will only be applied to a chart with class `m2chart` */
.m2chart .chart-plot-background{
-fx-background-color: transparent;
}
.m2chart .default-color0.chart-series-line{
-fx-stroke: blue;
}
/* These styles will only be applied to a chart with class `l1chart` */
.l1chart .chart-plot-background{
-fx-background-color: transparent;
}
.l1chart .default-color0.chart-series-line{
-fx-stroke: green;
}
现在,您有两种方法可以将 css 应用于您的应用程序 - 来自 fxml
和来自代码:
要从 fxml
应用 styles.css
,只需将 stylesheets
属性添加到根节点并将 styleClass
属性添加到每个要设置样式的 LineChart
:
/* Main.fxml, irrelevant parts are omitted */
<AnchorPane stylesheets="@../css/styles.css">
...
<LineChart styleClass="m1chart">
...
</LineChart>
<LineChart styleClass="m2chart">
...
</LineChart>
<LineChart styleClass="l1chart">
...
</LineChart>
...
</AnchorPane>
不要忘记从 LineChart
个节点中删除 style
和 stylesheets
属性。
直接从代码应用 styles.css
(请注意,如果您使用此方法,您的 css 样式将不会在 SceneBuilder 中可见):
//in Core.java start() method
yourScene.getStylesheets().add(getClass().getResource("/css/styles.css").toExternalForm());
//in your fxml controller
M1chart.getStyleClass().add("m1chart");
M2chart.getStyleClass().add("m2chart");
L1chart.getStyleClass().add("l1chart");