I tried to create an application reproducing the bug after your description (see code below), but it did not freeze. Do you see any Component or piece of code missing to perform the steps you described? By the way, thanks for the screenshots.
If you focus a Dockable, the framework tries to focus a child Component of that Dockable by force. But the algorithm does not try more than 20 times (with a pause of 10 milliseconds between each attempt) to set the focus. As a result, after 200 milliseconds the framework stops playing around with focus - this does not explain the 3-5 seconds of freezing you see.
About “setPreventFocusStealing”: you mean ScreenDockWindow.setPreventFocusStealing? That only affects floating (externalized) dockables. It is called when the owner window of a ScreenDockStation changes, in this case for a short amount of time all windows are made invisible and recreated. Making the windows visible again causes Swing to automatically transfer focus, unless prevented by calling Window.setFocusableWindowState. But applications should not call this method.
Other than that I can only ask the same questions Marco already did.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
public class FreezeIssueTest {
public static void main( String[] args ){
JFrame frame = new JFrame( "Freeze" );
CControl control = new CControl( frame );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setBounds( 20, 20, 400, 400 );
frame.add( control.getContentArea() );
final PersonDockable person = new PersonDockable();
final SearchDockable search = new SearchDockable( person );
control.addDockable( person );
control.addDockable( search );
search.setVisible( true );
JPanel topPanel = new JPanel( new GridLayout( 1, 2 ) );
JButton open = new JButton( "Open results" );
topPanel.add( open );
topPanel.add( new JButton( "No action" ) );
frame.add( topPanel, BorderLayout.NORTH );
open.addActionListener( new ActionListener(){
@Override
public void actionPerformed( ActionEvent e ){
search.openResult();
}
});
frame.setVisible( true );
}
private static class SearchDockable extends DefaultSingleCDockable{
private PersonDockable searchResult;
public SearchDockable( PersonDockable result ){
super( "search" );
setTitleText( "Traitement des évènements" );
this.searchResult = result;
JTextField idField = new JTextField();
JButton okButton = new JButton( "Ok" );
setLayout( new GridBagLayout() );
Insets insets = new Insets( 1, 1, 1, 1 );
add( new JLabel("Id"), new GridBagConstraints( 0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0 ) );
add( idField, new GridBagConstraints( 1, 0, 1, 1, 5.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0 ) );
add( okButton, new GridBagConstraints( 0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, insets, 0, 0 ));
okButton.addActionListener( new ActionListener(){
@Override
public void actionPerformed( ActionEvent e ){
openResult();
}
});
}
public void openResult(){
searchResult.setLocation( getBaseLocation().aside() );
searchResult.setVisible( true );
}
}
private static class PersonDockable extends DefaultSingleCDockable{
public PersonDockable(){
super( "test person" );
setTitleText( "Personne Morale" );
setCloseable( true );
JTabbedPane content = new JTabbedPane();
add( content, BorderLayout.CENTER );
JPanel general = new JPanel( new GridLayout( 2, 2 ));
general.add( new JLabel( "No" ) );
general.add( new JTextField() );
general.add( new JLabel( "Name" ) );
general.add( new JTextField() );
content.addTab( "Tab 1", general );
}
}
}