A JavaFX library for Gauges. The main focus of this project is to provide Gauges that can be configured in multiple ways.
Donations are welcome at Paypal
A JavaFX library for Gauges
License: Apache License 2.0
Donations are welcome at Paypal
I am trying to make a clock and a gauge using both the LCD skin the same height. I am putting them both in the "top" of a BorderPane. Inside this "top", I have another BorderPane where I place the actual components "left" and "right". This is the result:
On both, I have called:
.maxSize(200, 85)
.prefHeight(85)
You can see that the gauge on the left has some padding on top, which is not present on the clock on the right. The clock also has some right padding.
You can also see that they are different height.
It would be great if you could suggest how to make their heights the same.
On a related note: how do I change the temperature gauge to only use up to 3 numbers before the decimal separator (In my case, temparture will not go above 999 degrees C)?
I've run into an issue where when I specify the max value of the gauge what is displayed doesn't match what I specified. In the following case it doesn't match (I set 3600 but it displays 4000):
Gauge gauge = GaugeBuilder.create()
.skinType(Gauge.SkinType.DASHBOARD)
.minValue(0)
.maxValue(3600)
.animated(true)
.valueVisible(false)
.build();
I'm using Medusa 7.3 and java 1.8u60
Something similar to #28 is happening when you resize LinearSkin
with Orientation.VERTICAL
- gauge is drawing bar outside its boundaries.
Can be reproduced with code I sent you yesterday just set value and resize window.
Setting knob color at ru-time doesn't work.
package se.ess.medusa.tests.clock;
import eu.hansolo.medusa.Clock;
import eu.hansolo.medusa.ClockBuilder;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import static javafx.application.Application.launch;
public class MainApp extends Application {
private static final Logger LOGGER = Logger.getLogger(MainApp.class.getName());
public static void main( String[] args ) {
launch(args);
}
private Clock clock;
private long lastTimerCall;
private AnimationTimer timer;
@Override
public void init() throws Exception {
clock = ClockBuilder.create()
.skinType(Clock.ClockSkinType.CLOCK)
.backgroundPaint(Color.web("#1f1e23"))
.borderPaint(Color.web("#03af07"))
.borderWidth(4.7)
.dateColor(Color.RED)
.dateVisible(true)
.discreteHours(false)
.discreteMinutes(false)
.discreteSeconds(false)
.hourColor(Color.CORAL)
.hourTickMarkColor(Color.AQUA)
.hourTickMarksVisible(true)
.knobColor(Color.MAGENTA)
.running(true)
.build();
lastTimerCall = System.nanoTime();
timer = new AnimationTimer() {
@Override
public void handle( long now ) {
if ( now > lastTimerCall + 5_000_000_000L ) {
clock.setKnobColor(Color.GREEN);
lastTimerCall = now;
}
}
};
}
@Override
public void start( Stage stage ) throws Exception {
StackPane pane = new StackPane(clock);
pane.setPadding(new Insets(20));
pane.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
Scene scene = new Scene(pane);
stage.setTitle("Medusa Clock Test");
stage.setScene(scene);
stage.show();
timer.start();
}
}
If major and minor ticks are invisible then the tickMarkType in line 706 can be null.
One you start running a Clock, the java vm will not exit. I believe either the task thread or executor is not getting cleaned up properly.
There is still an import in LcdDesign for FlatUiColor.
Missing bintray upload of fix to #38, and version number change
Just cosmetics, was able to built it myself, works like a charm.
Hello,
I cannot find it on maven central. Have you deployed there?
Regards,
Claudio
Sorry for creating another issue, maybe it's my mistake
Following code is not rendering title:
gauge3 = GaugeBuilder.create() .barBorderColor(Color.WHITE) .needleBorderColor(Color.WHITE) .borderWidth(2) .borderPaint(Color.WHITE) .barColor(Color.AZURE) .titleColor(Color.WHITE) .subTitleColor(Color.WHITE) .unitColor(Color.WHITE) .majorTickMarkColor(Color.WHITE) .tickLabelColor(Color.WHITE) .valueColor(Color.WHITE) .build();
gauge3.setSkin(new BulletChartSkin(gauge3));
gauge3.setTitle("TITLE");
gauge3.setTitleColor(Color.WHITE);
gauge3.setValue(10);
Gauge gauge = new Gauge();
gauge.setOrientation(Orientation.HORIZONTAL);
gauge.setPrefHeight(600);
gauge.setValueVisible(false);
gauge.setValue(40);
//valueText shows 40
gauge.setDecimals(0);
//setting number of decimal works, valueText changes
gauge.setSkin(new LinearSkin(gauge));
But gauge value text still persists
Using latest Medusa 5.1 & java 8
If you run this program:
import eu.hansolo.medusa.Clock;
import eu.hansolo.medusa.ClockBuilder;
import eu.hansolo.medusa.LcdDesign;
import eu.hansolo.medusa.LcdFont;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class LcdClockSkinTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
HBox topPanel = new HBox();
topPanel.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
topPanel.setMaxHeight(50);
topPanel.setAlignment(Pos.CENTER_RIGHT);
Clock clock = createClock();
topPanel.getChildren().add(clock);
root.setTop(topPanel);
Scene scene = new Scene(root);
scene.widthProperty().addListener((observableValue, oldValue, newValue) -> {
System.out.println( "scene: " + newValue );
System.out.println( "clock: " + clock.getWidth());
});
primaryStage.setScene(scene);
primaryStage.setWidth(800);
primaryStage.setHeight(600);
primaryStage.show();
}
private Clock createClock() {
Clock clock = ClockBuilder.create()
.skinType(Clock.ClockSkinType.LCD)
.lcdDesign(LcdDesign.BLUE)
.lcdFont(LcdFont.DIGITAL)
.lcdCrystalEnabled(true)
.dateVisible(false)
.secondsVisible(true)
.build();
clock.setRunning(true);
clock.setBackground(new Background(new BackgroundFill(Color.YELLOW, null, null)));
clock.setOnMouseClicked(event -> Platform.exit());
return clock;
}
}
It will give the following result:
Notice how the yellow rectangle is the background of the clock. I would like to be able to have the clock to the far right in the top bar, but the clock node itself takes more width then it is actually using when drawing.
This is tested with version 6.8 and the current master (dd627ef)
If the angleRange property of a Gauge is changed when the Gauge is shown, the Gauge goes into an infinite loop between Gauge.calcAutoScale, Gauge.setMajorTickSpace, Gauge.fireUpdateEvent and GaugeSkin.registerListeners. So having created a Gauge gauge and a button angleRangeButton with angleRangeButton.setOnAction(e -> gauge.angleRangeProperty().set(90));, the button will cause the program to go into an infinite loop and crash with a stack overflow.
I've not been able to identify a workaround.
The newly introduced SkinType enum is not supported by the builder. Intentionally?
This issue can be reproduced by using the code I sent you yesterday.
Just set the CustomPanel
as center to scene and then maximize window - gauges won't redraw.
Then minimize the window - gauges will be drawn with the scale as they're in the maximized window.
Note: This seems only to be affecting LinearSkin (maybe BulletChartSkin too), other gauges will redraw.
Note: Using medusa-5.3
PS> sorry for another issue
LinearSkin
shows max value 160 instead of 150.
I assume the library is calculating this number for proper drawing of the scale.
How can this be avoided?
In build.gradde add 'Bundle-SymbolicName' : 'eu.hansolo.medusa'
to jar manifest attributes, thus avoiding it being set by default to 'Medusa'
.
Regards,
Claudio
A gauge with dashboardskin and min value not zero, does not set properly databar gradient because it consideres starts at zero.
The issue can be reproduced easily setting a minValue different to zero in OverviewDemo class.
Just food for thought: overriding state properties of controls hardly makes sense, which is the reason why most JavaFX controls use "final" to prevent overriding methods.
gradlew build
Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
I have not used grade before and I have installed the latest gradle, 2.12
For small ranges the tick labels are drawn incorrect:
The following code
GaugeBuilder.create()
.skinType(SkinType.GAUGE)
.maxSize(200, 200)
.minSize(200, 200)
.title("dP")
.unit("hPa")
.minValue(-2.2)
.maxValue(+2.2)
.build();
The tick labels are [0, 1, 1, 2, 2, 3] instead of [0, 0.5, 1, 1.5, 2, 2.5]. Probably it is even better to label only integer numbers like [0, 1, 2].
Thanks!
Remove line medusa/skins/LinearSkin.java#L218
Is there a way to get bar bounds when using LinearSkin
for custom event listener?
Calling setAreas or setSections on a gauge results in:
Exception in thread "JavaFX Application Thread" java.lang.StackOverflowError
at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:890)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:2313)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:1881)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:2100)
at eu.hansolo.medusa.skins.QuarterSkin.handleEvents(QuarterSkin.java:354)
at eu.hansolo.medusa.skins.QuarterSkin.lambda$registerListeners$91(QuarterSkin.java:294)
at eu.hansolo.medusa.Gauge.lambda$fireUpdateEvent$1(Gauge.java:2313)
at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:890)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:2313)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:1881)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:2100)
at eu.hansolo.medusa.skins.QuarterSkin.handleEvents(QuarterSkin.java:354)
at eu.hansolo.medusa.skins.QuarterSkin.lambda$registerListeners$91(QuarterSkin.java:294)
at eu.hansolo.medusa.Gauge.lambda$fireUpdateEvent$1(Gauge.java:2313)
at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:890)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:2313)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:1881)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:2100)
at eu.hansolo.medusa.skins.QuarterSkin.handleEvents(QuarterSkin.java:354)
at eu.hansolo.medusa.skins.QuarterSkin.lambda$registerListeners$91(QuarterSkin.java:294)
at eu.hansolo.medusa.Gauge.lambda$fireUpdateEvent$1(Gauge.java:2313)
at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:890)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:2313)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:1881)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:2100)
I need to change the min/max values of my gauge according to the user's selection, but when I call "setMin[or max]Value" after the user has selected an option, I get a StackOverflow error.
The gauge is initialized in the FXML file.
Hi
I would like to know where does the LinearSkin decides that it should change max value to 160 and how does it come to this number.
To reproduce this issue just add in line 221 of file OverviewDemo.java the following expresssion:
gauge5.setValue(20);
And run the demo. It does not start
First thanks a lot for this great library! I have to create many similar gauges. So I created the following function with two section:
public static Gauge create(double max)
{
return GaugeBuilder.create()
.skinType(SkinType.GAUGE)
.maxSize(150, 150)
.minSize(150, 150)
.title("dP")
.unit("hPa")
.minValue(-1.1 * max)
.maxValue(+1.1 * max)
.sectionsVisible(true)
.sections(new Section(-1.1 * max, -max, Color.LIGHTCORAL),
new Section(+max, +1.1 * max, Color.LIGHTCORAL))
.build();
}
With
create(20d);
I get
To start the section at -25 and stop at +25 I tried to increase the section range (note the -25 and +25 range is computed by the Medusa library):
.sections(new Section(-2 * max, -max, Color.LIGHTCORAL),
new Section(+max, +2 * max, Color.LIGHTCORAL))
While this works for the section on the right side, the section on the left side does not draw correctly.
If I use a Gauge I can click on it and resize works very well.
The following code displays in console a message when the component is clicked. Moreover, resizing the window will always display the component centered.
package se.ess.medusa.tests.gauge;
import eu.hansolo.medusa.Gauge;
import eu.hansolo.medusa.GaugeBuilder;
import eu.hansolo.medusa.GaugeDesign;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import static javafx.application.Application.launch;
public class MainApp extends Application {
private static final Logger LOGGER = Logger.getLogger(MainApp.class.getName());
public static void main( String[] args ) {
launch(args);
}
private Gauge gauge;
@Override
public void init() throws Exception {
GaugeDesign design = GaugeDesign.NONE;
Gauge.SkinType skin = Gauge.SkinType.SIMPLE_SECTION;
gauge = GaugeBuilder.create()
.skinType(skin)
.title(skin.name() + " - " + design.name())
.build();
}
@Override
public void start( Stage stage ) throws Exception {
final Node node = gauge;
node.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> System.out.println("*** SELECTED"));
StackPane pane = new StackPane(node);
pane.setPadding(new Insets(20));
pane.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
Scene scene = new Scene(pane);
stage.setTitle("Medusa Clock Test");
stage.setScene(scene);
stage.show();
timer.start();
}
}
If, instead, I use an FGauge then
Here the code. As you can see:
package se.ess.medusa.tests.gauge;
import eu.hansolo.medusa.FGauge;
import eu.hansolo.medusa.FGaugeBuilder;
import eu.hansolo.medusa.Gauge;
import eu.hansolo.medusa.GaugeBuilder;
import eu.hansolo.medusa.GaugeDesign;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import static javafx.application.Application.launch;
public class MainApp extends Application {
private static final Logger LOGGER = Logger.getLogger(MainApp.class.getName());
public static void main( String[] args ) {
launch(args);
}
private Gauge gauge;
@Override
public void init() throws Exception {
GaugeDesign design = GaugeDesign.NONE;
Gauge.SkinType skin = Gauge.SkinType.SIMPLE_SECTION;
gauge = GaugeBuilder.create()
.skinType(skin)
.title(skin.name() + " - " + design.name())
.build();
fgauge = FGaugeBuilder.create()
.gauge(gauge)
.gaugeDesign(design)
.build();
}
@Override
public void start( Stage stage ) throws Exception {
final Node node = fgauge;
node.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> System.out.println("*** SELECTED"));
StackPane pane = new StackPane(node);
pane.setPadding(new Insets(20));
pane.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
Scene scene = new Scene(pane);
stage.setTitle("Medusa Clock Test");
stage.setScene(scene);
stage.show();
timer.start();
}
}
Would you mind uploading the new version (which supports section update events) on bintray? Thx
configurationGauge.getSections().forEach(section -> section.setOnSectionUpdate(sectionEvent ->{
System.out.println("Updating section");
configurationGauge.fireUpdateEvent(new UpdateEvent(ConfigGaugeWindow.this, UpdateEvent.EventType.REDRAW));
}));
Following code is printing to console, however it's not redrawing the Gauge (Am I doing something wrong?)
The gauge is in Gauge --> BorderPane --> GridPane --> GaugeConfigWindow
Setting min value to a value greater than 0 with DashboardSkin does not work properly. It fills the whole semicircle of the gauge.
To reproduce it just add to OverviewDemo.java, in line 206 the following:
.minValue(15)
And execute the demo
Changing the areasVisibleProperty after the gauge has been drawn does not appear to have any effect on the visibility of areas.
CheckBox areasVisibleBox = new CheckBox();
//...
areasVisibleBox.selectedProperty().bindBidirectional(gauge.areasVisibleProperty());
The checkbox correctly reflects the initial state of areasVisibleProperty (set by the builder), but changing it does not change the visibility of areas.
Repro:
I set the maxValue of a gauge (with setAutoScale(true) set) during runtime
Exception in thread "JavaFX Application Thread" java.lang.StackOverflowError
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4401)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:5086)
at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:357)
at eu.hansolo.medusa.skins.GaugeSkin.lambda$registerListeners$4(GaugeSkin.java:297)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5458)
Would be nice to have some kind of samples / test application to get users started quickly and to highlight the libs features.
I create a Clock showing seconds, then after 5 seconds I try to hide them, but it's not working.
Here the code:
package se.ess.medusa.tests.clock;
import eu.hansolo.medusa.Clock;
import eu.hansolo.medusa.ClockBuilder;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import static javafx.application.Application.launch;
public class MainApp extends Application {
private static final Logger LOGGER = Logger.getLogger(MainApp.class.getName());
public static void main( String[] args ) {
launch(args);
}
private Clock clock;
private long lastTimerCall;
private AnimationTimer timer;
@Override
public void init() throws Exception {
Clock.ClockSkinType skin = Clock.ClockSkinType.INDUSTRIAL;
clock = ClockBuilder.create()
.skinType(skin)
.secondsVisible(true)
.running(true)
.build();
lastTimerCall = System.nanoTime();
timer = new AnimationTimer() {
@Override
public void handle( long now ) {
if ( now > lastTimerCall + 5_000_000_000L ) {
System.out.println("*** HIDING SECONDS");
clock.setSecondsVisible(false);
lastTimerCall = now;
}
}
};
}
@Override
public void start( Stage stage ) throws Exception {
StackPane pane = new StackPane(clock);
pane.setPadding(new Insets(20));
pane.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
Scene scene = new Scene(pane);
stage.setTitle("Medusa Clock Test");
stage.setScene(scene);
stage.show();
timer.start();
}
}
LinearSkin gauge has no problem drawing the gauge outside its boundaries, when using Orientation.HORIZONTAL
on LinearSkin
.
My opinion is that the issue is caused by calculating height of canvas from width of the Gauge
Note: Orientation.VERTICAL
gauges working fine
Hey man! I am here again, first i want to say: Congratulations! you improve your own limits... This is a ENZO RELOADED. I have been using the old technique of Enzo to create some aditional gauges to my electrical system application too, i am going to create a blog about that someday...
Ok, now to the point. Have you ever seen a Power Factor Gauge? I am wondering how to do it, and basically the hardest part is the scale... Take a look:
http://www.celsagermany.com/typo3temp/processed/csm_DPQ96n-1_e97f3d8f13.png
There is a totally custom scale, but indeep (a transductor signal of 0Volt to 10Volt actually), it is an integer that can be in the range [0...2], so when the value is 1,5 the needle has to move to 0.5cap(capacitive) and when the value is 0.5 the needle has to go to 0.5ind.
So, my question is: How could someone do this behavior with the gauges that we use to design?
Aditional information:
https://www.youtube.com/watch?v=ob2rcI7_tzo
This video shows the hardware device working, but its easy in this case because you can change the meter label and it is isolated from the mechanism..
sayōnara!
I'm attempting to load the Medusa 5.9 jar file in SceneBuilder and am encountering the following error
when viewing the .jar analysis report.
Exception for: eu/hansolo/medusa/FGauge.class
java.io.IOException: java.lang.ExceptionInInitializerError
at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.instantiateWithFXMLLoader(JarExplorer.java:111)
at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.exploreEntry(JarExplorer.java:154)
at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.explore(JarExplorer.java:67)
at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.exploreAndUpdateLibrary(LibraryFolderWatcher.java:313)
at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.runDiscovery(LibraryFolderWatcher.java:142)
at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.run(LibraryFolderWatcher.java:94)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ExceptionInInitializerError
at eu.hansolo.medusa.Gauge.<init>(Gauge.java:113)
at eu.hansolo.medusa.Gauge.<init>(Gauge.java:379)
at eu.hansolo.medusa.FGauge.<init>(FGauge.java:61)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1009)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2425)
at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.instantiateWithFXMLLoader(JarExplorer.java:107)
... 6 more
Caused by: java.lang.IllegalArgumentException: EventType "BTN_PRESSED"with parent "EVENT" already exists
at javafx.event.EventType.register(EventType.java:186)
at javafx.event.EventType.<init>(EventType.java:128)
at eu.hansolo.medusa.Gauge$ButtonEvent.<clinit>(Gauge.java:5197)
... 21 more
Hello,
I run the following simple code and when, after 5 seconds, the skin is changed a NullPointer happens. What is wrong in my code?
package se.ess.medusa.tests.clock;
import eu.hansolo.medusa.Clock;
import eu.hansolo.medusa.ClockBuilder;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import static javafx.application.Application.launch;
public class MainApp extends Application {
private static final Logger LOGGER = Logger.getLogger(MainApp.class.getName());
public static void main( String[] args ) {
launch(args);
}
private Clock clock;
private long lastTimerCall;
private AnimationTimer timer;
@Override
public void init() throws Exception {
clock = ClockBuilder.create()
.skinType(Clock.ClockSkinType.PLAIN)
.backgroundPaint(Color.web("#1f1e23"))
.borderPaint(Color.web("#03af07"))
.borderWidth(8.5)
.running(true)
.build();
lastTimerCall = System.nanoTime();
timer = new AnimationTimer() {
@Override
public void handle( long now ) {
if ( now > lastTimerCall + 5_000_000_000L ) {
clock.setSkinType(Clock.ClockSkinType.SLIM);
lastTimerCall = now;
}
}
};
}
@Override
public void start( Stage stage ) throws Exception {
StackPane pane = new StackPane(clock);
pane.setPadding(new Insets(20));
pane.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
Scene scene = new Scene(pane);
stage.setTitle("Medusa Clock Test");
stage.setScene(scene);
stage.show();
timer.start();
}
}
Running a gauge with SpaceXSkin
works fine on Desktop but on Android and iOS the bars are wrong.
After some debugging, it turns out the threshold doesn't get the passed value (25000), but keeps the one it gets in the init() pass (100 due to maxValue).
When fireUpdateEvent(RECALC_EVENT)
in Gauge.setMaxValue()
is triggered after a first pass (initial value 100), on desktop the max value is set immediately (30000), before the call to setTheshold()
is made.
But on mobile, the call to setThreshold()
happens before this second call to set the maximum value, and that's why the threshold value gets clamped.
As a quick check, setting the threshold again before running the animation fixes the problem.
Exception in thread "JavaFX Application Thread" java.lang.StackOverflowError
at java.lang.StrictMath.floor(StrictMath.java:359)
at java.lang.Math.floor(Math.java:442)
at eu.hansolo.medusa.tools.Helper.calcNiceNumber(Helper.java:107)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4763)
at eu.hansolo.medusa.skins.LinearSkin.handleEvents(LinearSkin.java:244)
at eu.hansolo.medusa.skins.LinearSkin.lambda$registerListeners$2(LinearSkin.java:208)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5083)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4205)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4764)
at eu.hansolo.medusa.skins.LinearSkin.handleEvents(LinearSkin.java:244)
at eu.hansolo.medusa.skins.LinearSkin.lambda$registerListeners$2(LinearSkin.java:208)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5083)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4205)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4764)
at eu.hansolo.medusa.skins.LinearSkin.handleEvents(LinearSkin.java:244)
at eu.hansolo.medusa.skins.LinearSkin.lambda$registerListeners$2(LinearSkin.java:208)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5083)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4205)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4764)
at eu.hansolo.medusa.skins.LinearSkin.handleEvents(LinearSkin.java:244)
at eu.hansolo.medusa.skins.LinearSkin.lambda$registerListeners$2(LinearSkin.java:208)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5083)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4205)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4764)
at eu.hansolo.medusa.skins.LinearSkin.handleEvents(LinearSkin.java:244)
at eu.hansolo.medusa.skins.LinearSkin.lambda$registerListeners$2(LinearSkin.java:208)
at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5083)
at eu.hansolo.medusa.Gauge.setMajorTickSpace(Gauge.java:4205)
at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4764)
is created by following code:
setZeroButton.setOnMouseClicked(event -> {
double max_value = gauge.getMaxValue() - gauge.getCurrentValue();
double min_value = 0 - gauge.getCurrentValue();
gauge.setMaxValue(max_value);
gauge.setMinValue(min_value);
});
Any ideas what am I doing wrong?
When using gauge.getSection().get(0).setStart()
-> won't redraw until I redraw (resize) it manually
Adding change listeners to section start/end property should fix this issue, however I assume that Section doesn't have internal reference to parent gauge, so this is probably behavior needs to be implemented by changing(appending) to function addSection where for every Section needs to be done something like this section.startProperty.addListener(<redraw>)
To reproduce this issue in OverviewDemo add the folloging line:
gauge5.setTitle("New Title");
And check the title is not modified
Hi!
I'm trying to disable the autoscale of averege on TileSparklineSkin gauge.
It's possible ?
Thanks !
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.