mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
- 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:
@@ -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");
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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%!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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} */
|
||||||
|
|||||||
@@ -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()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
366
src/main/java/forge/gui/toolbox/JXButtonPanel.java
Normal file
366
src/main/java/forge/gui/toolbox/JXButtonPanel.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user