/**
* Copyright (C) 2002-2012 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol 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 2 of the License, or
* (at your option) any later version.
*
* FreeCol 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 FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.client.gui.option;
import org.freecolandroid.repackaged.java.awt.Color;
import org.freecolandroid.repackaged.java.awt.Dimension;
import org.freecolandroid.repackaged.java.awt.Graphics2D;
import org.freecolandroid.repackaged.java.awt.event.ActionEvent;
import org.freecolandroid.repackaged.java.awt.event.ActionListener;
import org.freecolandroid.repackaged.java.awt.event.KeyEvent;
import org.freecolandroid.repackaged.java.awt.event.KeyListener;
import org.freecolandroid.repackaged.java.awt.event.MouseEvent;
import org.freecolandroid.repackaged.java.awt.event.MouseListener;
import org.freecolandroid.repackaged.java.awt.image.BufferedImage;
import org.freecolandroid.repackaged.javax.swing.BorderFactory;
import org.freecolandroid.repackaged.javax.swing.ImageIcon;
import org.freecolandroid.repackaged.javax.swing.JButton;
import org.freecolandroid.repackaged.javax.swing.JLabel;
import org.freecolandroid.repackaged.javax.swing.JPanel;
import org.freecolandroid.repackaged.javax.swing.KeyStroke;
import org.freecolandroid.repackaged.javax.swing.Timer;
import net.sf.freecol.client.gui.GUI;
import net.sf.freecol.client.gui.action.FreeColAction;
/**
* User interface for displaying/changing a keyboard accelerator for a <code>FreeColAction</code>.
*/
public final class FreeColActionUI extends OptionUI<FreeColAction> implements ActionListener {
private OptionGroupUI optionGroupUI;
private KeyStroke keyStroke;
private JButton recordButton;
private JButton removeButton;
private BlinkingLabel bl;
private JPanel panel = new JPanel();
/**
* Creates a new <code>FreeColActionUI</code> for the
* given <code>FreeColAction</code>.
*
* @param option The <code>FreeColAction</code> to make a user
* interface for.
* @param editable boolean whether user can modify the setting
*/
public FreeColActionUI(GUI gui, FreeColAction option, boolean editable) {
super(gui, option, editable);
this.optionGroupUI = optionGroupUI;
keyStroke = option.getAccelerator();
panel.add(getLabel());
bl = new BlinkingLabel();
panel.add(bl);
recordButton = new JButton(getRecordImage());
recordButton.addActionListener(this);
panel.add(recordButton);
removeButton = new JButton(getRemoveImage());
removeButton.addActionListener(this);
panel.add(removeButton);
initialize();
}
/**
* Creates an icon for symbolizing the recording of a <code>KeyStroke</code>.
* @return The <code>ImageIcon</code>.
*/
public static ImageIcon getRecordImage() {
BufferedImage bi = new BufferedImage(9, 9, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.RED);
g.fillOval(0, 0, 9, 9);
g.setColor(Color.BLACK);
g.drawOval(0, 0, 9, 9);
return new ImageIcon(bi);
}
/**
* Creates an icon to be used on the button that removes a keyboard accelerator.
* @return The <code>ImageIcon</code>.
*/
public static ImageIcon getRemoveImage() {
BufferedImage bi = new BufferedImage(9, 9, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
/*g.fillRect(0, 0, 9, 9);*/
g.setColor(Color.BLACK);
g.drawLine(1, 0, 8, 7);
g.drawLine(0, 1, 7, 8);
g.drawLine(7, 0, 0, 7);
g.drawLine(9, 0, 0, 9);
g.setColor(Color.RED);
g.drawLine(0, 0, 8, 8);
g.drawLine(8, 0, 0, 8);
return new ImageIcon(bi);
}
/**
* Gets a string to represent the given <code>KeyStroke</code> to the user.
*
* @param keyStroke <code>java.awt.event.KeyStroke</code>
* @return String
*/
public static String getHumanKeyStrokeText(KeyStroke keyStroke) {
if (keyStroke == null) {
return " ";
}
String s = KeyEvent.getKeyModifiersText(keyStroke.getModifiers());
if (!s.equals("")) {
s += "+";
}
return s + KeyEvent.getKeyText(keyStroke.getKeyCode());
}
/**
* Removes the given <code>KeyStroke</code>. That is:
* This action's <code>KeyStroke</code> is set to
* <code>null</code> if it is the same as the given
* <code>KeyStroke</code>.
*
* @param k The <code>KeyStroke</code> to be removed.
*/
public void removeKeyStroke(KeyStroke k) {
if (k != null && keyStroke != null
&& k.getKeyCode() == keyStroke.getKeyCode()
&& k.getModifiers() == keyStroke.getModifiers()) {
keyStroke = null;
bl.setText(" ");
}
}
public void setOptionGroupUI(OptionGroupUI ui) {
this.optionGroupUI = ui;
}
/**
* {@inheritDoc}
*/
public JPanel getComponent() {
return panel;
}
/**
* {@inheritDoc}
*/
public void updateOption() {
getOption().setAccelerator(keyStroke);
}
/**
* {@inheritDoc}
*/
public void reset() {
keyStroke = getOption().getAccelerator();
bl.setText(getHumanKeyStrokeText(keyStroke));
}
public void actionPerformed(ActionEvent evt) {
if (evt.getSource() == recordButton) {
bl.startBlinking();
bl.requestFocus();
} else if (evt.getSource() == removeButton) {
bl.stopBlinking();
bl.setText(" ");
keyStroke = null;
}
}
/**
* Label for displaying a <code>KeyStroke</code>.
*/
class BlinkingLabel extends JLabel implements ActionListener, KeyListener, MouseListener {
// private Timer blinkingTimer = new Timer(500, this, gui.get);
private boolean blinkOn = false;
BlinkingLabel() {
super(getHumanKeyStrokeText(keyStroke), JLabel.CENTER);
setOpaque(false);
setBorder(BorderFactory.createLineBorder(Color.BLACK));
addKeyListener(this);
addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
startBlinking();
requestFocus();
}
}
public void mouseEntered(MouseEvent e) { /* No such event */ }
public void mouseExited(MouseEvent e) { /* No such event */ }
public void mousePressed(MouseEvent e) { /* No such event */ }
public void mouseReleased(MouseEvent e) { /* No such event */ }
@Override
public Dimension getMinimumSize() {
return new Dimension(80, super.getMinimumSize().height);
}
@Override
public Dimension getPreferredSize() {
return getMinimumSize();
}
public void startBlinking() {
// blinkingTimer.start();
}
public void stopBlinking() {
// blinkingTimer.stop();
setOpaque(false);
repaint();
}
public void actionPerformed(ActionEvent evt) {
if (!hasFocus()) {
stopBlinking();
}
if (blinkOn) {
setOpaque(false);
blinkOn = false;
repaint();
} else {
setOpaque(true);
setBackground(Color.RED);
blinkOn = true;
repaint();
}
}
public void keyPressed(KeyEvent e) { /* No such event */ }
public void keyTyped(KeyEvent e) { /* No such event */ }
public void keyReleased(KeyEvent e) {
KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
optionGroupUI.removeKeyStroke(ks);
keyStroke = ks;
//keyStroke = KeyStroke.getKeyStroke(new Character(e.getKeyChar()), e.getModifiers());
stopBlinking();
setText(getHumanKeyStrokeText(keyStroke));
recordButton.requestFocus();
}
}
}