B4J Library jGauges

SS-2016-08-31_13.04.05.png


This is a wrapper for Medusa gauges library: https://github.com/HanSolo/Medusa
License: https://github.com/HanSolo/Medusa/blob/master/license.txt

It includes many types of gauges. The gauges are implemented as custom views.

The gauges can be further customized. You can use JavaObject to access the various methods (see the source code of Gauge.java: https://github.com/HanSolo/Medusa/blob/master/src/main/java/eu/hansolo/medusa/Gauge.java).

Library: www.b4x.com/b4j/files/jGauges.zip

Example is attached.

Updates:

v1.10 - Based on latest version of the open source projects. Includes three new skins (TILE_KPI, TILE_TEXT_KPI, TILE_SPARK_LINE)
java_MYXILlD7yu.png
 

Attachments

  • GaugesExample.zip
    4.5 KB · Views: 1,156
Last edited:

CHAUVET

Member
Licensed User
Longtime User
Hi jmon,
Hi Erel,

Thank you for your explanation and example.

Thanks to you I understand the mechanism. But it is not very simple in the sense that we do not know what to look for.

What would be fantastic about the B4X tools is having a panel with all the properties of an object (as VB did).

I worked very long time on ATARI ST with GFA Basic, then even more time on Visual Basic. Currently I work in PHP.

When I discovered B4J I had an immense joy. This tool allowed me to continue using the BASIC language to create JAVA programs. An old language that allows to generate a modern code. In this, the idea of Erel is an extraordinary idea. Many small developers (like me) have stalled with VB.NET.

B4J is fantastic but if the syntax is easily understandable it is necessary to have solid knowledge in JAVA to be able to get out (search in java source code for use this in basic langugage). It is somehow nonsense. Indeed why continue in BASIC if I know the JAVA? Or if I have to learn the JAVA to do Basic? Strange not?

In my case (and I think I'm not the only one) I have a great pleasure and a facility to use the Basic language and I do not master in JAVA. Because of this I have a great frustration because I can use a simple tool but I can not go very far in my projects because it becomes limited if we do not control JAVA.

Erel, how to make B4J simpler for a "small devloper in BASIC"?

I think your project is a beautiful thing. But I think so too it lacks a link in your project.

You can propose and sell additional modules as was possible with VB (like .vbx in old VB) And open this to the community of B4J for a good JAVA encoder that knows B4J. These coders could free or not to offer new modules with all the properties available on a panel.

For each module (jGauge for example) there is a panel with all the properties to define the set : sizes, colors, position on form, etc...

What do you think ?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
For each module (jGauge for example) there is a panel with all the properties to define the set : sizes, colors, position on form, etc...

What do you think ?
This is already the case with %99.9 of the libraries. You can use this tool to see the methods: https://www.b4x.com/android/forum/t...cumentation-b4x-object-browser.25682/#content
Also available online: https://www.b4x.com/b4j/documentation.html

In this library, there were so many native methods that I decided not to wrap them and therefore they require a bit more work.
 

jmon

Well-Known Member
Licensed User
Longtime User
How can I find the list of methods available in this library?
I found better:
https://github.com/HanSolo/Medusa/wiki
Gauge gauge =
GaugeBuilder.create()
.skinType(SkinType.GAUGE) // Skin for your Gauge
.prefSize(500,500) // Preferred size of control
// Related to Foreground Elements
.foregroundBaseColor(Color.BLACK) // Color for title, subtitle, unit, value, tick label, zeroColor, tick mark, major tick mark, medium tick mark and minor tick mark
// Related to Title Text
.title("Title") // Text for title
.titleColor(Color.BLACK) // Color for title text
// Related to Sub Title Text
.subTitle("SubTitle") // Text for subtitle
.subTitleColor(Color.BLACK) // Color for subtitle text
// Related to Unit Text
.unit("Unit") // Text for unit
.unitColor(Color.BLACK) // Color for unit text
// Related to Value Text
.valueColor(Color.BLACK) // Color for value text
.decimals(0) // Number of decimals for the value/lcd text
// Related to LCD
.lcdVisible(false) // LCD instead of the plain value text
.lcdDesign(LcdDesign.STANDARD) // Design for LCD
.lcdFont(LcdFont.DIGITAL_BOLD) // Font for LCD (STANDARD, LCD, DIGITAL, DIGITAL_BOLD, ELEKTRA)
// Related to scale
.scaleDirection(ScaleDirection.CLOCKWISE) // Direction of Scale (CLOCKWISE, COUNTER_CLOCKWISE)
.minValue(0) // Start value of Scale
.maxValue(100) // End value of Scale
.startAngle(320) // Start angle of Scale (bottom -> 0, direction -> CCW)
.angleRange(280) // Angle range of Scale starting from the start angle
// Related to Tick Labels
.tickLabelDecimals(0) // Number of decimals for tick labels
.tickLabelLocation(TickLabelLocation.INSIDE) // Should tick labels be inside or outside Scale (INSIDE, OUTSIDE)
.tickLabelOrientation(TickLabelOrientation.HORIZONTAL) // Orientation of tick labels (ORTHOGONAL, HORIZONTAL, TANGENT)
.onlyFirstAndLastTickLabelVisible(false) // Should only the first and last tick label be visible
.tickLabelSectionsVisible(false) // Should sections for tick labels be visible
.tickLabelSections(section1, section2) // Sections to color tick labels
.tickLabelColor(Color.BLACK) // Color for tick labels (overriden by tick label sections)
// Related to Tick Marks
.tickMarkSectionsVisible(false) // Should sections for tick marks be visible
.tickMarkSections(section1, section2) // Sections to color tick marks
// Related to Major Tick Marks
.majorTickMarksVisible(true) // Should major tick marks be visible
.majorTickMarkType(TickMarkType.LINE) // Tick mark type for major tick marks (LINE, DOT, TRIANGLE, TICK_LABEL)
.majorTickMarkColor(Color.BLACK) // Color for major tick marks (overriden by tick mark sections)
// Related to Medium Tick Marks
.mediumTickMarksVisible(true) // Should medium tick marks be visible
.mediumTickMarkType(TickMarkType.LINE) // Tick mark type for medium tick marks (LINE, DOT, TRIANGLE)
.mediumTickMarkColor(Color.BLACK) // Color for medium tick marks (overriden by tick mark sections)
// Related to Minor Tick Marks
.minorTickMarksVisible(true) // Should minor tick marks be visible
.minorTickMarkType(TickMarkType.LINE) // Tick mark type for minor tick marks (LINE, DOT, TRIANGLE)
.minorTickMarkColor(Color.BLACK) // Color for minor tick marks (override by tick mark sections)
// Related to LED
.ledVisible(false) // Should LED be visible
.ledType(LedType.STANDARD) // Type of the LED (STANDARD, FLAT)
.ledColor(Color.rgb(255, 200, 0)) // Color of LED
.ledBlinking(false) // Should LED blink
.ledOn(false) // LED on or off
// Related to Needle
.needleShape(NeedleShape.ANGLED) // Shape of needle (ANGLED, ROUND, FLAT)
.needleSize(NeedleSize.STANDARD) // Size of needle (THIN, STANDARD, THICK)
.needleColor(Color.CRIMSON) // Color of needle
// Related to Needle behavior
.startFromZero(false) // Should needle start from the 0 value
.returnToZero(false) // Should needle return to the 0 value (only makes sense when animated==true)
// Related to Knob
.knobType(KnobType.STANDARD) // Type for center knob (STANDARD, PLAIN, METAL, FLAT)
.knobColor(Color.LIGHTGRAY) // Color of center knob
.interactive(false) // Should center knob be act as button
.onButtonPressed(buttonEvent -> System.out.println("Knob pressed")) // Handler (triggered when the center knob was pressed)
.onButtonReleased(buttonEvent -> System.out.println("Knob released")) // Handler (triggered when the center knob was released)
// Related to Threshold
.thresholdVisible(false) // Should threshold indicator be visible
.threshold(50) // Value of threshold
.thresholdColor(Color.RED) // Color of threshold indicator
.checkThreshold(false) // Should each value be checked against threshold
.onThresholdExceeded(thresholdEvent -> System.out.println("Threshold exceeded")) // Handler (triggered if checkThreshold==true and the threshold is exceeded)
.onThresholdUnderrun(thresholdEvent -> System.out.println("Threshold underrun")) // Handler (triggered if checkThreshold==true and the threshold is underrun)
// Related to Gradient Bar
.gradientBarEnabled(false) // Should gradient filled bar be visible to visualize a range
.gradientBarStops(new Stop(0.0, Color.BLUE), // Color gradient that will be use to color fill bar
new Stop(0.25, Color.CYAN),
new Stop(0.5, Color.LIME),
new Stop(0.75, Color.YELLOW),
new Stop(1.0, Color.RED))
// Related to Sections
.sectionsVisible(false) // Should sections be visible
.sections(section1, section2) // Sections that will be drawn (won't be drawn if colorGradientEnabled==true)
.checkSectionsForValue(false) // Should each section be checked against current value (if true section events will be fired)
// Related to Areas
.areasVisible(false) // Should areas be visible
.areas(section1, section2) // Areas that will be drawn
// Related to Markers
.markersVisible(false) // Should markers be visible
.markers(marker1, marker2) // Markers that will be drawn
// Related to Value
.animated(false) // Should needle be animated
.animationDuration(500) // Speed of needle in milliseconds (10 - 10000 ms)
.onValueChanged(o -> System.out.println(((DoubleProperty) o).get())) // InvalidationListener (triggered each time the value changed)
.build();

Also a wiki for the skins:
https://github.com/HanSolo/Medusa/wiki/Gauge Skins
 

CHAUVET

Member
Licensed User
Longtime User
Hi,
jmon you are the King !!!
big thanks

With your help here is the result :

B4X:
    Dim minValue, maxValue, Value, decimal As Double 'type is important
    Dim Title, Unit, Skin, subTitle As String
    Value = 75
    minValue = 0
    maxValue = 150
    Title = "Power"
    subTitle = "sub title"
    Unit = "Watt"
    Skin = "DASHBOARD"

    Dim jo As JavaObject = Gauge12


    jo.RunMethod("setSkinType", Array(Skin))
    jo.RunMethod("setMinValue", Array(minValue))
    jo.RunMethod("setMaxValue", Array(maxValue))
    jo.RunMethod("setValue", Array(Value))

    jo.RunMethod("setTitle", Array(Title))
    jo.RunMethod("setUnit", Array(Unit))
    jo.RunMethod("setSubTitle", Array(subTitle))
  
    jo.RunMethod("setForegroundBaseColor", Array(fx.Colors.RGB(82,82,82))) ' Color for title, subtitle, unit, value, tick label, zeroColor
    jo.RunMethod("setUnitColor", Array(fx.Colors.RGB(82,82,82)))
    jo.RunMethod("setTitleColor", Array(fx.Colors.RGB(82,82,82)))
    jo.RunMethod("setSubTitleColor", Array(fx.Colors.RGB(82,82,82)))


    jo.RunMethod("setValueColor", Array(fx.Colors.RGB(82,82,82)))
    jo.RunMethod("setBarBackgroundColor", Array(fx.Colors.RGB(255,64,64)))
    jo.RunMethod("setBarColor", Array(fx.Colors.RGB(125,125,125)))

    jo.RunMethod("setDecimals", Array(1))
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,

receiving stackoverflow error when setting min/max value for Skin GAUGE.
A small test project attached with two gauges, one (gauge1) with skin DASHBOARD for which min/max value setting is working and the second (gauge2) with skin GAUGE.

The error log is rather big - here an extract:
B4X:
main._buttongauge2setminmax_action (java line: 104)
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 anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
    at b4j.example.main._buttongauge2setminmax_action(main.java:104)
    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 anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
    at anywheresoftware.b4a.BA$2.run(BA.java:165)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.StackOverflowError
    at eu.hansolo.medusa.Gauge.getRange(Gauge.java:744)
    at eu.hansolo.medusa.Gauge.calcAutoScale(Gauge.java:4844)
    at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:353)
...
 

Attachments

  • GaugesTest.zip
    2.7 KB · Views: 656

rwblinn

Well-Known Member
Licensed User
Longtime User
Thanks for the hint.
Found a next runtime error when the minValue > 99 (Note: when setting using the designer, then no issue with f.e. range 950 - 1100):
B4X:
main._buttongauge2setminmax_action (java line: 106)
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 anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
    at b4j.example.main._buttongauge2setminmax_action(main.java:106)
    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 anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
    at anywheresoftware.b4a.BA$2.run(BA.java:165)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NumberFormatException: Infinite or NaN
    at java.math.BigDecimal.<init>(Unknown Source)
    at java.math.BigDecimal.<init>(Unknown Source)
    at eu.hansolo.medusa.tools.Helper.drawRadialTickMarks(Helper.java:531)
    at eu.hansolo.medusa.skins.GaugeSkin.redraw(GaugeSkin.java:1055)
    at eu.hansolo.medusa.skins.GaugeSkin.handleEvents(GaugeSkin.java:369)
    at eu.hansolo.medusa.skins.GaugeSkin.lambda$4(GaugeSkin.java:301)
    at eu.hansolo.medusa.Gauge.fireUpdateEvent(Gauge.java:5177)
    at eu.hansolo.medusa.Gauge.setMinValue(Gauge.java:667)
    ... 19 more

when using
B4X:
jo.RunMethod("setAutoScale", Array(False))
jo.RunMethod("setMinValue", Array(minValue))
jo.RunMethod("setMaxValue", Array(maxValue))
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Thanks again --- after various tryouts because the scale was either missing or only 3 ticks etc., this is working for values > 99:

In the designer set the min to 0 and the max to 100.
Then when app is running, change the scale like
B4X:
Dim minValue, maxValue As Double
minValue = 950
maxValue = 1100
'IMPORTANT = set autoscale to false, then max prior min value
jo.RunMethod("setAutoScale", Array(False))
jo.RunMethod("setMaxValue", Array(maxValue))
jo.RunMethod("setMinValue", Array(minValue))

BTW: this is the result:
upload_2017-2-5_12-16-42.png
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
but receive errors.
You should post it.

1. The method name is "setTickMarkSections"

2. It expects a list of sections.

Untested code:
B4X:
Dim sections As List
sections.Initialize
sections.Add(CreateSection(1, 2))
jo.RunMethod("setTickMarkSections", Array(sections))


Sub CreateSection(Start As Double, Stop As Double) As Object
 Dim jo As JavaObject
 jo.InitializeNewInstance("eu.hansolo.medusa.Section", Array(Start, Stop))
Return jo
End Sub
 

maleche

Active Member
Licensed User
Longtime User
The inner scale worked!
however, the outer numbers still show 1,1,2,2,3,3. I'm looking for the method to change this as well.
see picture.
thank you for the insight!
Doyle
 

Attachments

  • DAQ picture.PNG
    DAQ picture.PNG
    131.3 KB · Views: 414
Top