Package com.mucommander.ui.button

Source Code of com.mucommander.ui.button.ButtonChoicePanel

/*
* This file is part of muCommander, http://www.mucommander.com
* Copyright (C) 2002-2012 Maxence Bernard
*
* muCommander is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* muCommander 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


package com.mucommander.ui.button;

import com.mucommander.ui.helper.MnemonicHelper;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


/**
* ButtonChoicePanel lays out an array of buttons on a grid and provides an easy way
* for the user to navigate and select buttons :
* <ul>
<li>At any given time, the current active button (the first one initially) can be selected by pressing ENTER
<li>LEFT key goes back to the previous button, to the last button if current button is the first one
<li>RIGHT key goes forward one button, to the first button if current button is the last one
<li>UP key goes up one row, to the last row if current button is on the first row
<li>DOWN key goes down one row, to the first row if current button is on the last row
<li>Buttons can directly be selected by pressing the Mnemonic associated with the button (if any)
* </ul>
* This does not interfere with regular focus management where TAB (resp. Shift+TAB) goes to the next (resp. previous)
* focusable component.
*
* @author Maxence Bernard
*/
public class ButtonChoicePanel extends JPanel implements KeyListener, FocusListener {

    /** Provided JButton instances */
    private JButton buttons[];
 
    /** RootPane associated with this ButtonChoicePanel */
    private JRootPane rootPane;

    /** Number of columns of the buttons grid */
    private int nbCols;
    /** Number of row of the buttons grid */
    private int nbRows;

    /** Current button, i.e. the one that currently has focus */
    private int currentButton;
 
    /** Total number of buttons */
    private int nbButtons;

 
    /**
     * Creates a new ButtonChoicePanel and lays out the given buttons on a grid
     * according to the provided number of colums.
     *
     * <p>Initial focus will be given to the first button.</p>
     *
     * @param buttons  the JButton instances to layout
     * @param nbCols   number of columns for the buttons grid, if <=0 all buttons will be put on a single row
     * @param rootPane associated with this ButtonChoicePanel
     */
    public ButtonChoicePanel(JButton buttons[], int nbCols, JRootPane rootPane) {
        this.buttons = buttons;
        this.nbButtons = buttons.length;
        this.nbCols = nbCols<=0?nbButtons:nbCols;
        this.rootPane = rootPane;
        this.nbRows = nbCols<=0?1:nbButtons/nbCols+(nbButtons%nbCols==0?0:1);

        // If the provided number of columns is <= 0, lay out all buttons on a single row
        // and use FlowLayout to do that
        if (nbCols<=0) {
            setLayout(new FlowLayout(FlowLayout.RIGHT));
        }
        // Use GridLayout to lay out buttons on 2-dimensional grid
        else {
            setLayout(new GridLayout(0, nbCols));
        }
       
        JButton button;
        for(int i=0; i<nbButtons; i++) {
            button = buttons[i];

            // Listener to key events to transfer focus
            button.addKeyListener(this);

            // Allow buttons to be made 'default buttons' when enter is pressed
            button.setDefaultCapable(true);

            // Listen to focus events to make the focused button the default button
            button.addFocusListener(this);

            add(button);
        }

        // Set mnemonics to buttons
        updateMnemonics();

        // First button is made 'default button'
        rootPane.setDefaultButton(buttons[0]);
        this.currentButton = 0;
    }


    /**
     * Updates the buttons mnemonics. This method should be called when at least one of the button's label has changed.
     */
    public void updateMnemonics() {
        MnemonicHelper mnemonicHelper = new MnemonicHelper();
        char mnemonic;

        JButton button;
        for(int i=0; i<nbButtons; i++) {
            button = buttons[i];
            mnemonic = mnemonicHelper.getMnemonic(button);
            if(mnemonic!=0)
                button.setMnemonic(mnemonic);
        }
    }


    /////////////////////////
    // KeyListener methods //
    /////////////////////////

    public void keyPressed(KeyEvent e) {
      int keyCode = e.getKeyCode();

        int oldCurrentButton = currentButton;

        // LEFT key goes back one button, to the last button if current button is the first one
        if (keyCode==KeyEvent.VK_LEFT) {
            this.currentButton = currentButton==0?nbButtons-1:currentButton-1;
        }
        // RIGHT key goes forward one button, to the first button if current button is the last one
        else if (keyCode==KeyEvent.VK_RIGHT) {
            this.currentButton = currentButton==nbButtons-1?0:currentButton+1;
        }
        // UP key goes up one row, to the last row if current button is on the first row
        else if (keyCode==KeyEvent.VK_UP) {
            if (currentButton<nbCols) {    // If current button is on the first row
                this.currentButton = (nbRows-1)*nbCols+currentButton%nbCols;
                if(this.currentButton>nbButtons-1)
                    this.currentButton -= nbCols;
            }
            else
                this.currentButton -= nbCols;
        }
        // DOWN key goes down one row, to the first row if current button is on the last row
        else if (keyCode==KeyEvent.VK_DOWN) {
            if(nbButtons-currentButton>0 && nbButtons-currentButton<=nbCols)    // If current button is on the last row
                this.currentButton = currentButton%nbCols;
            else
                this.currentButton += nbCols;
        }
        // Click button when a key that corresponds to one of the buttons' mnemonic has been pressed
        else if(!e.isAltDown()) {
            for(int i=0; i<nbButtons; i++) {
                if (keyCode==buttons[i].getMnemonic()) {
                    buttons[i].doClick();
                    return;
                }
            }
        }

        // Make the new button the default button and request focus on this button
        if(oldCurrentButton!=currentButton) {
            rootPane.setDefaultButton(buttons[currentButton]);
            buttons[currentButton].requestFocus();
        }
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }


    //////////////////////////////////
    // FocusListener implementation //
    //////////////////////////////////

    public void focusGained(FocusEvent focusEvent) {
        // Makes the newly focused button the default button
        rootPane.setDefaultButton((JButton)focusEvent.getComponent());
    }

    public void focusLost(FocusEvent focusEvent) {
    }
}
TOP

Related Classes of com.mucommander.ui.button.ButtonChoicePanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.