This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 225160

Summary: Can't use custom JTabbedPane when the Bean Info containerDelegate is setted
Product: guibuilder Reporter: davide.garcia
Component: CodeAssignee: issues@guibuilder <issues>
Status: NEW ---    
Severity: normal    
Priority: P4    
Version: 7.2.1   
Hardware: PC   
OS: Windows 7   
Issue Type: DEFECT Exception Reporter:
Attachments: An example project with to test the issue

Description davide.garcia 2013-01-22 00:29:54 UTC
Created attachment 130473 [details]
An example project with to test the issue

1. Create a custom JTabbedPane
1.1 Add a new Tab, for example a JPanel (The delegated Pane)
2. Create a bean info including: containerDelegate descrition
3. Add this custom JTabbedPane to a new Form in any project with the GUI builder
4. Add any component (JLabel, JTextField, etc) in the Custom JTabbedPane. The gui builder do nothing, probably an Exception occurs:

INFO: Index: 1, Size: 0
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
	at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:612)
	at java.util.ArrayList.add(ArrayList.java:426)
	at org.netbeans.modules.form.RADVisualContainer.add(RADVisualContainer.java:416)
	at org.netbeans.modules.form.FormModel.addVisualComponent(FormModel.java:463)
[catch] at org.netbeans.modules.form.MetaComponentCreator.addVisualComponent2(MetaComponentCreator.java:973)
	at org.netbeans.modules.form.MetaComponentCreator.access$500(MetaComponentCreator.java:79)
	at org.netbeans.modules.form.MetaComponentCreator$3.run(MetaComponentCreator.java:353)
	at org.netbeans.modules.form.FormLAF$3.run(FormLAF.java:322)
	at org.openide.util.Mutex.doEventAccess(Mutex.java:1363)
	at org.openide.util.Mutex.readAccess(Mutex.java:273)
	at org.netbeans.modules.form.FormLAF.executeWithLookAndFeel(FormLAF.java:305)
	at org.netbeans.modules.form.MetaComponentCreator.addPrecreatedComponent(MetaComponentCreator.java:350)
	at org.netbeans.modules.form.HandleLayer$NewComponentDrag.end(HandleLayer.java:3411)
	at org.netbeans.modules.form.HandleLayer$NewComponentDropListener.drop(HandleLayer.java:3615)
	at java.awt.dnd.DropTarget.drop(DropTarget.java:450)
	at sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:537)
	at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:851)
	at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:775)
	at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
	at java.awt.Component.dispatchEventImpl(Component.java:4716)
	at java.awt.Container.dispatchEventImpl(Container.java:2287)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
	at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4566)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4417)
	at java.awt.Container.dispatchEventImpl(Container.java:2273)
	at java.awt.Window.dispatchEventImpl(Window.java:2719)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:703)
	at java.awt.EventQueue.access$000(EventQueue.java:102)
	at java.awt.EventQueue$3.run(EventQueue.java:662)
	at java.awt.EventQueue$3.run(EventQueue.java:660)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.awt.EventQueue$4.run(EventQueue.java:676)
	at java.awt.EventQueue$4.run(EventQueue.java:674)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:673)
	at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:158)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

I attach a project example

public class ExtendedTabbedPanel extends JTabbedPane{
    Container contentPane = new JPanel();  
    public ExtendedTabbedPanel(){
        addTab("Test", contentPane);
    }
    public Container getContentPane(){
        return contentPane;
    }
}

public class ExtendedTabbedPanelBeanInfo extends SimpleBeanInfo{
    @Override
    public BeanDescriptor getBeanDescriptor() {
        BeanDescriptor beanDescriptor = new BeanDescriptor( ExtendedTabbedPanel.class , null ); // NOI18N                              
        beanDescriptor.setValue("containerDelegate", "getContentPane");
        beanDescriptor.setValue("isContainer", Boolean.TRUE);
        return beanDescriptor;
    }
}
Comment 1 Tomas Pavek 2013-01-22 18:19:20 UTC
I guess the GUI builder is confused by that the class is a JTabbedPane which is normally a special container with dedicated support for the tabs.

Possible workaround: If you really want a component that looks like a tabbed pane with only one tab that should not work as tabbed pane but as a container with the tab being the only container delegate, then perhaps create your custom component class as a JPanel subclass which contains the tabbed pane. Why to expose the component as JTabbedPane if it should not be treated as such?
Comment 2 davide.garcia 2013-01-22 19:17:13 UTC
The example have only a testing purpose. But the idea is: 

Have a panel to add any JComponent in the first tab.

One or more tabs that are generated dynamically based in the components at the delegated panel.

At runtime, the user can navigate in the delegated panel (a Form), and get extra information in the other panels.
Comment 3 Tomas Pavek 2013-01-23 10:12:01 UTC
This is what I meant as the workaround which works fine in the GUI builder:

public class ExtendedTabbedPanel extends JPanel {
    JTabbedPane tabbedPane = new JTabbedPane();
    Container contentPane = new JPanel();
    public ExtendedTabbedPanel() {
        super(new BorderLayout());
        add(tabbedPane, BorderLayout.CENTER);
        tabbedPane.addTab("Test", contentPane);
    }
    public Container getContentPane(){
        return contentPane;
    }
}
Comment 4 davide.garcia 2013-01-24 00:37:36 UTC
(In reply to comment #3)
> This is what I meant as the workaround which works fine in the GUI builder:
> 
> public class ExtendedTabbedPanel extends JPanel {
>     JTabbedPane tabbedPane = new JTabbedPane();
>     Container contentPane = new JPanel();
>     public ExtendedTabbedPanel() {
>         super(new BorderLayout());
>         add(tabbedPane, BorderLayout.CENTER);
>         tabbedPane.addTab("Test", contentPane);
>     }
>     public Container getContentPane(){
>         return contentPane;
>     }
> }

This workaround works for me. Thanks