- make radio button groups navigatable with arrow keys and behave as a single focus component

- allow quest duels/challenges to start with a double-click on an opponent
This commit is contained in:
myk
2013-02-26 09:17:54 +00:00
parent 91cbc750b4
commit 6888240861
10 changed files with 493 additions and 173 deletions

View File

@@ -37,7 +37,6 @@ import java.util.Random;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.DefaultBoundedRangeModel; import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
@@ -65,6 +64,7 @@ import forge.gui.toolbox.FPanel;
import forge.gui.toolbox.FProgressBar; import forge.gui.toolbox.FProgressBar;
import forge.gui.toolbox.FRadioButton; import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.JXButtonPanel;
import forge.properties.ForgeProps; import forge.properties.ForgeProps;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.util.FileUtil; import forge.util.FileUtil;
@@ -123,10 +123,11 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
/** Constructor. */ /** Constructor. */
protected GuiDownloader() { protected GuiDownloader() {
final ButtonGroup grpRad = new ButtonGroup(); String radConstraints = "w 100%!, h 30px!, gap 2% 0 0 10px";
grpRad.add(radProxyNone); JXButtonPanel grpPanel = new JXButtonPanel();
grpRad.add(radProxyHTTP); grpPanel.add(radProxyNone, radConstraints);
grpRad.add(radProxySocks); grpPanel.add(radProxyHTTP, radConstraints);
grpPanel.add(radProxySocks, radConstraints);
radProxyNone.addChangeListener(new ProxyHandler(0)); radProxyNone.addChangeListener(new ProxyHandler(0));
radProxyHTTP.addChangeListener(new ProxyHandler(1)); radProxyHTTP.addChangeListener(new ProxyHandler(1));
@@ -142,9 +143,7 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
pnlDialog.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE)); pnlDialog.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
// Layout // Layout
pnlDialog.add(radProxyNone, "w 50%!, h 30px!, gap 2% 0 0 10px"); pnlDialog.add(grpPanel, "w 50%!");
pnlDialog.add(radProxyHTTP, "w 50%!, h 30px!, gap 2% 0 0 10px");
pnlDialog.add(radProxySocks, "w 50%!, h 30px!, gap 2% 0 0 10px");
pnlDialog.add(txfAddr, "w 95%!, h 30px!, gap 2% 0 0 10px"); pnlDialog.add(txfAddr, "w 95%!, h 30px!, gap 2% 0 0 10px");
pnlDialog.add(txfPort, "w 95%!, h 30px!, gap 2% 0 0 10px"); pnlDialog.add(txfPort, "w 95%!, h 30px!, gap 2% 0 0 10px");
pnlDialog.add(barProgress, "w 95%!, h 40px!, gap 2% 0 20px 0"); pnlDialog.add(barProgress, "w 95%!, h 40px!, gap 2% 0 20px 0");

View File

@@ -5,9 +5,11 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List; import java.util.List;
import javax.swing.ButtonGroup; import javax.swing.JRadioButton;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
@@ -18,6 +20,7 @@ import forge.gui.framework.EDocID;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.home.CHomeUI; import forge.gui.home.CHomeUI;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.JXButtonPanel;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.QuestEventChallenge; import forge.quest.QuestEventChallenge;
import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestItemType;
@@ -104,6 +107,14 @@ public enum CSubmenuChallenges implements ICDoc {
} }
} }
}; };
private final MouseAdapter _startOnDblClick = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) {
VSubmenuChallenges.SINGLETON_INSTANCE.getBtnStart().doClick();
}
}
};
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update() * @see forge.control.home.IControlSubmenu#update()
@@ -121,20 +132,22 @@ public enum CSubmenuChallenges implements ICDoc {
view.getPnlChallenges().removeAll(); view.getPnlChallenges().removeAll();
final List<QuestEventChallenge> challenges = qCtrl.getChallengesManager().generateChallenges(); final List<QuestEventChallenge> challenges = qCtrl.getChallengesManager().generateChallenges();
ButtonGroup grp = new ButtonGroup(); JXButtonPanel grpPanel = new JXButtonPanel();
for (int i = 0; i < challenges.size(); i++) { for (int i = 0; i < challenges.size(); i++) {
final PnlEvent temp = new PnlEvent(challenges.get(i)); final PnlEvent temp = new PnlEvent(challenges.get(i));
grp.add(temp.getRad()); final JRadioButton rad = temp.getRad();
if (i == 0) { if (i == 0) {
temp.getRad().setSelected(true); rad.setSelected(true);
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { temp.getRad().requestFocusInWindow(); } @Override public void run() { rad.requestFocusInWindow(); }
}); });
} }
temp.getRad().addKeyListener(_startOnEnter); rad.addKeyListener(_startOnEnter);
view.getPnlChallenges().add(temp, "w 96%!, h 135px!, gap 2% 0 15px 15px"); rad.addMouseListener(_startOnDblClick);
grpPanel.add(temp, rad, "w 100%!, h 135px!, gap 2% 0 15px 15px");
} }
view.getPnlChallenges().add(grpPanel, "w 96%!");
if (challenges.size() == 0) { if (challenges.size() == 0) {
final FLabel lbl = new FLabel.Builder() final FLabel lbl = new FLabel.Builder()

View File

@@ -4,9 +4,11 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List; import java.util.List;
import javax.swing.ButtonGroup; import javax.swing.JRadioButton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import forge.Command; import forge.Command;
@@ -14,6 +16,7 @@ import forge.Singletons;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.home.CHomeUI; import forge.gui.home.CHomeUI;
import forge.gui.toolbox.JXButtonPanel;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.QuestEventDuel; import forge.quest.QuestEventDuel;
import forge.quest.bazaar.QuestPetController; import forge.quest.bazaar.QuestPetController;
@@ -86,6 +89,14 @@ public enum CSubmenuDuels implements ICDoc {
} }
} }
}; };
private final MouseAdapter _startOnDblClick = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) {
VSubmenuDuels.SINGLETON_INSTANCE.getBtnStart().doClick();
}
}
};
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update() * @see forge.control.home.IControlSubmenu#update()
@@ -102,20 +113,22 @@ public enum CSubmenuDuels implements ICDoc {
view.getPnlDuels().removeAll(); view.getPnlDuels().removeAll();
final List<QuestEventDuel> duels = Singletons.getModel().getQuest().getDuelsManager().generateDuels(); final List<QuestEventDuel> duels = Singletons.getModel().getQuest().getDuelsManager().generateDuels();
ButtonGroup grp = new ButtonGroup(); JXButtonPanel grpPanel = new JXButtonPanel();
for (int i = 0; i < duels.size(); i++) { for (int i = 0; i < duels.size(); i++) {
final PnlEvent temp = new PnlEvent(duels.get(i)); final PnlEvent temp = new PnlEvent(duels.get(i));
grp.add(temp.getRad()); final JRadioButton rad = temp.getRad();
if (i == 0) { if (i == 0) {
temp.getRad().setSelected(true); rad.setSelected(true);
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { temp.getRad().requestFocusInWindow(); } @Override public void run() { rad.requestFocusInWindow(); }
}); });
} }
temp.getRad().addKeyListener(_startOnEnter); rad.addKeyListener(_startOnEnter);
view.getPnlDuels().add(temp, "w 96%!, h 135px!, gap 2% 0 15px 15px"); rad.addMouseListener(_startOnDblClick);
grpPanel.add(temp, rad, "w 100%!, h 135px!, gap 2% 0 15px 15px");
} }
view.getPnlDuels().add(grpPanel, "w 96%!");
} }
} }

View File

@@ -6,7 +6,6 @@ import java.awt.event.ActionListener;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
@@ -36,6 +35,7 @@ import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FRadioButton; import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FScrollPane; import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.JXButtonPanel;
import forge.item.PreconDeck; import forge.item.PreconDeck;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.QuestWorld; import forge.quest.QuestWorld;
@@ -194,11 +194,12 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
scrQuests.setBorder(null); scrQuests.setBorder(null);
final ButtonGroup group1 = new ButtonGroup(); final JXButtonPanel difficultyPanel = new JXButtonPanel();
group1.add(radEasy); final String difficulty_constraints = "h 27px!, gapbottom 5";
group1.add(radMedium); difficultyPanel.add(radEasy, difficulty_constraints);
group1.add(radHard); difficultyPanel.add(radMedium, difficulty_constraints);
group1.add(radExpert); difficultyPanel.add(radHard, difficulty_constraints);
difficultyPanel.add(radExpert, difficulty_constraints);
radEasy.setSelected(true); radEasy.setSelected(true);
cbxStartingPool.addItem(StartingPoolType.Complete); cbxStartingPool.addItem(StartingPoolType.Complete);
@@ -272,14 +273,9 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
pnlOptions.setOpaque(false); pnlOptions.setOpaque(false);
pnlOptions.setLayout(new MigLayout("insets 0, gap 10px, fillx, wrap 2")); pnlOptions.setLayout(new MigLayout("insets 0, gap 10px, fillx, wrap 2"));
JPanel pnlDifficultyMode = new JPanel(); JPanel pnlDifficultyMode = new JPanel(new MigLayout("insets 0, gap 1%, flowy"));
pnlDifficultyMode.setLayout(new MigLayout("insets 0, gap 1%, flowy")); pnlDifficultyMode.add(difficultyPanel, "gapright 4%");
final String n_constraints = "h 27px!"; pnlDifficultyMode.add(boxFantasy, difficulty_constraints + ", gapright 4%");
pnlDifficultyMode.add(radEasy, n_constraints + ", gap 0 4% 0 5px");
pnlDifficultyMode.add(radMedium, n_constraints + ", gap 0 4% 0 5px");
pnlDifficultyMode.add(radHard, n_constraints + ", gap 0 4% 0 5px");
pnlDifficultyMode.add(radExpert, n_constraints + ", gap 0 4% 0 5px");
pnlDifficultyMode.add(boxFantasy, n_constraints + ", gap 0 4% 0 5px");
pnlDifficultyMode.setOpaque(false); pnlDifficultyMode.setOpaque(false);
pnlOptions.add(pnlDifficultyMode, "w 40%"); pnlOptions.add(pnlDifficultyMode, "w 40%");
@@ -429,7 +425,6 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
return parentCell; return parentCell;
} }
public int getSelectedDifficulty() { public int getSelectedDifficulty() {
if (radEasy.isSelected()) { if (radEasy.isSelected()) {
return 0; return 0;

View File

@@ -93,7 +93,7 @@ public enum CSubmenuDraft implements ICDoc {
} }
private void startGame(final GameType gameType) { private void startGame(final GameType gameType) {
final boolean gauntlet = !VSubmenuDraft.SINGLETON_INSTANCE.getRadSingle().isSelected(); final boolean gauntlet = !VSubmenuDraft.SINGLETON_INSTANCE.isSingleSelected();
final Deck humanDeck = VSubmenuDraft.SINGLETON_INSTANCE.getLstDecks().getSelectedDeck(); final Deck humanDeck = VSubmenuDraft.SINGLETON_INSTANCE.getLstDecks().getSelectedDeck();
final int aiIndex = (int) Math.floor(Math.random() * 8); final int aiIndex = (int) Math.floor(Math.random() * 8);

View File

@@ -2,7 +2,6 @@ package forge.gui.home.sanctioned;
import java.awt.Font; import java.awt.Font;
import javax.swing.ButtonGroup;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
@@ -27,6 +26,7 @@ import forge.gui.toolbox.FList;
import forge.gui.toolbox.FRadioButton; import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FScrollPane; import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.JXButtonPanel;
/** /**
* Assembles Swing components of draft submenu singleton. * Assembles Swing components of draft submenu singleton.
@@ -81,16 +81,15 @@ public enum VSubmenuDraft implements IVSubmenu<CSubmenuDraft> {
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
final ButtonGroup grp = new ButtonGroup(); JXButtonPanel grpPanel = new JXButtonPanel();
grp.add(radSingle); grpPanel.add(radSingle, "w 200px!, h 30px!");
grp.add(radAll); grpPanel.add(radAll, "w 200px!, h 30px!");
radSingle.setSelected(true); radSingle.setSelected(true);
pnlStart.setLayout(new MigLayout("insets 0, gap 0, wrap 2")); pnlStart.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
pnlStart.setOpaque(false); pnlStart.setOpaque(false);
pnlStart.add(radSingle, "w 200px!, h 30px!, gap 0 20px 0 0"); pnlStart.add(grpPanel, "gapright 20");
pnlStart.add(btnStart, "span 1 2, growx, pushx"); pnlStart.add(btnStart);
pnlStart.add(radAll, "w 200px!, h 30px!, gap 0 20px 0 0");
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -128,8 +127,8 @@ public enum VSubmenuDraft implements IVSubmenu<CSubmenuDraft> {
} }
/** @return {@link javax.swing.JRadioButton} */ /** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadSingle() { public boolean isSingleSelected() {
return this.radSingle; return radSingle.isSelected();
} }
/** @return {@link forge.gui.toolbox.DeckLister} */ /** @return {@link forge.gui.toolbox.DeckLister} */

View File

@@ -90,7 +90,6 @@ public enum CSubmenuArchenemy implements ICDoc {
public void execute() { public void execute() {
Predicate<CardPrinted> predSchemes = new Predicate<CardPrinted>() { Predicate<CardPrinted> predSchemes = new Predicate<CardPrinted>() {
@Override @Override
public boolean apply(CardPrinted arg0) { public boolean apply(CardPrinted arg0) {
if(arg0.getRules().getType().isScheme()) if(arg0.getRules().getType().isScheme())
@@ -100,7 +99,6 @@ public enum CSubmenuArchenemy implements ICDoc {
return false; return false;
} }
}; };
FControl.SINGLETON_INSTANCE.changeState(FControl.Screens.DECK_EDITOR_CONSTRUCTED); FControl.SINGLETON_INSTANCE.changeState(FControl.Screens.DECK_EDITOR_CONSTRUCTED);
@@ -255,7 +253,6 @@ public enum CSubmenuArchenemy implements ICDoc {
worker.execute(); worker.execute();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.gui.framework.ICDoc#getCommandOnSelect() * @see forge.gui.framework.ICDoc#getCommandOnSelect()
*/ */

View File

@@ -5,7 +5,6 @@ import java.awt.event.ItemListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JPanel; import javax.swing.JPanel;
@@ -34,6 +33,7 @@ import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FScrollPane; import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTabbedPane; import forge.gui.toolbox.FTabbedPane;
import forge.gui.toolbox.JXButtonPanel;
/** /**
* Assembles Swing components of constructed submenu singleton. * Assembles Swing components of constructed submenu singleton.
@@ -70,7 +70,6 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
private final List<Deck> allSchemeDecks = new ArrayList<Deck>(); private final List<Deck> allSchemeDecks = new ArrayList<Deck>();
private final JCheckBox cbUseDefaultSchemes = new FCheckBox("Use default scheme decks if possible."); private final JCheckBox cbUseDefaultSchemes = new FCheckBox("Use default scheme decks if possible.");
private final List<JRadioButton> fieldRadios = new ArrayList<JRadioButton>(); private final List<JRadioButton> fieldRadios = new ArrayList<JRadioButton>();
private final ButtonGroup grpFields = new ButtonGroup();
private int currentNumTabsShown = 8; private int currentNumTabsShown = 8;
////////////////////////////// //////////////////////////////
@@ -82,7 +81,6 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
//This listener will look for any of the radio buttons being selected //This listener will look for any of the radio buttons being selected
//and call the method that shows/hides tabs appropriately. //and call the method that shows/hides tabs appropriately.
ItemListener iListener = new ItemListener() { ItemListener iListener = new ItemListener() {
@Override @Override
public void itemStateChanged(ItemEvent arg0) { public void itemStateChanged(ItemEvent arg0) {
FRadioButton aButton = (FRadioButton) arg0.getSource(); FRadioButton aButton = (FRadioButton) arg0.getSource();
@@ -94,28 +92,21 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
}; };
//Create all 8 player settings panel
FRadioButton tempRadio = null;
FPanel tempPanel;
FDeckChooser tempChooser;
//Settings panel //Settings panel
FPanel settingsPanel = new FPanel(); FPanel settingsPanel = new FPanel();
settingsPanel.setLayout(new MigLayout("wrap 2")); settingsPanel.setLayout(new MigLayout("wrap 2"));
FPanel radioPane = new FPanel(); FPanel radioPaneContainer = new FPanel(new MigLayout());
radioPane.setLayout(new MigLayout("wrap 1")); radioPaneContainer.setOpaque(false);
radioPane.setOpaque(false); JXButtonPanel radioPane = new JXButtonPanel();
radioPane.add(new FLabel.Builder().text("Set number of opponents").build(), "wrap"); radioPane.add(new FLabel.Builder().text("Set number of opponents").build());
for (int i = 1; i < 8; i++) { for (int i = 1; i < 8; i++) {
tempRadio = new FRadioButton(); FRadioButton tempRadio = new FRadioButton(String.valueOf(i));
tempRadio.setText(String.valueOf(i));
fieldRadios.add(tempRadio); fieldRadios.add(tempRadio);
grpFields.add(tempRadio);
tempRadio.setSelected(true);
tempRadio.addItemListener(iListener); tempRadio.addItemListener(iListener);
radioPane.add(tempRadio, "wrap,align 50% 50%"); radioPane.add(tempRadio, "align 50% 50%, gaptop 5");
} }
settingsPanel.add(radioPane, "span 1 2"); radioPaneContainer.add(radioPane);
settingsPanel.add(radioPaneContainer, "span 1 2");
settingsPanel.add(cbUseDefaultSchemes); settingsPanel.add(cbUseDefaultSchemes);
settingsPanel.add(lblEditor, "w pref+24, h pref+8"); settingsPanel.add(lblEditor, "w pref+24, h pref+8");
tabPane.add("Settings", settingsPanel); tabPane.add("Settings", settingsPanel);
@@ -128,10 +119,10 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
//Player panels (Human + 7 AIs) //Player panels (Human + 7 AIs)
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
tempPanel = new FPanel(); FPanel tempPanel = new FPanel();
tempPanel.setLayout(new MigLayout("insets 0, gap 0 , wrap 2, flowy")); tempPanel.setLayout(new MigLayout("insets 0, gap 0 , wrap 2, flowy"));
tempChooser = new FDeckChooser("Select deck:", i == 0 ? PlayerType.HUMAN : PlayerType.COMPUTER); FDeckChooser tempChooser = new FDeckChooser("Select deck:", i == 0 ? PlayerType.HUMAN : PlayerType.COMPUTER);
tempChooser.initialize(); tempChooser.initialize();
deckChoosers.add(tempChooser); deckChoosers.add(tempChooser);
@@ -161,6 +152,9 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center"); pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");
pnlStart.add(cbArtifacts, strCheckboxConstraints); pnlStart.add(cbArtifacts, strCheckboxConstraints);
pnlStart.add(cbRemoveSmall, strCheckboxConstraints); pnlStart.add(cbRemoveSmall, strCheckboxConstraints);
// ensure we don't fire the selected event before the tabPane is populated
fieldRadios.get(fieldRadios.size() - 1).setSelected(true);
} }
private void changeTabs(int toShow) { private void changeTabs(int toShow) {

View File

@@ -1,27 +1,25 @@
package forge.gui.toolbox; package forge.gui.toolbox;
import java.awt.Font; import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.commons.lang3.ArrayUtils;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.ArrayUtils;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.deck.Deck; import forge.deck.Deck;
@@ -32,17 +30,12 @@ import forge.quest.QuestController;
import forge.quest.QuestEvent; import forge.quest.QuestEvent;
import forge.util.storage.IStorage; import forge.util.storage.IStorage;
/**
* TODO: Write javadoc for this type.
*
*/
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class FDeckChooser extends JPanel { public class FDeckChooser extends JPanel {
private enum ESubmenuConstructedTypes {
private enum ESubmenuConstructedTypes { /** */ COLORS,
COLORS, /** */ THEMES,
THEMES, /** */ CUSTOM,
CUSTOM, /** */
QUESTEVENTS QUESTEVENTS
} }
@@ -56,16 +49,14 @@ public class FDeckChooser extends JPanel {
private final JList lstDecks = new FList(); private final JList lstDecks = new FList();
private final FLabel btnRandom = new FLabel.ButtonBuilder().text("Random").fontSize(16).build(); private final FLabel btnRandom = new FLabel.ButtonBuilder().text("Random").fontSize(16).build();
private final JScrollPane scrDecks = new FScrollPane(lstDecks, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); private final JScrollPane scrDecks =
new FScrollPane(lstDecks, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
private final FLabel lblDecklist = new FLabel.Builder() private final FLabel lblDecklist = new FLabel.Builder().text("Double click a non-random deck for its decklist.").fontSize(12).build();
.text("Double click a non-random deck for its decklist.")
.fontSize(12).build();
private final JPanel pnlRadios = new JPanel(new MigLayout("insets 0, gap 0, wrap")); private final JPanel pnlRadios = new JPanel(new MigLayout("insets 0, gap 0, wrap"));
private final PlayerType playerType; private final PlayerType playerType;
private final MouseAdapter madDecklist = new MouseAdapter() { private final MouseAdapter madDecklist = new MouseAdapter() {
@Override @Override
public void mouseClicked(final MouseEvent e) { public void mouseClicked(final MouseEvent e) {
@@ -79,86 +70,51 @@ public class FDeckChooser extends JPanel {
}; };
public FDeckChooser(String titleText, PlayerType pt) { public FDeckChooser(String titleText, PlayerType pt) {
setOpaque(false);
playerType = pt; playerType = pt;
// Radio button panels: Human and AI // Radio button group
final String strRadioConstraints = "w 100%!, h 30px!"; final String strRadioConstraints = "w 100%!, h 30px!";
JXButtonPanel grpRadios = new JXButtonPanel();
this.setOpaque(false); grpRadios.add(radCustom, strRadioConstraints);
grpRadios.add(radQuests, strRadioConstraints);
// Radio button group: Human grpRadios.add(radColors, strRadioConstraints);
final ButtonGroup grpRadios = new ButtonGroup(); grpRadios.add(radThemes, strRadioConstraints);
grpRadios.add(radCustom);
grpRadios.add(radQuests);
grpRadios.add(radColors);
grpRadios.add(radThemes);
pnlRadios.setOpaque(false); pnlRadios.setOpaque(false);
pnlRadios.add(new FLabel.Builder().text(titleText) pnlRadios.add(new FLabel.Builder().text(titleText).fontStyle(Font.BOLD).fontSize(16).build());
.fontStyle(Font.BOLD).fontSize(16)
.fontAlign(SwingConstants.LEFT).build(), strRadioConstraints);
pnlRadios.add(lblDecklist, "h 20px!, gap 0 0 0 10px"); pnlRadios.add(lblDecklist, "h 20px!, gap 0 0 0 10px");
pnlRadios.add(radCustom, strRadioConstraints); pnlRadios.add(grpRadios, "w 100%");
pnlRadios.add(radQuests, strRadioConstraints);
pnlRadios.add(radColors, strRadioConstraints);
pnlRadios.add(radThemes, strRadioConstraints);
pnlRadios.add(btnRandom, "w 200px!, h 30px!, gap 0 0 10px 0, ax center"); pnlRadios.add(btnRandom, "w 200px!, h 30px!, gap 0 0 10px 0, ax center");
} }
private void _listen(final JRadioButton btn, final Runnable onSelect) {
btn.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
if (btn.isSelected()) { onSelect.run(); }
}
});
}
public void initialize() { public void initialize() {
// Radio button event handling // Radio button event handling
getRadColors().addActionListener(new ActionListener() { @Override _listen(getRadColors(), new Runnable() { @Override public void run() { updateColors(); } });
public void actionPerformed(final ActionEvent arg0) { _listen(getRadThemes(), new Runnable() { @Override public void run() { updateThemes(); } });
updateColors(); } }); _listen(getRadCustom(), new Runnable() { @Override public void run() { updateCustom(); } });
_listen(getRadQuests(), new Runnable() { @Override public void run() { updateQuestEvents(); } });
getRadThemes().addActionListener(new ActionListener() { @Override
public void actionPerformed(final ActionEvent arg0) {
updateThemes(); } });
getRadCustom().addActionListener(new ActionListener() { @Override
public void actionPerformed(final ActionEvent arg0) {
updateCustom(); } });
getRadQuests().addActionListener(new ActionListener() { @Override
public void actionPerformed(final ActionEvent arg0) {
updateQuestEvents(); } });
// First run: colors // First run: colors
getRadColors().setSelected(true); getRadColors().setSelected(true);
updateColors();
} }
/** @return {@link javax.swing.JList} */ public JList getLstDecks() { return lstDecks; }
public JList getLstDecks() { public FLabel getBtnRandom() { return btnRandom; }
return this.lstDecks; public JRadioButton getRadColors() { return radColors; }
} public JRadioButton getRadThemes() { return radThemes; }
/** @return {@link forge.gui.toolbox.ExperimentalLabel} */ public JRadioButton getRadCustom() { return radCustom; }
public FLabel getBtnRandom() { public JRadioButton getRadQuests() { return radQuests; }
return this.btnRandom;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadColors() {
return this.radColors;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadThemes() {
return this.radThemes;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadCustom() {
return this.radCustom;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadQuests() {
return this.radQuests;
}
/** Handles all control for "colors" radio button click. */ /** Handles all control for "colors" radio button click. */
private void updateColors() { private void updateColors() {
@@ -171,9 +127,8 @@ public class FDeckChooser extends JPanel {
lst.removeMouseListener(madDecklist); lst.removeMouseListener(madDecklist);
lst.addMouseListener(madDecklist); lst.addMouseListener(madDecklist);
final FLabel btn = getBtnRandom(); getBtnRandom().setCommand(new Command() {
@Override public void execute() { lst.setSelectedIndices(DeckgenUtil.randomSelectColors()); } });
btn.setCommand(new Command() { @Override public void execute() { lst.setSelectedIndices(DeckgenUtil.randomSelectColors()); } });
// Init basic two color deck // Init basic two color deck
lst.setSelectedIndices(new int[]{0, 1}); lst.setSelectedIndices(new int[]{0, 1});
@@ -195,8 +150,8 @@ public class FDeckChooser extends JPanel {
lst.setName(ESubmenuConstructedTypes.THEMES.toString()); lst.setName(ESubmenuConstructedTypes.THEMES.toString());
lst.removeMouseListener(madDecklist); lst.removeMouseListener(madDecklist);
final FLabel btn = getBtnRandom(); getBtnRandom().setCommand(new Command() {
btn.setCommand(new Command() { @Override public void execute() { DeckgenUtil.randomSelect(lst); } }); @Override public void execute() { DeckgenUtil.randomSelect(lst); } });
// Init first in list // Init first in list
lst.setSelectedIndex(0); lst.setSelectedIndex(0);
@@ -216,9 +171,8 @@ public class FDeckChooser extends JPanel {
lst.removeMouseListener(madDecklist); lst.removeMouseListener(madDecklist);
lst.addMouseListener(madDecklist); lst.addMouseListener(madDecklist);
final FLabel btn = getBtnRandom(); getBtnRandom().setCommand(new Command() {
@Override public void execute() { DeckgenUtil.randomSelect(lst); } });
btn.setCommand(new Command() { @Override public void execute() { DeckgenUtil.randomSelect(lst); } });
// Init first in list // Init first in list
lst.setSelectedIndex(0); lst.setSelectedIndex(0);
@@ -244,8 +198,8 @@ public class FDeckChooser extends JPanel {
lst.removeMouseListener(madDecklist); lst.removeMouseListener(madDecklist);
lst.addMouseListener(madDecklist); lst.addMouseListener(madDecklist);
final FLabel btn = getBtnRandom(); getBtnRandom().setCommand(new Command() {
btn.setCommand(new Command() { @Override public void execute() { DeckgenUtil.randomSelect(lst); } }); @Override public void execute() { DeckgenUtil.randomSelect(lst); } });
// Init first in list // Init first in list
lst.setSelectedIndex(0); lst.setSelectedIndex(0);
@@ -281,24 +235,14 @@ public class FDeckChooser extends JPanel {
return deck; return deck;
} }
/**
* TODO: Write javadoc for this method.
* @return
*/
private PlayerType getPlayerType() { private PlayerType getPlayerType() {
return playerType; return playerType;
} }
/**
* TODO: Write javadoc for this method.
*/
public void populate() { public void populate() {
this.setLayout(new MigLayout("insets 0, gap 0, flowy, ax right")); this.setLayout(new MigLayout("insets 0, gap 0, flowy, ax right"));
this.add(pnlRadios, "w 100%!, gap 0 0 20px 20px"); this.add(pnlRadios, "w 100%!, gap 0 0 20px 20px");
this.add(scrDecks, "w 100%!, growy, pushy"); this.add(scrDecks, "w 100%!, growy, pushy");
} }
} }

View File

@@ -0,0 +1,366 @@
/*
* Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// move from original package (org.jdesktop.swinghelper.buttonpanel) to keep with other gui widgets
package forge.gui.toolbox;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.KeyboardFocusManager;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.DefaultButtonModel;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.LayoutFocusTraversalPolicy;
import net.miginfocom.swing.MigLayout;
/**
* This is a JPanel subclass which provides a special functionality
* for its children buttons components.
* It makes it possible to transfer focus from button to button
* with help of arrows keys.
* <p>The following example shows how to enable cyclic focus transfer
* <pre>
* import org.jdesktop.swinghelper.buttonpanel.*;
* import javax.swing.*;
*
* public class SimpleDemo {
* public static void main(String[] args) throws Exception {
* SwingUtilities.invokeLater(new Runnable() {
* public void run() {
* final JFrame frame = new JFrame();
* frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
*
* JXButtonPanel panel = new JXButtonPanel();
* panel.setCyclic(true);
*
* panel.add(new JButton("One"));
* panel.add(new JButton("Two"));
* panel.add(new JButton("Three"));
*
* frame.add(panel);
* frame.setSize(200, 200);
* frame.setLocationRelativeTo(null);
* frame.setVisible(true);
* }
* });
* }
* }
* </pre>
*
* If your buttons inside JXButtonPanel are added to one ButtonGroup
* arrow keys will transfer selection between them as well as they do it for focus<p>
* Note: you can control this behaviour with setGroupSelectionFollowFocus(boolean)
* <pre>
* import org.jdesktop.swinghelper.buttonpanel.*;
* import javax.swing.*;
*
* public class RadioButtonDemo {
* public static void main(String[] args) throws Exception {
* SwingUtilities.invokeLater(new Runnable() {
* public void run() {
* final JFrame frame = new JFrame();
* frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
*
* JXButtonPanel panel = new JXButtonPanel();
* ButtonGroup group = new ButtonGroup();
*
* JRadioButton rb1 = new JRadioButton("One");
* panel.add(rb1);
* group.add(rb1);
* JRadioButton rb2 = new JRadioButton("Two");
* panel.add(rb2);
* group.add(rb2);
* JRadioButton rb3 = new JRadioButton("Three");
* panel.add(rb3);
* group.add(rb3);
*
* rb1.setSelected(true);
* frame.add(panel);
*
* frame.setSize(200, 200);
* frame.setLocationRelativeTo(null);
* frame.setVisible(true);
* }
* });
* }
* }
* </pre>
*
* @author Alexander Potochkin
*
* https://swinghelper.dev.java.net/
* http://weblogs.java.net/blog/alexfromsun/
*
* Modified for use by Forge
*/
@SuppressWarnings("serial")
public class JXButtonPanel extends JPanel {
private final ButtonGroup grp = new ButtonGroup();
private boolean isCyclic;
private boolean isGroupSelectionFollowFocus;
public JXButtonPanel() {
this(new MigLayout("wrap, insets 0, gap 0"));
}
public JXButtonPanel(LayoutManager layout) {
super(layout);
init();
}
public JXButtonPanel(boolean isDoubleBuffered) {
super(isDoubleBuffered);
init();
}
public JXButtonPanel(LayoutManager layout, boolean isDoubleBuffered) {
super(layout, isDoubleBuffered);
init();
}
private void init() {
setFocusTraversalPolicyProvider(true);
setFocusTraversalPolicy(new JXButtonPanelFocusTraversalPolicy());
ActionListener actionHandler = new ActionHandler();
registerKeyboardAction(actionHandler, ActionHandler.FORWARD,
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
registerKeyboardAction(actionHandler, ActionHandler.FORWARD,
KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
registerKeyboardAction(actionHandler, ActionHandler.BACKWARD,
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
registerKeyboardAction(actionHandler, ActionHandler.BACKWARD,
KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
setGroupSelectionFollowFocus(true);
// added defaults for Forge
setOpaque(false);
setCyclic(true);
}
/**
* Returns whether arrow keys should support
* cyclic focus traversal ordering for for this JXButtonPanel.
*/
public boolean isCyclic() {
return isCyclic;
}
/**
* Sets whether arrow keys should support
* cyclic focus traversal ordering for this JXButtonPanel.
*/
public void setCyclic(boolean isCyclic) {
this.isCyclic = isCyclic;
}
/**
* Returns whether arrow keys should transfer button's
* selection as well as focus for this JXButtonPanel.<p>
*
* Note: this property affects buttons which are added to a ButtonGroup
*/
public boolean isGroupSelectionFollowFocus() {
return isGroupSelectionFollowFocus;
}
/**
* Sets whether arrow keys should transfer button's
* selection as well as focus for this JXButtonPanel.<p>
*
* Note: this property affects buttons which are added to a ButtonGroup
*/
public void setGroupSelectionFollowFocus(boolean groupSelectionFollowFocus) {
isGroupSelectionFollowFocus = groupSelectionFollowFocus;
}
@Override
public Component add(Component comp) {
Component ret = super.add(comp);
if (comp instanceof AbstractButton) {
grp.add((AbstractButton)comp);
}
return ret;
}
public Component add(Component comp, AbstractButton groupedComp) {
Component ret = super.add(comp);
if (null != groupedComp) {
grp.add(groupedComp);
}
return ret;
}
@Override
public void add(Component comp, Object constraints) {
super.add(comp, constraints);
if (comp instanceof AbstractButton) {
grp.add((AbstractButton)comp);
}
}
public void add(Component comp, AbstractButton groupedComp, Object constraints) {
super.add(comp, constraints);
if (null != groupedComp) {
grp.add(groupedComp);
}
}
@Override
public void add(Component comp, Object constraints, int idx) {
super.add(comp, constraints, idx);
if (comp instanceof AbstractButton) {
grp.add((AbstractButton)comp);
}
}
public void add(Component comp, AbstractButton groupedComp, Object constraints, int idx) {
super.add(comp, constraints, idx);
if (null != groupedComp) {
grp.add(groupedComp);
}
}
private static ButtonGroup getButtonGroup(AbstractButton button) {
ButtonModel model = button.getModel();
if (model instanceof DefaultButtonModel) {
return ((DefaultButtonModel) model).getGroup();
}
return null;
}
private class ActionHandler implements ActionListener {
private static final String FORWARD = "moveSelectionForward";
private static final String BACKWARD = "moveSelectionBackward";
public void actionPerformed(ActionEvent e) {
FocusTraversalPolicy ftp = JXButtonPanel.this.getFocusTraversalPolicy();
if (ftp instanceof JXButtonPanelFocusTraversalPolicy) {
JXButtonPanelFocusTraversalPolicy xftp =
(JXButtonPanelFocusTraversalPolicy) ftp;
String actionCommand = e.getActionCommand();
Component fo =
KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
Component next;
xftp.setAlternativeFocusMode(true);
if (FORWARD.equals(actionCommand)) {
next = xftp.getComponentAfter(JXButtonPanel.this, fo);
} else if (BACKWARD.equals(actionCommand)) {
next = xftp.getComponentBefore(JXButtonPanel.this, fo);
} else {
throw new AssertionError("Unexpected action command: " + actionCommand);
}
xftp.setAlternativeFocusMode(false);
if (fo instanceof AbstractButton) {
AbstractButton b = (AbstractButton) fo;
b.getModel().setPressed(false);
}
if (next != null) {
if (fo instanceof AbstractButton && next instanceof AbstractButton) {
ButtonGroup group = getButtonGroup((AbstractButton) fo);
AbstractButton nextButton = (AbstractButton) next;
if (group != getButtonGroup(nextButton)) {
return;
}
if (isGroupSelectionFollowFocus() && group != null &&
group.getSelection() != null && !nextButton.isSelected()) {
nextButton.setSelected(true);
}
next.requestFocusInWindow();
}
}
}
}
}
private class JXButtonPanelFocusTraversalPolicy extends LayoutFocusTraversalPolicy {
private boolean isAlternativeFocusMode;
public boolean isAlternativeFocusMode() {
return isAlternativeFocusMode;
}
public void setAlternativeFocusMode(boolean alternativeFocusMode) {
isAlternativeFocusMode = alternativeFocusMode;
}
protected boolean accept(Component c) {
if (!isAlternativeFocusMode() && c instanceof AbstractButton) {
AbstractButton button = (AbstractButton) c;
ButtonGroup group = JXButtonPanel.getButtonGroup(button);
if (group != null && group.getSelection() != null
&& !button.isSelected()) {
return false;
}
}
return super.accept(c);
}
public Component getComponentAfter(Container aContainer, Component aComponent) {
Component componentAfter = super.getComponentAfter(aContainer, aComponent);
if (!isAlternativeFocusMode()) {
return componentAfter;
}
if (JXButtonPanel.this.isCyclic()) {
return componentAfter == null ?
getFirstComponent(aContainer) : componentAfter;
}
if (aComponent == getLastComponent(aContainer)) {
return aComponent;
}
return componentAfter;
}
public Component getComponentBefore(Container aContainer, Component aComponent) {
Component componentBefore = super.getComponentBefore(aContainer, aComponent);
if (!isAlternativeFocusMode()) {
return componentBefore;
}
if (JXButtonPanel.this.isCyclic()) {
return componentBefore == null ?
getLastComponent(aContainer) : componentBefore;
}
if (aComponent == getFirstComponent(aContainer)) {
return aComponent;
}
return componentBefore;
}
}
}