Behaviour of keyboard shortcuts on nested dock stations

Hi,

I’m experiencing some somewhat unexpected behaviour when using keyboard shortcuts to maximise, minimise, externalise and normalise tabs. I’m just wondering whether you might be able to help me understand why I am experiencing the behaviour and if it would be possible to alter it.

My application is laid out as in the picture below. There is a SecureSplitDockStation (shown in yellow) which contains a DefaultSingleCDockable used as a menu to launch other tabs (DefaultMultipleCDockables) in another SecureSplitDockStation (shown in orange) to the right of the menu tab.

If I use the maximize option in the menu of tab 2 (shown in blue), for example, it expands to fill up the orange station but if I use the keyboard shortcut while focused on this tab it maximises the orange station to fill the yellow station.

The other shortcuts similarly are all applied to the orange station as opposed to the relevant tab/StackDockStation.

Would you think that it would be expected that the shortcuts would work like this or do you know if there’s a way I can ensure that they are applied to the correct Dockable so that the shortcuts behave the same way as if you had used the menu on the focused tab?

Any help would be greatly appreciated.

Thanks

It’s a bug of the framework, the key-event is first received by the parent instead of the children. I’ll change that for the next release.

btw. nice drawing :slight_smile:

Independent from that, I would suggest you use the Common project for this kind of application. Because Common has some features that were explicitly designed to work in the way how you described your application. For example in Common the orange station will never disappear if it has only one child left, nor will the user have the option to mix the menu-dockable with the other dockables.

As an example how the code look like:


import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

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;

public class TabTest2 {
	public static void main( String[] args ){
		JFrame frame = new JFrame( "Test" );
		CControl control = new CControl( frame );
		
		frame.add( control.getContentArea() );
		
		CWorkingArea work = control.createWorkingArea( "work" );
		work.setVisible( true );
		work.setMaximizingArea( true );
		
		DefaultSingleCDockable menu = new DefaultSingleCDockable( "menu", "Menu",  new JScrollPane( new JTextArea() ) );
		menu.setLocation( CLocation.base().normal().west( 0.25 ) );
		control.addDockable( menu );
		menu.setVisible( true );
		
		CGrid grid = new CGrid( control );
		grid.add( 0, 0, 1, 1, new DefaultSingleCDockable( "work 1", "Work 1", new JScrollPane( new JTextArea() ) ) );
		grid.add( 0, 1, 1, 1, new DefaultSingleCDockable( "work 2", "Work 2", new JScrollPane( new JTextArea() ) ) );
		work.deploy( grid );
		
		frame.setBounds( 20, 20, 400, 400 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setVisible( true );
	}
}

Hi Beni,

Thanks for the reply (and liking my drawing :slight_smile: ).

Do you know if it would be a large undertaking for me to modify this behaviour in my current version? I believe we have a somewhat old version here at the moment.

Thanks for the suggestion and the code, I’ll bear it in mind and have another look at my application.

Thanks

You would need to modify the code of the framework itself. Fixing this from outside is nigh impossible. Well, the source is available…

Search for a class called “LocatedListenerList”, and then for the method “affected”. If neither of these exists, then you have a really old version, and I would need to know the version number (can be found in the “changes.txt” file). You see there is an anonymous Comparator in this method. Replace every “return 1” by “return -1” and every “return -1” by “return 1” to change the order of the items. That’s it.

But if you have an option to make an update, I would do so. I’ll upload the fixed version this weekend (there are some other changes which need testing before that).

I’m not sure that we are in a position to update our version here, I’d have to run it by some people.

I found the class you mentioned and I changed the return values as you suggested, I can see the changes were taken, but it didn’t seem to have any effect on the behaviour.

That is strange, because when I fixed it in the current version I did nothing else. Hm, which version exactly do you use? And you are certain your application uses the new class files (no old *.jar files hanging around?).

I believe we are at version 1.0.8.

Yeah, I saw the updated jar being used when I started up my application. The only thing that seems to have changed is that if I use the externalise shortcut the area now seems to be bigger when externalised than it used to be.

I’ve installed 1.0.8, but the fix worked there. Hm, are there any elements on your Dockables that can have the focus? Because if not, then the KeyEvent is sent to some other Component, even if you clicked with the mouse on the Dockable.That’s part of the design of Swing, I would not be able to change that.

Ah. That’s interesting.

The tabs would all have some somewhat complex guis in them alright but I think that as far as the framework is concerned the selected dockable would have focus. Do you think having these screens inside the dockables could be causing my issue?

Please run the application below, just to make sure the fix was applied correctly. At least on my version this behaves as expected.

Just to clarify: as long as there are any textfields, buttons, checkboxes or any other Component with the “focusable” property set to “true”, it should focused when you click anywhere on the dockable. But if you click on a Dockable the framework always will mark it (different title color, etc.), even if Swing itself does not transfer focus.


import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import bibliothek.gui.DockController;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.station.split.SplitDockProperty;

public class TabTest1 {
	public static void main( String[] args ){
		JFrame frame = new JFrame( "Test" );
		
		DockController controller = new DockController();
		controller.setRootWindow( frame );
		
		SplitDockStation root = new SplitDockStation();
		controller.add( root );
		frame.add( root );
		
		SplitDockStation work = new SplitDockStation();
		work.drop( new DefaultDockable( new JScrollPane( new JTextArea() ), "Work 1" ) );
		work.drop( new DefaultDockable( new JScrollPane( new JTextArea() ), "Work 2" ), SplitDockProperty.SOUTH );
		root.drop( work );
		
		root.drop( new DefaultDockable( new JScrollPane( new JTextArea() ), "Menu" ), SplitDockProperty.WEST );
		
		frame.setBounds( 20, 20, 400, 400 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setVisible( true );
	}
}

I ran the application you provided and the menu based maximising performs the same as what I currently have but as there were no keyboard shortcuts set up I wasn’t able to test whether the fix had been correctly applied.

I’m not certain, but is there some kind of misunderstanding? Because I’m talking about the ctrl+m shortcut that is provided by the framework, and does work on my machine.

Yes, that is the shortcut I am talking about too. It had no effect when I ran the code you gave me. Perhaps there is something stopping it on my side. I’ll have to take a look and see.