Skip to content

Commit 2eb57de

Browse files
committed
Fix NPE in JTabbedPaneInfo if tab-item bounds are null #1509
Depending on the UI (which is determined by the current LookAndFeel), the call to `getBoundsAt(int)` may return null. Such tabs must be removed from the model. Closes #1509
1 parent 7abebf4 commit 2eb57de

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

org.eclipse.wb.swing/src/org/eclipse/wb/internal/swing/model/component/JTabbedPaneInfo.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2011 Google, Inc.
2+
* Copyright (c) 2011, 2026 Google, Inc. and others.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License 2.0 which is available at
@@ -145,16 +145,19 @@ protected void refresh_afterCreate() throws Exception {
145145
{
146146
int tabCount = pane.getTabCount();
147147
for (int i = tabCount - 1; i >= 0; i--) {
148-
if (pane.getComponentAt(i) == null) {
148+
if (pane.getComponentAt(i) == null || pane.getBoundsAt(i) == null) {
149149
pane.remove(i);
150150
}
151151
}
152152
}
153153
// apply active component
154154
{
155-
ComponentInfo activeComponent = getActiveComponent();
156-
if (activeComponent != null) {
157-
pane.setSelectedComponent(activeComponent.getComponent());
155+
ComponentInfo activeComponentInfo = getActiveComponent();
156+
if (activeComponentInfo != null) {
157+
Component activeComponent = activeComponentInfo.getComponent();
158+
if (activeComponent != null && pane.indexOfComponent(activeComponent) != -1) {
159+
pane.setSelectedComponent(activeComponent);
160+
}
158161
}
159162
}
160163
}

org.eclipse.wb.tests/src/org/eclipse/wb/tests/designer/swing/model/component/JTabbedPaneTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,43 @@ class Test extends JPanel {
176176
Assertions.assertThat(tabbed.getTabs()).isEmpty();
177177
}
178178

179+
/**
180+
* @see <a href="https://github.com/eclipse-windowbuilder/windowbuilder/issues/1509">here</a>
181+
*/
182+
@Test
183+
public void test_invisibleTab() throws Exception {
184+
setFileContentSrc("test/AlwaysNullTabbedPaneUI.java", getTestSource("""
185+
import javax.swing.plaf.basic.BasicTabbedPaneUI;
186+
class AlwaysNullTabbedPaneUI extends BasicTabbedPaneUI {
187+
@Override
188+
public Rectangle getTabBounds(JTabbedPane pane, int index) {
189+
return null;
190+
}
191+
}
192+
"""));
193+
waitForAutoBuild();
194+
ContainerInfo panel = parseContainer("""
195+
class Test extends JPanel {
196+
Test() {
197+
JTabbedPane tabbed = new JTabbedPane() {
198+
public void repaint(Rectangle r) {
199+
if (r != null) {
200+
super.repaint(r);
201+
}
202+
}
203+
};
204+
add(tabbed);
205+
tabbed.addTab("Tab ", new JLabel());
206+
tabbed.setUI(new AlwaysNullTabbedPaneUI());
207+
}
208+
}""");
209+
refresh();
210+
JTabbedPaneInfo tabbed = (JTabbedPaneInfo) panel.getChildrenComponents().get(0);
211+
assertNoErrors(panel);
212+
// ask tabs
213+
Assertions.assertThat(tabbed.getTabs()).isEmpty();
214+
}
215+
179216
/**
180217
* {@link JTabbedPane} can have more tabs that number of {@link ComponentInfo}s which we see.
181218
*/

0 commit comments

Comments
 (0)