Skip to content

Phase 2.2: ToolBar and StatusBar Integration for Simulation Speed Control#485

Merged
bedaHovorka merged 8 commits intocopilot/goal-7-simulation-speed-controlfrom
copilot/add-toolbar-statusbar-integration
May 5, 2026
Merged

Phase 2.2: ToolBar and StatusBar Integration for Simulation Speed Control#485
bedaHovorka merged 8 commits intocopilot/goal-7-simulation-speed-controlfrom
copilot/add-toolbar-statusbar-integration

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 5, 2026

Implements Phase 2.2 of Goal 7 (Simulation Speed Control): wires ToolBar and StatusBar to the SimulationRunner PropertyChangeListener for automatic, EDT-safe UI updates during simulation.

Changes Made

ToolBar.kt (+20 lines)

  • Added showSimulationControls() — dynamically appends a JToolBar.Separator and a "▶ Simulation" label to the toolbar when a simulation starts. Idempotent (no-op if already shown).
  • Added hideSimulationControls() — removes those components when the simulation stops. Idempotent (no-op if already hidden).

StatusBar.kt (+15 lines)

  • Added updateSpeedIndicator(multiplier: Double) — EDT-safe via SwingUtilities.invokeLater; shows "Speed: X.Xx" text and makes the bar visible when multiplier ≠ 1.0×, hides it at default speed.
  • Added companion object with DEFAULT_SPEED and SPEED_EPSILON constants.

SimulationController.kt

  • Added optional toolBar: ToolBar? and statusBar: StatusBar? constructor parameters (default null, fully backward-compatible).
  • start(): registers a PropertyChangeListener on SimulationRunner.PROP_SPEED_MULTIPLIER with a safe as? Double cast and debug logging for unexpected types; calls toolBar.showSimulationControls().
  • stop() and monitor-thread finally: call toolBar.hideSimulationControls(), statusBar.updateSpeedIndicator(DEFAULT_SPEED), and remove the speed listener via cleanupSpeedListener() to prevent leaks.

Frame.kt

  • Introduced southPanel: JPanel (BoxLayout Y_AXIS) permanently at BorderLayout.SOUTH, acting as a container for both StatusBar and EventTimelinePanel. This resolves the layout conflict that previously required removing StatusBar from the content pane.
  • switchToSimulationMode(): adds EventTimelinePanel at index TIMELINE_PANEL_SOUTH_INDEX = 0 (above StatusBar), hides StatusBar (re-shown by updateSpeedIndicator when speed ≠ 1.0×).
  • switchToEditingMode(): removes EventTimelinePanel, shows StatusBar.
  • Passes toolBar and statusBar to SimulationController.

Design Points

  • ToolBar appends/removes a separator + label; no SimulationControlPanel subclass needed.
  • StatusBar speed indicator is hidden at default speed and shown automatically for non-1× speeds.
  • PropertyChangeListener is registered on the active SimulationRunner in start() and removed on stop() or natural completion — no listener leaks.
  • All UI mutations go through SwingUtilities.invokeLater, ensuring EDT safety.

Testing

  • StatusBarTest: 3 new tests covering speed text rendering, visibility at default speed, and decimal formatting.
  • SimulationControllerTest: 2 new tests covering speed change propagation to StatusBar and speed indicator reset on stop(). Both test classes include a flushEDT() helper to reliably flush invokeLater tasks.
  • FrameTest: Updated frameHasStatusBarAtSouth to reflect the new southPanel container at BorderLayout.SOUTH.
  • ✅ 504 tests total (503 pass, 1 pre-existing skip), ktlintCheck and detekt clean.

@bedaHovorka
Copy link
Copy Markdown
Owner

@copilot : please try again

@bedaHovorka
Copy link
Copy Markdown
Owner

@copilot : please try again

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 5, 2026

@copilot : please try again

Reimplemented Phase 2.2 from scratch (commit 92db2b3):

ToolBar.kt: Added showSimulationControls() / hideSimulationControls() — dynamically adds/removes a "▶ Simulation" label + separator to the toolbar. Both are idempotent and EDT-safe.

StatusBar.kt: Added updateSpeedIndicator(Double) — shows "Speed: X.Xx" and makes the bar visible when speed ≠ 1.0×, hides it at default speed. EDT-safe via SwingUtilities.invokeLater.

SimulationController.kt: Added optional toolBar/statusBar params; registers a PropertyChangeListener on SimulationRunner.PROP_SPEED_MULTIPLIER that forwards speed changes to statusBar.updateSpeedIndicator(). Calls toolBar.show/hideSimulationControls() on start/stop/natural finish. Safe as? Double cast with debug logging for unexpected types.

Frame.kt: Introduced southPanel: JPanel (BoxLayout Y_AXIS) at BorderLayout.SOUTH; StatusBar and EventTimelinePanel are both children of this panel (EventTimelinePanel added/removed on mode switch). Passes toolBar and statusBar to SimulationController.

Tests: 5 new tests covering speed indicator visibility, format, and wiring (504 total, 503 pass, 1 skip pre-existing).

Copilot AI changed the title [WIP] Add toolbar and status bar integration for simulation controls Phase 2.2: ToolBar and StatusBar Integration for Simulation Speed Control May 5, 2026
@bedaHovorka bedaHovorka marked this pull request as ready for review May 5, 2026 20:08

This comment was marked as resolved.

@bedaHovorka
Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

Copilot AI and others added 6 commits May 5, 2026 23:05
…tor integration

Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/a05d505b-27f4-4dc3-8ad6-c336a6ca4ec8

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
…o, named constant

Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/a05d505b-27f4-4dc3-8ad6-c336a6ca4ec8

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/f4316065-c3a6-47a4-be98-31cf8f27dd5d

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
The class-level ASCII diagram omitted StatusBar from the simulation mode
view. The implementation keeps StatusBar visible throughout (speed
indicator uses its separate speedLabel); the diagram now matches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The test was missing the EDT drain call that the sibling test
stopResetsStatusBarSpeedIndicator already has. Without it, the
monitor thread's invokeLater callback races the invokeAndWait verify
task on slow CI runners, causing a non-deterministic 10s timeout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bedaHovorka bedaHovorka force-pushed the copilot/add-toolbar-statusbar-integration branch from 640459c to f831447 Compare May 5, 2026 21:36
CI runs on ubuntu-latest with no Xvfb, default headless mode, and parallel
test forks. The cumulative latch + flushEDT + invokeAndWait budget exceeds
the previous 10s cap under contention even though the test logic is sound.
30s gives ~3x headroom while still failing fast on a true logic regression
(internal latches still cap themselves at 5s and 10s).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

@bedaHovorka bedaHovorka merged commit 6a1db41 into copilot/goal-7-simulation-speed-control May 5, 2026
9 checks passed
@bedaHovorka bedaHovorka deleted the copilot/add-toolbar-statusbar-integration branch May 5, 2026 22:15
Copilot AI added a commit that referenced this pull request May 6, 2026
…trol (#485)

* Phase 2.2: Add ToolBar/StatusBar simulation controls and speed indicator integration

Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/a05d505b-27f4-4dc3-8ad6-c336a6ca4ec8

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>

* Fix code review: safe cast, kotlin.math.abs import, function name typo, named constant

Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/a05d505b-27f4-4dc3-8ad6-c336a6ca4ec8

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>

* Address code review: import order, debug logging, flushEDT() helpers in tests

Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/a05d505b-27f4-4dc3-8ad6-c336a6ca4ec8

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>

* Changes before error encountered

Agent-Logs-Url: https://github.com/bedaHovorka/interlockSim/sessions/f4316065-c3a6-47a4-be98-31cf8f27dd5d

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>

* Fix Frame.kt simulation-mode layout diagram to show StatusBar

The class-level ASCII diagram omitted StatusBar from the simulation mode
view. The implementation keeps StatusBar visible throughout (speed
indicator uses its separate speedLabel); the diagram now matches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix flaky stopHidesToolBarSimulationControls: add missing flushEDT()

The test was missing the EDT drain call that the sibling test
stopResetsStatusBarSpeedIndicator already has. Without it, the
monitor thread's invokeLater callback races the invokeAndWait verify
task on slow CI runners, causing a non-deterministic 10s timeout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Bump stopHidesToolBarSimulationControls @timeout 10s -> 30s

CI runs on ubuntu-latest with no Xvfb, default headless mode, and parallel
test forks. The cumulative latch + flushEDT + invokeAndWait budget exceeds
the previous 10s cap under contention even though the test logic is sound.
30s gives ~3x headroom while still failing fast on a true logic regression
(internal latches still cap themselves at 5s and 10s).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
Co-authored-by: Bedrich Hovorka <bedrich.hovorka@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 2.2: ToolBar and StatusBar Integration

3 participants