Skip to content

Conversation

AlexV525
Copy link
Member

@AlexV525 AlexV525 commented Sep 4, 2025

(originally #8496)

This PR fixes a NoSuchElementException that occurs in the DeviceSelectorAction when IntelliJ's toolbar layout system tries to calculate component widths.

Problem

The error manifested as:

java.util.NoSuchElementException: Key io.flutter.actions.DeviceSelectorAction$1[...] is missing in the map.
	at kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable(MapWithDefault.kt:24)
	at kotlin.collections.MapsKt__MapsKt.getValue(Maps.kt:369)
	at com.intellij.openapi.actionSystem.toolbarLayout.CompressingLayoutStrategyKt.calculateComponentWidths(CompressingLayoutStrategy.kt:200)

Root Cause

The getPreferredSize() method in the anonymous JButton class was being called by IntelliJ's layout system before the client properties (ICON_LABEL_KEY, TEXT_LABEL_KEY, ARROW_LABEL_KEY) were set during component initialization. This caused the layout system to fail when trying to register the component in its internal maps because:

  1. The method accessed null client properties without proper fallback handling
  2. Used unsafe Objects.requireNonNull(fm) calls that could throw exceptions
  3. The layout system couldn't determine proper component dimensions during initialization

Solution

Enhanced the getPreferredSize() method with defensive programming:

  • Added fallback logic: When client properties are null (during initialization), use the same default icons and text that would normally be used
  • Safe null checking: Replaced Objects.requireNonNull(fm) with proper null checks
  • Reasonable defaults: Provide sensible sizing estimates using FlutterIcons.Mobile, chevron down icon, and "No device selected" text width
// Before: Unsafe access
width += Objects.requireNonNull(fm).stringWidth(text);

// After: Defensive with fallback
if (fm != null) {
  width += fm.stringWidth(text);
  height = Math.max(height, fm.getHeight());
}

Impact

  • Eliminates NoSuchElementException during toolbar initialization
  • Maintains exact same functionality once component is fully initialized
  • No performance impact - fallback logic only runs during the brief initialization phase
  • More robust component that gracefully handles IntelliJ's layout timing

Fixes #8494.

@AlexV525 AlexV525 self-assigned this Sep 4, 2025
@AlexV525 AlexV525 requested a review from pq September 4, 2025 07:06
@AlexV525 AlexV525 marked this pull request as ready for review September 4, 2025 07:06
@AlexV525 AlexV525 requested review from jwren and helin24 September 9, 2025 14:32
@helin24 helin24 added the 🤖 AI-assisted For PRs with significant code generated by AI label Sep 9, 2025
@AlexV525 AlexV525 added the autosubmit When this label is applied to a PR, the PR will be submitted as soon as all checks are green. label Sep 10, 2025
@auto-submit auto-submit bot merged commit e9b498d into main Sep 10, 2025
7 checks passed
@AlexV525 AlexV525 deleted the copilot/fix-8494 branch September 10, 2025 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 AI-assisted For PRs with significant code generated by AI autosubmit When this label is applied to a PR, the PR will be submitted as soon as all checks are green.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DeviceSelectorAction: NoSuchElementException
2 participants