diff --git a/src/io/flutter/FlutterBundle.properties b/src/io/flutter/FlutterBundle.properties index 5eb641da6..d5ecbb1a5 100644 --- a/src/io/flutter/FlutterBundle.properties +++ b/src/io/flutter/FlutterBundle.properties @@ -74,6 +74,8 @@ flutter.io.gettingStarted.IDE.url=https://docs.flutter.dev/tools/android-studio flutter.io.runAndDebug.url=https://docs.flutter.dev/tools/android-studio#running-and-debugging devicelist.loading=Loading... +devicelist.noDevices= +devicelist.noDeviceSelected= flutter.pop.frame.action.text=Drop Frame (Flutter) flutter.pop.frame.action.description=Pop the current frame off the stack diff --git a/src/io/flutter/actions/DeviceSelectorAction.java b/src/io/flutter/actions/DeviceSelectorAction.java index c2c23728b..570b1d82f 100644 --- a/src/io/flutter/actions/DeviceSelectorAction.java +++ b/src/io/flutter/actions/DeviceSelectorAction.java @@ -115,21 +115,44 @@ public Dimension getPreferredSize() { int width = 0; int height = JBUI.scale(22); + // Provide fallback values if client properties are not yet set if (iconLabel instanceof JBLabel label && label.getIcon() instanceof Icon icon) { width += icon.getIconWidth(); height = Math.max(height, icon.getIconHeight()); } + else if (iconLabel == null) { + // Fallback: use the default mobile icon size when the component is not fully initialized + Icon defaultIcon = FlutterIcons.Mobile; + width += defaultIcon.getIconWidth(); + height = Math.max(height, defaultIcon.getIconHeight()); + } if (textLabel instanceof JBLabel label && label.getText() instanceof String text && !text.isEmpty()) { final FontMetrics fm = label.getFontMetrics(label.getFont()); - width += Objects.requireNonNull(fm).stringWidth(text); - height = Math.max(height, fm.getHeight()); + if (fm != null) { + width += fm.stringWidth(text); + height = Math.max(height, fm.getHeight()); + } + } + else if (textLabel == null) { + // Fallback: estimate width for typical device name length + final FontMetrics fm = getFontMetrics(getFont()); + if (fm != null) { + width += fm.stringWidth(FlutterBundle.message("devicelist.noDeviceSelected")); + height = Math.max(height, fm.getHeight()); + } } if (arrowLabel instanceof JBLabel label && label.getIcon() instanceof Icon icon) { width += icon.getIconWidth(); height = Math.max(height, icon.getIconHeight()); } + else if (arrowLabel == null) { + // Fallback: use the default chevron down icon size + Icon defaultArrow = IconUtil.scale(AllIcons.General.ChevronDown, null, 1.2f); + width += defaultArrow.getIconWidth(); + height = Math.max(height, defaultArrow.getIconHeight()); + } width += JBUI.scale(24); height += JBUI.scale(8); @@ -286,11 +309,11 @@ public void projectClosing(@NotNull Project project) { text = FlutterBundle.message("devicelist.loading"); } else { - text = ""; + text = FlutterBundle.message("devicelist.noDevices"); } } else if (selectedDevice == null) { - text = ""; + text = FlutterBundle.message("devicelist.noDeviceSelected"); } else { text = selectedDevice.presentationName();