This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-23512-fix-tui-tamboui-api in repository https://gitbox.apache.org/repos/asf/camel.git
commit b5c3d1c166623836094c9143b54b11ecfe0176d0 Author: Claus Ibsen <[email protected]> AuthorDate: Wed May 13 21:58:36 2026 +0200 CAMEL-23512: Fix TamboUI API misuse in camel-jbang-plugin-tui - Replace deprecated KeyEvent.character() with ke.string() for proper Unicode support - Use CharWidth for display width calculations instead of String.length() - Fix TuiHelper.truncate() to use CharWidth.truncateWithEllipsis() - Fix CamelCatalogTui.wrapText() and flowFields() to use CharWidth - Fix CamelMonitor diagram width calculation to use CharWidth - Enable mouse capture in CamelMonitor for diagram scrolling - Move TableState for processors and route header to class fields Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> --- .../jbang/core/commands/tui/CamelCatalogTui.java | 31 +++++++++++++--------- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 12 ++++++--- .../dsl/jbang/core/commands/tui/TuiHelper.java | 5 +++- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelCatalogTui.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelCatalogTui.java index cbd2e3022b0c..6b2ffc12e9b3 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelCatalogTui.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelCatalogTui.java @@ -28,6 +28,7 @@ import dev.tamboui.style.Color; import dev.tamboui.style.Overflow; import dev.tamboui.style.Style; import dev.tamboui.terminal.Frame; +import dev.tamboui.text.CharWidth; import dev.tamboui.text.Line; import dev.tamboui.text.Span; import dev.tamboui.text.Text; @@ -374,10 +375,10 @@ public class CamelCatalogTui extends CamelCommand { // Typing filters the active panel if (ke.code() == KeyCode.CHAR) { if (focus == FOCUS_LIST) { - componentFilter.append(ke.character()); + componentFilter.append(ke.string()); applyComponentFilter(); } else { - optionFilter.append(ke.character()); + optionFilter.append(ke.string()); applyOptionFilter(); } return true; @@ -677,10 +678,10 @@ public class CamelCatalogTui extends CamelCommand { for (String[] field : fields) { String label = field[0] + ": "; String value = field[1]; - int fieldLen = label.length() + value.length(); + int fieldLen = CharWidth.of(label) + CharWidth.of(value); // If adding this field would exceed width, flush current line - if (!currentSpans.isEmpty() && currentLen + gap.length() + fieldLen > maxWidth) { + if (!currentSpans.isEmpty() && currentLen + CharWidth.of(gap) + fieldLen > maxWidth) { lines.add(Line.from(currentSpans)); currentSpans = new ArrayList<>(); currentLen = 1; @@ -688,7 +689,7 @@ public class CamelCatalogTui extends CamelCommand { if (!currentSpans.isEmpty()) { currentSpans.add(Span.raw(gap)); - currentLen += gap.length(); + currentLen += CharWidth.of(gap); } else { currentSpans.add(Span.raw(" ")); } @@ -723,15 +724,19 @@ public class CamelCatalogTui extends CamelCommand { } int pos = 0; while (pos < text.length()) { - int end = Math.min(pos + width, text.length()); - if (end < text.length() && end > pos) { - int lastSpace = text.lastIndexOf(' ', end); - if (lastSpace > pos) { - end = lastSpace + 1; - } + String remaining = text.substring(pos); + int remainingWidth = CharWidth.of(remaining); + if (remainingWidth <= width) { + lines.add(Line.from(Span.styled(" " + remaining.trim(), style))); + break; + } + String chunk = CharWidth.substringByWidth(remaining, width); + int lastSpace = chunk.lastIndexOf(' '); + if (lastSpace > 0) { + chunk = chunk.substring(0, lastSpace + 1); } - lines.add(Line.from(Span.styled(" " + text.substring(pos, end).trim(), style))); - pos = end; + lines.add(Line.from(Span.styled(" " + chunk.trim(), style))); + pos += chunk.length(); } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java index 8b3f9e9a3fc4..ea17f985877c 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java @@ -49,9 +49,11 @@ import dev.tamboui.style.Color; import dev.tamboui.style.Overflow; import dev.tamboui.style.Style; import dev.tamboui.terminal.Frame; +import dev.tamboui.text.CharWidth; import dev.tamboui.text.Line; import dev.tamboui.text.Span; import dev.tamboui.text.Text; +import dev.tamboui.tui.TuiConfig; import dev.tamboui.tui.TuiRunner; import dev.tamboui.tui.event.Event; import dev.tamboui.tui.event.KeyCode; @@ -131,6 +133,8 @@ public class CamelMonitor extends CamelCommand { private final TableState routeTableState = new TableState(); private final TableState healthTableState = new TableState(); private final TableState endpointTableState = new TableState(); + private final TableState processorTableState = new TableState(); + private final TableState routeHeaderTableState = new TableState(); private final TabsState tabsState = new TabsState(TAB_OVERVIEW); // Sparkline: throughput history per PID (one point per second) @@ -206,7 +210,7 @@ public class CamelMonitor extends CamelCommand { // Initial data load refreshData(); - try (var tui = TuiRunner.create()) { + try (var tui = TuiRunner.create(TuiConfig.builder().mouseCapture(true).build())) { // Intercept Ctrl+C: quit the TUI cleanly instead of letting // the JVM tear down the classloader while we're still running Signal.handle(new Signal("INT"), sig -> tui.quit()); @@ -936,7 +940,7 @@ public class CamelMonitor extends CamelCommand { .title(" Processors [" + route.routeId + "] ").build()) .build(); - frame.renderStatefulWidget(table, area, new TableState()); + frame.renderStatefulWidget(table, area, processorTableState); } private void renderRouteHeader(Frame frame, Rect area, IntegrationInfo info) { @@ -994,7 +998,7 @@ public class CamelMonitor extends CamelCommand { .title(" Route [" + info.name + "] ").build()) .build(); - frame.renderStatefulWidget(table, area, new TableState()); + frame.renderStatefulWidget(table, area, routeHeaderTableState); } private void renderDiagram(Frame frame, Rect area) { @@ -1011,7 +1015,7 @@ public class CamelMonitor extends CamelCommand { // Compute max width for horizontal scrolling int maxWidth = 0; for (String line : diagramLines) { - maxWidth = Math.max(maxWidth, line.length()); + maxWidth = Math.max(maxWidth, CharWidth.of(line)); } Rect inner = block.inner(area); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java index 87b7cc74d9e3..0183a53b139e 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Function; +import dev.tamboui.text.CharWidth; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.FileUtil; @@ -109,7 +110,9 @@ final class TuiHelper { if (s == null) { return ""; } - return s.length() > max ? s.substring(0, max - 1) + "\u2026" : s; + return CharWidth.of(s) > max + ? CharWidth.truncateWithEllipsis(s, max, CharWidth.TruncatePosition.END) + : s; } /**
