Toolbar bug

When I drag and drop some button in toolbar,sometimes throw below exception

Exception in thread “AWT-EventQueue-0” java.lang.ArrayIndexOutOfBoundsException: 2
at bibliothek.gui.dock.station.toolbar.group.ToolbarGroupSpanStrategy.getLine(Unknown Source)
at bibliothek.gui.dock.station.toolbar.layout.ToolbarGridLayoutManager.layoutSize(Unknown Source)
at bibliothek.gui.dock.station.toolbar.layout.ToolbarGridLayoutManager.layoutSize(Unknown Source)
at bibliothek.gui.dock.station.toolbar.layout.ToolbarGridLayoutManager.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at java.awt.BorderLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at bibliothek.gui.dock.ToolbarGroupDockStation$OverpaintablePanelBase.getPreferredSize(Unknown Source)
at java.awt.GridLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at bibliothek.gui.dock.themes.basic.DisplayerContentPane.getPreferredSize(DisplayerContentPane.java:111)
at java.awt.GridLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at java.awt.GridLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at java.awt.BorderLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at bibliothek.gui.dock.station.OverpaintablePanel.getPreferredSize(OverpaintablePanel.java:194)
at java.awt.GridLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at javax.swing.JRootPane$RootLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at java.awt.BorderLayout.preferredLayoutSize(Unknown Source)
at java.awt.Container.preferredSize(Unknown Source)
at java.awt.Container.getPreferredSize(Unknown Source)
at bibliothek.gui.dock.station.screen.window.ResizingLayoutManager.layoutContainer(ResizingLayoutManager.java:61)
at java.awt.Container.layout(Unknown Source)
at java.awt.Container.doLayout(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validate(Unknown Source)
at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Neither Herve nor I ever saw this exception. Do you have any ideas on how to reproduce it? For example:

  • Has the toolbar always the same layout when the exception happens?
  • Is the origin of the button and the target toolbar the same?
  • Does it happen when the application started, or when the application has run for a while?
  • Do you see the bug when doing drag and drop the first time? Or only when doing DnD the first time?

Hi Beni, the above exception doesn’t happen the first time doing drag and drop .
When the application started, drag and drop some button to other toolbar from one toolbar, sometimes happen,but often see when fast drag and drop.
I have an example similar the exception,it happen when the application initialization.
If “show()” function at “initToolbar()” after execute in “init()”, no exception happen.

In addition,new a dockable in workArea run File menu->new,when close the dockable,toolbar auto hide.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.CLocation;
import bibliothek.gui.dock.common.CWorkingArea;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.action.CButton;
import bibliothek.gui.dock.toolbar.CToolbarContentArea;
import bibliothek.gui.dock.toolbar.CToolbarItem;
import bibliothek.gui.dock.toolbar.expand.ExpandedState;
import bibliothek.gui.dock.toolbar.location.CToolbarAreaLocation;

import tutorial.support.ColorIcon;
import tutorial.support.JTutorialFrame;

public class BugExample {
	
	public JTutorialFrame frame = null;
	public CControl control = null;
	public CToolbarContentArea contentArea = null;
	public CWorkingArea workArea = null;
	
	public JMenuBar mainMenuBar = null;
	
	public void init(){
		mainMenuBar = getMainMenuBar();
		
		initFrameController();
		show();
		initToolbar();
	}
	
	public void show(){
		frame.setTitle("Example");
		frame.setJMenuBar(mainMenuBar);

		frame.setSize(800, 600);
		frame.setVisible( true );
	}
	
	public JMenuBar getMainMenuBar(){
		if(mainMenuBar == null){
			mainMenuBar = new JMenuBar();
	    	JMenuItem mi;

	    	JMenu file = (JMenu) mainMenuBar.add(new JMenu("File(F)"));
	        file.setMnemonic('F');

	        mi = (JMenuItem) file.add(new JMenuItem());
	        mi.setText("New" + "(N)");
	        mi.setMnemonic('N');
	      	mi.addActionListener(new ActionListener() {
	      		public int count = 0;
	      		public void actionPerformed(ActionEvent e){
	      			DefaultSingleCDockable dockable = new DefaultSingleCDockable( String.valueOf(count++), "new file" );
	      			dockable.setCloseable(true);
	      			dockable.setMinimizable(false);
	      			dockable.add( new JPanel()); 
	      			workArea.show( dockable );
	      		}
	      	});
	      	
	        mi = (JMenuItem) file.add(new JMenuItem());
	        mi.setText("Exit" + "(C)");
	        mi.setMnemonic('C');
	      	mi.addActionListener(new ActionListener() {
	      		public void actionPerformed(ActionEvent e){
	      			System.exit(0);
	      		}
	      	});
		}
		
		return mainMenuBar;
	}
	
	private void initFrameController(){
		frame = new JTutorialFrame( DockFrame1.class );
        control = new CControl( frame );
        frame.destroyOnClose( control );
        contentArea = new CToolbarContentArea( control, "base" );
        
        control.addStationContainer( contentArea );
        frame.add( contentArea );
		
        workArea = control.createWorkingArea( "work" );
        CGrid grid = new CGrid( control );
        grid.add( 0, 0, 1, 1, workArea);
        contentArea.getCenterArea().deploy(grid);
	}
	
	public void initToolbar(){
        Icon red = new ColorIcon( Color.RED );
        Icon green = new ColorIcon( Color.GREEN );
        
        CToolbarAreaLocation north = contentArea.getNorthToolbar().getStationLocation();
        
        add( control, "A", red,   north.group( 0 ).toolbar( 0, 0 ).item( 0 ) );
        add( control, "B", red,   north.group( 0 ).toolbar( 0, 0 ).item( 1 ) );
        add( control, "C", red,   north.group( 0 ).toolbar( 0, 0 ).item( 2 ) );
        
        add( control, "D", green, north.group( 0 ).toolbar( 0, 1 ).item( 0 ) );
        add( control, "E", green, north.group( 0 ).toolbar( 0, 1 ).item( 1 ) );
        add( control, "F", green, north.group( 0 ).toolbar( 0, 1 ).item( 2 ) );
	}
	
    private static void add( CControl control, String id, Icon icon, CLocation location ){
        String text = id + id.toLowerCase() + id.toLowerCase() + id.toLowerCase(); 
        
        CToolbarItem item = new CToolbarItem( id );
        item.intern().setTitleText( text );
        
        item.setItem( new CButton( null, icon ) );
        item.setItem( new JButton( text, icon ), ExpandedState.STRETCHED );
          
        item.setLocation( location );
        control.addDockable( item );
        item.setVisible( true );
    }
    
    public static void main(String[] args){
    	BugExample frame = new BugExample();
    	frame.init();
    }
}```

I’ll continue searching your first exception, but I won’t make any promises about finding it…

I have an example similar the exception,it happen when the application initialization.
If „show()“ function at „initToolbar()“ after execute in „init()“, no exception happen.

That is a mistake in the client: the framework does not support multi-threading. But by calling „show“ the application starts the EDT (EventDispatcherThread), after that the modifications executed in the main-Thread concurrently mix with the operations from the EDT, creating race conditions. The framework can do almost nothing to fix these exceptions (fixing them would triple the amount of code), so the client has to make all modifications of the GUI in the EDT (you may use „EventDispatcher.invokeLater/invokeAndWait“ to do so).

In addition,new a dockable in workArea run File menu->new,when close the dockable,toolbar auto hide.

I’ll upload a fixed version within the next 12 hours. That is a bug of some code that prevents modes like „maximized“ to create a chaos while hiding a Dockable.

[Edit: I have to admit, most testing was going in the „core toolbar extension“, the Common part is still very much an alpha version.]

[Edit2:

but often see when fast drag and drop

Thanks, that did the trick. But on my machine I have to be really fast, basically just randomly clicking the mouse is the only way to get the exception. I should be able to fix it now.]

The reason behind the exception is an optimization: a LayoutManager caches some data so it does not have to calculate the same stuff over and over again. The cache is cleared if the layout is invalidated. But if you are really fast there are two passes through the LayoutManager, a first one with the old data, then an invalidation, and then another pass. Needless to say, the first pass fails because of the outdated data.

Will be fixed in the next version.

A new version, 1.1.1p8d is online, it contains the two bugfixes.

Thank you very much for reporting these bugs, the one with the disappearing toolbars was a really stupid mistake from me. Please download the new version, and let me know immediately if you run in any more troubles.

Thank you very mach for provide a fixed version,expect last Version1.1.1 to release!