/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo 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. * * OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.swing; import java.awt.AWTKeyStroke; import java.awt.Component; import java.awt.Container; import java.awt.FlowLayout; import java.awt.FocusTraversalPolicy; import java.awt.KeyboardFocusManager; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.HashSet; import java.util.Set; import java.util.Vector; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; /** * This class provides a common way to create and maintain a panel containing JButton stored with a FlowLayout. Support provided by this * class are mainly focus traversable policy management. Buttons stored in this panel are automatically managed according to a common focus * management scheme which could be exported to parent components with * * <pre> * applyFocusTraversablePolicyTo(Container,boolean) * </pre> * * @author sylvain * */ public class ButtonsControlPanel extends JPanel { Vector<JButton> _buttons; public ButtonsControlPanel() { super(); setLayout(new FlowLayout()); _buttons = new Vector<JButton>(); setFocusTraversalPolicyProvider(true); setFocusTraversalPolicy(new ButtonsControlPanelFocusTraversalPolicy()); } public JButton addButton(String buttonName, ActionListener listener) { final JButton returned = new JButton(); returned.setText(localizedForKeyAndButton(buttonName, returned)); returned.addActionListener(listener); returned.setFocusable(true); returned.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { returned.setSelected(true); } @Override public void focusLost(FocusEvent e) { returned.setSelected(false); } }); returned.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == KeyEvent.VK_ENTER) { returned.doClick(); } } }); _buttons.add(returned); add(returned); return returned; } @Override public void remove(Component comp) { super.remove(comp); if (_buttons.contains(comp)) { _buttons.remove(comp); } } public void requestFocusInFirstButton() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Component button = getFocusTraversalPolicy().getFirstComponent(ButtonsControlPanel.this); if (button != null) { button.requestFocusInWindow(); } } }); } public void applyFocusTraversablePolicyTo(Container container, boolean requestFocus) { container.setFocusTraversalPolicyProvider(true); container.setFocusTraversalPolicy(getFocusTraversalPolicy()); Set<AWTKeyStroke> set = container.getFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS); set = new HashSet<AWTKeyStroke>(set); KeyStroke right = KeyStroke.getKeyStroke("RIGHT"); set.add(right); KeyStroke down = KeyStroke.getKeyStroke("DOWN"); set.add(down); KeyStroke tab = KeyStroke.getKeyStroke("TAB"); set.add(tab); container.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set); set = container.getFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); set = new HashSet<AWTKeyStroke>(set); KeyStroke left = KeyStroke.getKeyStroke("LEFT"); set.add(left); KeyStroke up = KeyStroke.getKeyStroke("UP"); set.add(up); container.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, set); if (requestFocus) { requestFocusInFirstButton(); } } class ButtonsControlPanelFocusTraversalPolicy extends FocusTraversalPolicy { @Override public Component getComponentAfter(Container aContainer, Component aComponent) { if (allButtonsAreDisabled()) { return null; } JButton returned = null; int index = _buttons.indexOf(aComponent); if (index > -1) { int returnedIndex = index + 1; if (returnedIndex == _buttons.size()) { returnedIndex = 0; } returned = _buttons.elementAt(returnedIndex); } if (returned == null) { return null; } if (returned.isEnabled()) { return returned; } else { return getComponentAfter(aContainer, returned); } } @Override public Component getComponentBefore(Container aContainer, Component aComponent) { if (allButtonsAreDisabled()) { return null; } JButton returned = null; int index = _buttons.indexOf(aComponent); if (index > -1) { int returnedIndex = index - 1; if (returnedIndex == -1) { returnedIndex = _buttons.size() - 1; } returned = _buttons.elementAt(returnedIndex); } if (returned == null) { return null; } if (returned.isEnabled()) { return returned; } else { return getComponentBefore(aContainer, returned); } } @Override public Component getDefaultComponent(Container aContainer) { return getFirstComponent(aContainer); } @Override public Component getFirstComponent(Container aContainer) { if (allButtonsAreDisabled()) { return null; } JButton returned = null; if (_buttons.size() > 0) { returned = _buttons.firstElement(); } if (returned == null) { return null; } if (returned.isEnabled()) { return returned; } else { return getComponentAfter(aContainer, returned); } } @Override public Component getLastComponent(Container aContainer) { if (allButtonsAreDisabled()) { return null; } JButton returned = null; if (_buttons.size() > 0) { returned = _buttons.lastElement(); } if (returned == null) { return null; } if (returned.isEnabled()) { return returned; } else { return getComponentBefore(aContainer, returned); } } private boolean allButtonsAreDisabled() { for (JButton b : _buttons) { if (b.isEnabled()) { return false; } } return true; } } // Override if required public String localizedForKeyAndButton(String key, JButton component) { return key; } }