Make it impossible to have multiple actions bound to the same key.

This commit is contained in:
Campbell Suter 2016-10-21 09:01:19 +13:00
parent 4d0660b19f
commit 4c292466c1
No known key found for this signature in database
GPG key ID: 754A66CCF3F73C0F
3 changed files with 172 additions and 104 deletions

View file

@ -7,6 +7,7 @@ import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import mage.client.dialog.PreferencesDialog;
/**
*
@ -14,80 +15,102 @@ import javax.swing.JPopupMenu;
*/
public class KeyBindButton extends JButton implements ActionListener {
private final JPopupMenu menu;
private final PopupItem item;
private int keyCode;
private String text;
private final PreferencesDialog preferences;
private final String key;
private PopupItem item;
private JPopupMenu menu;
private int keyCode;
private String text;
public KeyBindButton() {
menu = new JPopupMenu();
menu.add(item = new PopupItem());
addActionListener(this);
/**
* For the IDE only, do not use!
*/
public KeyBindButton() {
this(null, null);
}
fixText();
}
public KeyBindButton(PreferencesDialog preferences, String key) {
this.preferences = preferences;
this.key = key;
addActionListener(this);
fixText();
}
private void applyNewKeycode(int code) {
keyCode = code;
switch (keyCode) {
case KeyEvent.VK_ESCAPE:
case KeyEvent.VK_SPACE:
keyCode = 0;
}
fixText();
menu.setVisible(false);
setSize(getPreferredSize());
}
private JPopupMenu getMenu() {
menu = new JPopupMenu();
menu.add(item = new PopupItem());
return menu;
}
private void fixText() {
if (keyCode == 0) {
text = "<None>";
} else {
text = KeyEvent.getKeyText(keyCode);
}
repaint();
}
private void applyNewKeycode(int code) {
preferences.getKeybindButtons().stream()
.filter(b -> b != KeyBindButton.this)
.filter(b -> b.getKeyCode() == code)
.forEach(b -> b.setKeyCode(0));
public void setKeyCode(int keyCode) {
this.keyCode = keyCode;
fixText();
}
setKeyCode(code);
menu.setVisible(false);
}
public int getKeyCode() {
return keyCode;
}
private void fixText() {
if (keyCode == 0) {
text = "<None>";
} else {
text = KeyEvent.getKeyText(keyCode);
}
repaint();
}
@Override
public String getText() {
return text;
}
public void setKeyCode(int keyCode) {
this.keyCode = keyCode;
switch (keyCode) {
case KeyEvent.VK_ESCAPE:
case KeyEvent.VK_SPACE:
keyCode = 0;
}
fixText();
setSize(getPreferredSize());
}
@Override
public void actionPerformed(ActionEvent e) {
menu.show(this, 0, 0);
item.requestFocusInWindow();
}
public int getKeyCode() {
return keyCode;
}
private class PopupItem extends JLabel implements KeyListener {
@Override
public String getText() {
return text;
}
public PopupItem() {
super("Press a key");
addKeyListener(this);
setFocusable(true);
}
public String getKey() {
return key;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void actionPerformed(ActionEvent e) {
getMenu().show(this, 0, 0);
item.requestFocusInWindow();
}
@Override
public void keyPressed(KeyEvent e) {
applyNewKeycode(e.getKeyCode());
}
private class PopupItem extends JLabel implements KeyListener {
@Override
public void keyReleased(KeyEvent e) {
}
public PopupItem() {
super("Press a key");
addKeyListener(this);
setFocusable(true);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
applyNewKeycode(e.getKeyCode());
}
@Override
public void keyReleased(KeyEvent e) {
}
}
}

View file

@ -5886,7 +5886,7 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="labelCancel" alignment="0" min="-2" max="-2" attributes="0"/>
@ -5921,8 +5921,9 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="controlsDescriptionLabel" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="labelConfirm" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="keyConfirm" alignment="3" min="-2" max="-2" attributes="0"/>
@ -5968,9 +5969,8 @@
<Component id="keyPriorEnd" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="controlsDescriptionLabel" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="263" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -6015,41 +6015,65 @@
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_CANCEL_SKIP)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keyNextTurn">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_NEXT_TURN)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keyMainStep">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_MAIN_STEP)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keyEndStep">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_END_STEP)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keyYourTurn">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_YOUR_TURN)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keySkipStack">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_SKIP_STACK)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keyPriorEnd">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_PRIOR_END)"/>
</AuxValues>
</Component>
<Component class="mage.client.components.KeyBindButton" name="keySkipStep">
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_SKIP_STEP)"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelSkipStep">
<Properties>
@ -6060,6 +6084,9 @@
<Properties>
<Property name="text" type="java.lang.String" value="keyBindButton1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new KeyBindButton(this, KEY_CONTROL_CONFIRM)"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelConfirm">
<Properties>

View file

@ -42,7 +42,9 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
@ -560,16 +562,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
lebelSkip = new javax.swing.JLabel();
labelPriorEnd = new javax.swing.JLabel();
labelCancel = new javax.swing.JLabel();
keyCancelSkip = new mage.client.components.KeyBindButton();
keyNextTurn = new mage.client.components.KeyBindButton();
keyMainStep = new mage.client.components.KeyBindButton();
keyEndStep = new mage.client.components.KeyBindButton();
keyYourTurn = new mage.client.components.KeyBindButton();
keySkipStack = new mage.client.components.KeyBindButton();
keyPriorEnd = new mage.client.components.KeyBindButton();
keySkipStep = new mage.client.components.KeyBindButton();
keyCancelSkip = new KeyBindButton(this, KEY_CONTROL_CANCEL_SKIP);
keyNextTurn = new KeyBindButton(this, KEY_CONTROL_NEXT_TURN);
keyMainStep = new KeyBindButton(this, KEY_CONTROL_MAIN_STEP);
keyEndStep = new KeyBindButton(this, KEY_CONTROL_END_STEP);
keyYourTurn = new KeyBindButton(this, KEY_CONTROL_YOUR_TURN);
keySkipStack = new KeyBindButton(this, KEY_CONTROL_SKIP_STACK);
keyPriorEnd = new KeyBindButton(this, KEY_CONTROL_PRIOR_END);
keySkipStep = new KeyBindButton(this, KEY_CONTROL_SKIP_STEP);
labelSkipStep = new javax.swing.JLabel();
keyConfirm = new mage.client.components.KeyBindButton();
keyConfirm = new KeyBindButton(this, KEY_CONTROL_CONFIRM);
labelConfirm = new javax.swing.JLabel();
controlsDescriptionLabel = new javax.swing.JLabel();
saveButton = new javax.swing.JButton();
@ -2548,8 +2550,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabControlsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(tabControlsLayout.createSequentialGroup()
.addContainerGap()
.add(tabControlsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(tabControlsLayout.createSequentialGroup()
.add(tabControlsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
.add(org.jdesktop.layout.GroupLayout.LEADING, controlsDescriptionLabel)
.add(org.jdesktop.layout.GroupLayout.LEADING, tabControlsLayout.createSequentialGroup()
.add(tabControlsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(labelConfirm)
.add(keyConfirm, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
@ -2584,9 +2587,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(tabControlsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(labelPriorEnd)
.add(keyPriorEnd, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
.add(controlsDescriptionLabel))
.add(263, 263, 263))
.add(keyPriorEnd, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
.addContainerGap())
);
tabsPanel.addTab("Controls", tabControls);
@ -2780,15 +2782,15 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.txtURLServerList, KEY_CONNECTION_URL_SERVER_LIST);
// controls
save(prefs, dialog.keyConfirm, KEY_CONTROL_CONFIRM);
save(prefs, dialog.keyCancelSkip, KEY_CONTROL_CANCEL_SKIP);
save(prefs, dialog.keyNextTurn, KEY_CONTROL_NEXT_TURN);
save(prefs, dialog.keyEndStep, KEY_CONTROL_END_STEP);
save(prefs, dialog.keySkipStep, KEY_CONTROL_SKIP_STEP);
save(prefs, dialog.keyMainStep, KEY_CONTROL_MAIN_STEP);
save(prefs, dialog.keyYourTurn, KEY_CONTROL_YOUR_TURN);
save(prefs, dialog.keySkipStack, KEY_CONTROL_SKIP_STACK);
save(prefs, dialog.keyPriorEnd, KEY_CONTROL_PRIOR_END);
save(prefs, dialog.keyConfirm);
save(prefs, dialog.keyCancelSkip);
save(prefs, dialog.keyNextTurn);
save(prefs, dialog.keyEndStep);
save(prefs, dialog.keySkipStep);
save(prefs, dialog.keyMainStep);
save(prefs, dialog.keyYourTurn);
save(prefs, dialog.keySkipStack);
save(prefs, dialog.keyPriorEnd);
// Avatar
if (selectedAvatarId < MIN_AVATAR_ID || selectedAvatarId > MAX_AVATAR_ID) {
@ -3327,15 +3329,15 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
private static void loadControlSettings(Preferences prefs) {
load(prefs, dialog.keyConfirm, KEY_CONTROL_CONFIRM);
load(prefs, dialog.keyCancelSkip, KEY_CONTROL_CANCEL_SKIP);
load(prefs, dialog.keyNextTurn, KEY_CONTROL_NEXT_TURN);
load(prefs, dialog.keyEndStep, KEY_CONTROL_END_STEP);
load(prefs, dialog.keySkipStep, KEY_CONTROL_SKIP_STEP);
load(prefs, dialog.keyMainStep, KEY_CONTROL_MAIN_STEP);
load(prefs, dialog.keyYourTurn, KEY_CONTROL_YOUR_TURN);
load(prefs, dialog.keySkipStack, KEY_CONTROL_SKIP_STACK);
load(prefs, dialog.keyPriorEnd, KEY_CONTROL_PRIOR_END);
load(prefs, dialog.keyConfirm);
load(prefs, dialog.keyCancelSkip);
load(prefs, dialog.keyNextTurn);
load(prefs, dialog.keyEndStep);
load(prefs, dialog.keySkipStep);
load(prefs, dialog.keyMainStep);
load(prefs, dialog.keyYourTurn);
load(prefs, dialog.keySkipStack);
load(prefs, dialog.keyPriorEnd);
}
private static void loadSelectedAvatar(Preferences prefs) {
@ -3462,8 +3464,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, checkBox, propName, PHASE_ON);
}
private static void load(Preferences prefs, KeyBindButton button, String propName) {
int prop = prefs.getInt(propName, getDefaultControlKey(propName));
private static void load(Preferences prefs, KeyBindButton button) {
String key = button.getKey();
int prop = prefs.getInt(key, getDefaultControlKey(key));
button.setKeyCode(prop);
}
@ -3504,10 +3507,11 @@ public class PreferencesDialog extends javax.swing.JDialog {
updateCache(propName, comboBox.getSelectedItem().toString().trim());
}
private static void save(Preferences prefs, KeyBindButton button, String propName) {
private static void save(Preferences prefs, KeyBindButton button) {
int code = button.getKeyCode();
prefs.putInt(propName, code);
updateCache(propName, Integer.toString(code));
String key = button.getKey();
prefs.putInt(key, code);
updateCache(key, Integer.toString(code));
}
public void reset() {
@ -3688,6 +3692,20 @@ public class PreferencesDialog extends javax.swing.JDialog {
);
}
public List<KeyBindButton> getKeybindButtons() {
return Arrays.asList(
keyCancelSkip,
keyConfirm,
keyEndStep,
keyMainStep,
keyNextTurn,
keyPriorEnd,
keySkipStack,
keySkipStep,
keyYourTurn
);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane avatarPane;
private javax.swing.JPanel avatarPanel;