Tab selection when dragging a minimized tab to a stack containing only one dockable

Hello,

I’ve noticed some peculiar behavior around dragging minimized tabs to an existing stack containing only one item. If there’s only one tab, the preexisting tab retains the focus after drop. If there are more than one, the dropped tab is shown/selected/focused. I’m not sure if its the intended behavior or not. This only happens if there is a single dockable in the stack, and only if you are adding a tab to the left of the existing tab.

[ol]
[li]Start the UI with some minimized dockables, and one showing normally. The showing dockable is selected.
[/li]
[li]Drag one of the minimized dockables to the showing dockable, so it will be placed to the left of the showing dockable in the stack (just below the caret in the title in my example
[/li]
[li]Drop the tab and it’ll be selected, then things will shuffle, selecting the original dockable and hiding the dragged dockable behind.
[/li]
[li]Repeat the same drag for the other minimized dockable(s) and note that they get focus/selection on drop.
[/li]
[/ol]

Here’s a quick example that reproduces it.


import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.SingleCDockable;
import bibliothek.gui.dock.common.SingleCDockableFactory;
import bibliothek.gui.dock.common.perspective.CControlPerspective;
import bibliothek.gui.dock.common.perspective.CGridPerspective;
import bibliothek.gui.dock.common.perspective.CMinimizePerspective;
import bibliothek.gui.dock.common.perspective.CPerspective;
import bibliothek.gui.dock.common.perspective.SingleCDockablePerspective;
import bibliothek.gui.dock.common.theme.ThemeMap;
import bibliothek.util.Filter;

public class TabSelectionBug
{
	private static final String LITTLE_GUY_TITLE = "Drag me!";
	private static final String BIG_GUY_TITLE = "^ Drag a tab to the caret";
	CControl mainControl;

	public void show()
	    throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
	{
		UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

		JFrame frame = new JFrame();
		mainControl = new CControl(frame);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		TitleLabelFactory factory = new TitleLabelFactory();
		mainControl.addSingleDockableFactory(factory, factory);
		frame.setLayout(new GridLayout(1, 1));
		frame.add(mainControl.getContentArea());

		CControlPerspective controlPerspectives = mainControl.getPerspectives();
		CPerspective perspective = controlPerspectives.createEmptyPerspective();

		CGridPerspective center = perspective.getContentArea().getCenter();
		CMinimizePerspective west = perspective.getContentArea().getWest();

		center.gridAdd(0, 0, 600, 400, new SingleCDockablePerspective(BIG_GUY_TITLE));

		//add as many as you want here...
		west.add(new SingleCDockablePerspective(LITTLE_GUY_TITLE));
		west.add(new SingleCDockablePerspective(LITTLE_GUY_TITLE + 2));

		mainControl.setTheme(ThemeMap.KEY_ECLIPSE_THEME);
		controlPerspectives.setPerspective("main", perspective);
		mainControl.load("main");

		frame.setBounds(10, 10, 600, 400);
		frame.setVisible(true);
	}

	public static void main(String[] args)
	    throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
	{
		TabSelectionBug thing = new TabSelectionBug();
		thing.show();
	}

	private class TitleLabelFactory
	    implements SingleCDockableFactory, Filter<String>
	{
		@Override
		public boolean includes(String arg0)
		{
			return true;
		}

		@Override
		public SingleCDockable createBackup(String title)
		{
			return new DefaultSingleCDockable(title, title, new JTextArea(new StringBuffer(title).reverse().toString()));
		}
	}
}```

I'm also investigating an issue related to this in which tabs can end up selected, but not on the top of the stack, requiring the user to click away from, then back to the tab to actually focus/show it:


Like the other issue, this only ever happens if there is only one item in the stack to begin with, and you're adding the new dockable to the 0th position. Adding to the right of a single-item stack, or to the 0th position of a greater-than-one-item stack behaves like I'd expect.

Unfortunately, I'm only able to reproduce the second issue when it involves a ton of heavier UI items inside of the dockables. If I can get an example of how to reproduce it in a simple case, I'll add it here.

Thanks!

-amish

I’ve figured out what’s causing the focus issue. I’d been setting the focus component in my custom dockable constructor. If you replace createBackup from above with the following code, it’ll reproduce the tab hiding issue that brought all of this up in the first place.

		@Override
		public SingleCDockable createBackup(String title)
		{
			JTextArea jTextArea = new JTextArea(new StringBuffer(title).reverse().toString());
			DefaultSingleCDockable defaultSingleCDockable = new DefaultSingleCDockable(title, title, jTextArea);
			defaultSingleCDockable.setFocusComponent(jTextArea);
			return defaultSingleCDockable;
		}

I can work around the tab hiding by not setting the focus component, but the weird selection issue described in my first post is still there.

thanks,

-amish

Sorry, I did not see this thread - completely missed it. I’ll try to reproduce this bug and fix it if possible. But this could take a while, because right now I am working on other stuff (not related to the framework) and this is not a bug that will completely stop your application from working.

Yup. Just a weird quirk. Thanks for the reply.