All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bibliothek.gui.dock.control.DockableSelector Maven / Gradle / Ivy

The newest version!
/*
 * Bibliothek - DockingFrames
 * Library built on Java/Swing, allows the user to "drag and drop"
 * panels containing any Swing-Component the developer likes to add.
 * 
 * Copyright (C) 2007 Benjamin Sigg
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Benjamin Sigg
 * [email protected]
 * CH - Switzerland
 */
package bibliothek.gui.dock.control;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;

import javax.swing.JDialog;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;

import bibliothek.gui.DockController;
import bibliothek.gui.DockTheme;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.control.focus.DefaultFocusRequest;
import bibliothek.gui.dock.focus.DockableSelection;
import bibliothek.gui.dock.focus.DockableSelectionListener;
import bibliothek.gui.dock.util.DockProperties;
import bibliothek.gui.dock.util.PropertyKey;
import bibliothek.gui.dock.util.PropertyValue;

/**
 * A {@link DockableSelector} is able to open a popup when the user hits a special
 * combination of keys. The popup uses a {@link DockableSelection} to present
 * the user different {@link Dockable}s from which he can choose one to become focused.
 * @author Benjamin Sigg
 */
public class DockableSelector {
    /** key for the {@link DockProperties}, telling which {@link KeyStroke} activates the selection */
    public static final PropertyKey INIT_SELECTION = 
        new PropertyKey( "dockable selector init selection keystroke" );
    
    /** the currently active keystroke */
    private PropertyValue initSelection = new PropertyValue( INIT_SELECTION ){
        @Override
        protected void valueChanged( KeyStroke oldValue, KeyStroke newValue ) {
             // ignore   
        }
    };
    
    /** listens to keyboard and to {@link DockableSelection} */
    private Listener listener = new Listener();
    
    /** The currently observed controller */
    private DockController controller;
    
    /** the selection which is currently used */
    private DockableSelection selection;
    
    /** the dialog which shows the selection */
    private JDialog dialog;
    
    /**
     * Sets the controller which should be observed.
     * @param controller the currently observed controller
     */
    public void setController( DockController controller ){
        cancel();
        
        if( this.controller != null ){
            this.controller.getKeyboardController().removeGlobalListener( listener );
        }
        
        this.controller = controller;
        initSelection.setProperties( controller );
        
        if( this.controller != null ){
            this.controller.getKeyboardController().addGlobalListener( listener );
        }
    }
    
    /**
     * Opens the popup window if possible and allows the user the choice between different 
     * {@link Dockable}s.
     */
    public void select(){
    	if( !isOpen() ){
	        cancel();
	        open();
    	}
    }
    
    /**
     * Tells whether the window is shown to the user right now.
     * @return whether the window is visible
     */
    public boolean isOpen(){
    	return selection != null && dialog != null && dialog.isVisible();
    }
    
    /**
     * Closes the currently open popup window without changing the focused {@link Dockable}
     */
    public void cancel(){
        close();
    }
    
    /**
     * Close the currently open popup window and changes the focused
     * {@link Dockable} to dockable.
     * @param dockable the element that will own the focus
     */
    public void stop( Dockable dockable ){
        close();
        controller.setFocusedDockable( new DefaultFocusRequest( dockable, null, false ));
    }
    
    private void open(){
        selection = controller.getProperties().get( DockTheme.DOCKABLE_SELECTION );
        if( selection != null && selection.hasChoices( controller )){
            Window root = controller.findRootWindow();
            if( dialog == null || dialog.getOwner() != root ){
                if( dialog != null )
                    dialog.dispose();
                
                if( root instanceof Frame )
                    dialog = new JDialog( (Frame)root, false );
                else if( root instanceof Dialog )
                    dialog = new JDialog( (Dialog)root, false );
                else{
                    dialog = new JDialog();
                    dialog.setModal( false );
                }
                
                dialog.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );
                dialog.setUndecorated( true );
                dialog.getRootPane().setWindowDecorationStyle( JRootPane.NONE );
                dialog.setLayout( new BorderLayout() );
            }
            
            dialog.addWindowFocusListener( listener );
            selection.open( controller );
            final Component base = selection.getComponent();
            dialog.add( base, BorderLayout.CENTER );
            
            dialog.pack();
            dialog.setLocationRelativeTo( root );
            
            selection.addDockableSelectionListener( listener );
            
            base.requestFocusInWindow();
            dialog.setVisible( true );
        }
        else
            selection = null;
    }
    
    private void close(){
        if( dialog != null ){
            if( selection != null ){
                dialog.removeWindowFocusListener( listener );
                selection.removeDockableSelectionListener( listener );
                selection.close();
                selection = null;
            }
            
            dialog.setVisible( false );
            dialog.getContentPane().removeAll();
        }   
    }
    
    /**
     * A listener that triggers the {@link DockableSelector} and that observes
     * the active {@link DockableSelection}.
     * @author Benjamin Sigg
     */
    private class Listener implements KeyListener, DockableSelectionListener, WindowFocusListener{
        public void keyPressed( KeyEvent event ) {
            if( event.isConsumed() )
                return;
            
            if( KeyStroke.getKeyStrokeForEvent( event ).equals( initSelection.getValue() )){
                select();
                event.consume();
            }
        }
        
        public void keyReleased( KeyEvent event ) {
            if( event.isConsumed() )
                return;
            
            if( KeyStroke.getKeyStrokeForEvent( event ).equals( initSelection.getValue() )){
                select();
                event.consume();
            }
        }

        public void keyTyped( KeyEvent event ) {
            if( event.isConsumed() )
                return;
            
            if( KeyStroke.getKeyStrokeForEvent( event ).equals( initSelection.getValue() )){
                select();
                event.consume();
            }
        }
        
        public void windowGainedFocus( WindowEvent e ) {
            // ignore
        }
        
        public void windowLostFocus( WindowEvent e ) {
            if( selection != null )
                cancel();
        }

        public void canceled() {
            cancel();
        }

        public void considering( Dockable dockable ) {
            // ignore
        }

        public void selected( Dockable dockable ) {
            stop( dockable );
        }
        
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy