/* FixedJRadioButton.java */ import com.sun.java.swing.*; import java.awt.*; import java.awt.event.*; /** * A JRadioButton subclass that works around Swing 1.0.2's broken button * mnemonics. * * Notes: * In Swing 1.0.2, button mnemonics were accidentally turned off. The * problem is that the installUI code in BasicButtonUI does not register * a KeyAccelerator for the mnemonic. This affects all AbstractButton * subclasses except for those in menus. * * This has already been fixed for the next release of Swing, however, * here is a temporary workaround until that release is out. * * The workaround involves adding a KeyAccelerator to the button * that monitors for the mnemonic. This code is nearly identical * to what should be happening automatically, so the behavior of * the workaround should be identical to how mnemonics worked in * Swing 1.0.1. * * Based on code by Jeff Dinkins. */ public class FixedJRadioButton extends JRadioButton { static private final int CHECK_PLEASE = 0; static private final int SWING_102 = 1; static private final int SWING_OTHER = 2; static private int swingVersion = CHECK_PLEASE; public FixedJRadioButton() { this(null, null, false); } public FixedJRadioButton(Icon icon) { this(null, icon, false); } public FixedJRadioButton(Icon icon, boolean selected) { this(null, icon, selected); } public FixedJRadioButton(String text) { this(text, null, false); } public FixedJRadioButton(String text, boolean selected) { this(text, null, selected); } public FixedJRadioButton(String text, Icon icon) { this(text, icon, false); } public FixedJRadioButton(String text, Icon icon, boolean selected) { super(text, icon, selected); if (swingVersion != CHECK_PLEASE) { return; } /* * Test whether we're running Swing 1.0.2. We do this by * checking whether the FileFilter class exists and is in * the preview package. FileFilter was introduced in 1.0.2; * in the next release, we expect it to be moved out of the * preview package. */ try { Class.forName("com.sun.java.swing.preview.filechooser.FileFilter"); swingVersion = SWING_102; } catch (ClassNotFoundException e) { swingVersion = SWING_OTHER; System.err.println("This program is using FixedJRadioButton, " + "but it should be using JRadioButton instead."); } } public void setMnemonic(char c) { super.setMnemonic(c); if (swingVersion == SWING_OTHER) { return; } int m = getMnemonic(); PressedAction pressedAction = new PressedAction(this); ReleasedAction releasedAction = new ReleasedAction(this); // the down-press of the alt-mnemonic keystroke KeyStroke altPressedKeyStroke = KeyStroke.getKeyStroke(m, ActionEvent.ALT_MASK, false); // the release of the alt-mnemonic keystroke KeyStroke altReleasedKeyStroke = KeyStroke.getKeyStroke(m, ActionEvent.ALT_MASK, true); // also watch the release of the mnemonic keystroke without the // alt key pressed (someone might hit alt-mnemonic, then release // the alt key before the mnemonic key - which should still trigger // the mnemonic accelerator) KeyStroke nonAltReleasedKeyStroke = KeyStroke.getKeyStroke(m, 0, true); registerKeyboardAction(pressedAction, altPressedKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); registerKeyboardAction(releasedAction, altReleasedKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); registerKeyboardAction(releasedAction, nonAltReleasedKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); } static class PressedAction extends AbstractAction { AbstractButton b = null; PressedAction(AbstractButton b) { super("pressedAction"); this.b = b; } public void actionPerformed(ActionEvent e) { ButtonModel model = b.getModel(); model.setArmed(true); model.setPressed(true); if(!b.hasFocus()) { b.requestFocus(); } } public boolean isEnabled() { if(!b.getModel().isEnabled()) { return false; } else { return true; } } } static class ReleasedAction extends AbstractAction { AbstractButton b = null; ReleasedAction(AbstractButton b) { super("releasedAction"); this.b = b; } public void actionPerformed(ActionEvent e) { b.getModel().setPressed(false); } public boolean isEnabled() { if(!b.getModel().isEnabled()) { return false; } else { return true; } } } }