Closed runiter closed 1 year ago
Hi @runiter, that's by design.
If you check out the JMetro documentation you'll see that unfortunately due to limitations in Javafx user agent stylesheets, JMetro will trump any rules set in code.
Set those rules in a stylesheet, that way JMetro rules will be overridden.
Thanks!
Hi @dukke The problem is that I don't know ahead of time what the color of various css items will be. The user will select the color from UI. So I cannot use stylesheet for these settings. Do you have any other suggestions for changing css color at runtime?
Use setStyle(...) method of Node, that will trump any rules set in stylesheets.
I do already use setStyle() as a workaround but the problem is that as soon as the chart is resized the color is reverted back to default. The reason for that is that resizing causes the LineChart to recreate its labels so they lose the style. I compensate for it by resetting the style as soon as I detect a resize but that causes flickering as label colors keeps switching back and forth between default color and style color. It only stops when I stop resizing. It's not a pleasant UI experience. Is there any other workaround?
That's weird, it seems like a javafx bug. If you set an inline style, via setStyle, that should trump any rules either set through code or in a stylesheet. Also, that inline style should be respected even when the layout is updated via a window resize or whatever... Unless there's something that resets that style in your code?
Another option I can think of would be to have various styleclasses in your Scene stylsheet, each setting a different color that the user can choose from. Then you add/remove a styleclass depending on which color the user chose. Wouldn't be ideal as you would have to have a styleclass per color and the user wouldn't be able to select an arbitrary color.
I don't think it's a bug because javafx charts were not designed to have their tickLabels modified directly. That's because when chart is resized, there may not be enough room for display the initial tickLabels so they have to be recalculated and recreated.
Even without jmetro I get flickering effect. Here's the code in case you like to try it:
public class Test extends Application {
public void start(Stage stage) {
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
LineChart<Number,Number> chart = new LineChart<>(xAxis, yAxis);
Scene scene = new Scene(chart,500,200);
stage.setScene(scene);
stage.show();
// xAxis.lookup(".axis").setStyle("-fx-tick-label-fill: red");
scene.widthProperty().addListener((s, o, v) -> {
Set<Node> nodes = xAxis.lookupAll(".axis Text");
System.out.println(nodes.iterator().next().hashCode()); // print hashcode of first axis number
nodes.forEach(n -> n.setStyle("-fx-fill: red;"));
});
}
public static void main(String[] args) {
launch(args);
}
}
Your solution may work but as you said it's not ideal. I found another workaround that is also not ideal but a little better. I need to create a subclass of javafx LineChart and override the methods so that I apply the style immediately after axis labels are created.
It works for me fine, but these issues could discourage other people from using jmetro. I'm going to file a ticket with JDK to ask them to provide the necessary API for user-agent solution. Hope they will listen.
In moderna I can change tick label color of charts via
xAxis.lookup(".axis").setStyle("-fx-tick-label-fill: red");
but this method has no effect in jmetro.In moderna I get this (correct):
In jmetro the axis labels appear as black (incorrect):
Here's the code: