1616import java .awt .image .BufferedImage ;
1717import java .text .NumberFormat ;
1818import java .util .Objects ;
19+ import java .util .regex .Pattern ;
1920import java .util .concurrent .TimeUnit ;
2021import java .util .concurrent .atomic .AtomicBoolean ;
2122
@@ -166,7 +167,11 @@ public RTTank()
166167 widthProperty ().addListener (resize_listener );
167168 heightProperty ().addListener (resize_listener );
168169
169- // 20Hz default throttle
170+ // 20Hz default throttle.
171+ // When parallel_rendering is enabled, each tank renders on the shared thread pool
172+ // so that many tanks on a display update concurrently. The default (false) serialises
173+ // all renders on the single global UpdateThrottle.TIMER thread — safe but slow for
174+ // displays with many Tank / ProgressBar widgets.
170175 update_throttle = new UpdateThrottle (50 , TimeUnit .MILLISECONDS , () ->
171176 {
172177 if (needUpdate .getAndSet (false )){
@@ -178,7 +183,7 @@ public RTTank()
178183 requestUpdate ();
179184 }
180185 }
181- });
186+ }, Activator . parallel_rendering ? Activator . thread_pool : UpdateThrottle . TIMER );
182187
183188 // Configure right-side scale — must happen after update_throttle is
184189 // initialised because setOnRight() triggers requestUpdate() via the
@@ -335,12 +340,12 @@ private static NumberFormat significantDigitsFormat(final int prec)
335340 @ Override
336341 public StringBuffer format (final double v , final StringBuffer buf , final java .text .FieldPosition pos )
337342 {
338- return buf .append (String .format (java .util .Locale .ROOT , pattern , v ));
343+ return buf .append (normaliseExponent ( String .format (java .util .Locale .ROOT , pattern , v ) ));
339344 }
340345 @ Override
341346 public StringBuffer format (final long v , final StringBuffer buf , final java .text .FieldPosition pos )
342347 {
343- return buf .append (String .format (java .util .Locale .ROOT , pattern , (double ) v ));
348+ return buf .append (normaliseExponent ( String .format (java .util .Locale .ROOT , pattern , (double ) v ) ));
344349 }
345350 @ Override
346351 public Number parse (final String s , final java .text .ParsePosition pos )
@@ -350,6 +355,28 @@ public Number parse(final String s, final java.text.ParsePosition pos)
350355 };
351356 }
352357
358+ /** Pre-compiled pattern for stripping the sign and leading zeros from a
359+ * {@code %g} exponent string such as {@code "-01"} or {@code "+02"}.
360+ */
361+ private static final Pattern EXP_LEADING_ZEROS = Pattern .compile ("^[+-]?0*" );
362+
363+ /** Normalise a {@code %g}-formatted string to match Phoebus axis convention:
364+ * uppercase {@code E}, no leading zeros on the exponent, no {@code +} sign.
365+ * Examples: {@code "1.0e-01"} → {@code "1.0E-1"},
366+ * {@code "2.5e+02"} → {@code "2.5E2"}.
367+ */
368+ private static String normaliseExponent (final String s )
369+ {
370+ final int e = s .indexOf ('e' );
371+ if (e < 0 )
372+ return s ; // decimal notation — no exponent to fix
373+ final String mantissa = s .substring (0 , e );
374+ final String raw = s .substring (e + 1 ); // e.g. "-01", "+02"
375+ final boolean neg = raw .startsWith ("-" );
376+ final String digits = EXP_LEADING_ZEROS .matcher (raw ).replaceFirst ("" );
377+ return mantissa + "E" + (neg ? "-" : "" ) + (digits .isEmpty () ? "0" : digits );
378+ }
379+
353380 /** Set alarm and warning limit values to display as horizontal lines on the tank.
354381 * Pass {@link Double#NaN} for any limit that should not be shown.
355382 * @param lolo LOLO (major alarm) lower limit
0 commit comments