mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
checkstyle
This commit is contained in:
@@ -636,7 +636,7 @@ public class BoosterDraftAI {
|
|||||||
BoosterDraftAI.colorToLand.put(Constant.Color.RED, "Mountain");
|
BoosterDraftAI.colorToLand.put(Constant.Color.RED, "Mountain");
|
||||||
BoosterDraftAI.colorToLand.put(Constant.Color.WHITE, "Plains");
|
BoosterDraftAI.colorToLand.put(Constant.Color.WHITE, "Plains");
|
||||||
|
|
||||||
// initilize deck array and playerColors list
|
// Initialize deck array and playerColors list
|
||||||
for (int i = 0; i < this.deck.length; i++) {
|
for (int i = 0; i < this.deck.length; i++) {
|
||||||
this.deck[i] = new CardList();
|
this.deck[i] = new CardList();
|
||||||
this.playerColors.add(new DeckColors());
|
this.playerColors.add(new DeckColors());
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class SealedDeck {
|
|||||||
private final List<Closure1<List<CardPrinted>, BoosterGenerator>> packs = new ArrayList<Closure1<List<CardPrinted>, BoosterGenerator>>();
|
private final List<Closure1<List<CardPrinted>, BoosterGenerator>> packs = new ArrayList<Closure1<List<CardPrinted>, BoosterGenerator>>();
|
||||||
|
|
||||||
/** The Land set code. */
|
/** The Land set code. */
|
||||||
public String LandSetCode[] = { "" };
|
private String[] landSetCode = { "" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -61,7 +61,7 @@ public class SealedDeck {
|
|||||||
this.packs.add(picker);
|
this.packs.add(picker);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.LandSetCode[0] = CardDb.instance().getCard("Plains").getSet();
|
this.getLandSetCode()[0] = CardDb.instance().getCard("Plains").getSet();
|
||||||
} else if (sealedType.equals("Block")) {
|
} else if (sealedType.equals("Block")) {
|
||||||
|
|
||||||
final Object o = GuiUtils.getChoice("Choose Block", SetUtils.getBlocks().toArray());
|
final Object o = GuiUtils.getChoice("Choose Block", SetUtils.getBlocks().toArray());
|
||||||
@@ -102,10 +102,10 @@ public class SealedDeck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.LandSetCode[0] = block.getLandSet().getCode();
|
this.getLandSetCode()[0] = block.getLandSet().getCode();
|
||||||
|
|
||||||
} else if (sealedType.equals("Custom")) {
|
} else if (sealedType.equals("Custom")) {
|
||||||
String dList[];
|
String[] dList;
|
||||||
final ArrayList<CustomLimited> customs = new ArrayList<CustomLimited>();
|
final ArrayList<CustomLimited> customs = new ArrayList<CustomLimited>();
|
||||||
|
|
||||||
// get list of custom draft files
|
// get list of custom draft files
|
||||||
@@ -162,7 +162,7 @@ public class SealedDeck {
|
|||||||
this.packs.add(picker);
|
this.packs.add(picker);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.LandSetCode[0] = draft.LandSetCode;
|
this.getLandSetCode()[0] = draft.LandSetCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,14 +200,14 @@ public class SealedDeck {
|
|||||||
int landsNeeded = 18;
|
int landsNeeded = 18;
|
||||||
int nCreatures = 15;
|
int nCreatures = 15;
|
||||||
|
|
||||||
final CardList AIPlayables = aiCardpool.filter(new CardListFilter() {
|
final CardList aiPlayables = aiCardpool.filter(new CardListFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean addCard(final Card c) {
|
public boolean addCard(final Card c) {
|
||||||
return !(c.getSVar("RemAIDeck").equals("True"));
|
return !(c.getSVar("RemAIDeck").equals("True"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
CardList creatures = AIPlayables.getType("Creature");
|
CardList creatures = aiPlayables.getType("Creature");
|
||||||
CardListUtil.sortByEvaluateCreature(creatures);
|
CardListUtil.sortByEvaluateCreature(creatures);
|
||||||
|
|
||||||
final CardList colorChooserList = new CardList(); // choose colors based
|
final CardList colorChooserList = new CardList(); // choose colors based
|
||||||
@@ -217,8 +217,8 @@ public class SealedDeck {
|
|||||||
colorChooserList.add(creatures.get(i));
|
colorChooserList.add(creatures.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
final int colorCounts[] = { 0, 0, 0, 0, 0 };
|
final int[] colorCounts = { 0, 0, 0, 0, 0 };
|
||||||
final String colors[] = Constant.Color.ONLY_COLORS;
|
final String[] colors = Constant.Color.ONLY_COLORS;
|
||||||
for (int i = 0; i < colors.length; i++) {
|
for (int i = 0; i < colors.length; i++) {
|
||||||
colorCounts[i] = colorChooserList.getColor(colors[i]).size();
|
colorCounts[i] = colorChooserList.getColor(colors[i]).size();
|
||||||
}
|
}
|
||||||
@@ -236,15 +236,15 @@ public class SealedDeck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final DeckColors dcAI = new DeckColors();
|
final DeckColors dcAI = new DeckColors();
|
||||||
dcAI.Color1 = colors[0];
|
dcAI.color1 = colors[0];
|
||||||
dcAI.Color2 = colors[1];
|
dcAI.color2 = colors[1];
|
||||||
dcAI.Splash = colors[2];
|
dcAI.splash = colors[2];
|
||||||
dcAI.Mana1 = dcAI.ColorToMana(colors[0]);
|
dcAI.mana1 = dcAI.colorToMana(colors[0]);
|
||||||
dcAI.Mana2 = dcAI.ColorToMana(colors[1]);
|
dcAI.mana2 = dcAI.colorToMana(colors[1]);
|
||||||
dcAI.ManaS = dcAI.ColorToMana(colors[2]);
|
dcAI.manaS = dcAI.colorToMana(colors[2]);
|
||||||
|
|
||||||
creatures = AIPlayables.getType("Creature").getOnly2Colors(dcAI.Color1, dcAI.Color2);
|
creatures = aiPlayables.getType("Creature").getOnly2Colors(dcAI.color1, dcAI.color2);
|
||||||
creatures.addAll(AIPlayables.getType("Artifact").getType("Creature"));
|
creatures.addAll(aiPlayables.getType("Artifact").getType("Creature"));
|
||||||
|
|
||||||
CardListUtil.sortByEvaluateCreature(creatures);
|
CardListUtil.sortByEvaluateCreature(creatures);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -253,67 +253,67 @@ public class SealedDeck {
|
|||||||
|
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
aiCardpool.remove(c);
|
aiCardpool.remove(c);
|
||||||
AIPlayables.remove(c);
|
aiPlayables.remove(c);
|
||||||
cardsNeeded--;
|
cardsNeeded--;
|
||||||
nCreatures--;
|
nCreatures--;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardList splashCreatures = AIPlayables.getType("Creature").getColor(dcAI.Splash);
|
final CardList splashCreatures = aiPlayables.getType("Creature").getColor(dcAI.splash);
|
||||||
while ((nCreatures > 1) && (splashCreatures.size() > 1)) {
|
while ((nCreatures > 1) && (splashCreatures.size() > 1)) {
|
||||||
final Card c = splashCreatures.get(MyRandom.getRandom().nextInt(splashCreatures.size() - 1));
|
final Card c = splashCreatures.get(MyRandom.getRandom().nextInt(splashCreatures.size() - 1));
|
||||||
|
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
aiCardpool.remove(c);
|
aiCardpool.remove(c);
|
||||||
AIPlayables.remove(c);
|
aiPlayables.remove(c);
|
||||||
splashCreatures.remove(c);
|
splashCreatures.remove(c);
|
||||||
cardsNeeded--;
|
cardsNeeded--;
|
||||||
nCreatures--;
|
nCreatures--;
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardList walkers = AIPlayables.getType("Planeswalker").getOnly2Colors(dcAI.Color1, dcAI.Color2);
|
final CardList walkers = aiPlayables.getType("Planeswalker").getOnly2Colors(dcAI.color1, dcAI.color2);
|
||||||
if (walkers.size() > 0) {
|
if (walkers.size() > 0) {
|
||||||
deck.add(walkers.get(0));
|
deck.add(walkers.get(0));
|
||||||
AIPlayables.remove(walkers.get(0));
|
aiPlayables.remove(walkers.get(0));
|
||||||
aiCardpool.remove(walkers.get(0));
|
aiCardpool.remove(walkers.get(0));
|
||||||
cardsNeeded--;
|
cardsNeeded--;
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardList spells = AIPlayables.getType("Instant").getOnly2Colors(dcAI.Color1, dcAI.Color2);
|
final CardList spells = aiPlayables.getType("Instant").getOnly2Colors(dcAI.color1, dcAI.color2);
|
||||||
spells.addAll(AIPlayables.getType("Sorcery").getOnly2Colors(dcAI.Color1, dcAI.Color2));
|
spells.addAll(aiPlayables.getType("Sorcery").getOnly2Colors(dcAI.color1, dcAI.color2));
|
||||||
spells.addAll(AIPlayables.getType("Enchantment").getOnly2Colors(dcAI.Color1, dcAI.Color2));
|
spells.addAll(aiPlayables.getType("Enchantment").getOnly2Colors(dcAI.color1, dcAI.color2));
|
||||||
|
|
||||||
while ((cardsNeeded > 0) && (spells.size() > 1)) {
|
while ((cardsNeeded > 0) && (spells.size() > 1)) {
|
||||||
final Card c = spells.get(MyRandom.getRandom().nextInt(spells.size() - 1));
|
final Card c = spells.get(MyRandom.getRandom().nextInt(spells.size() - 1));
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
spells.remove(c);
|
spells.remove(c);
|
||||||
AIPlayables.remove(c);
|
aiPlayables.remove(c);
|
||||||
aiCardpool.remove(c);
|
aiCardpool.remove(c);
|
||||||
cardsNeeded--;
|
cardsNeeded--;
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardList splashSpells = AIPlayables.getType("Instant").getColor(dcAI.Splash);
|
final CardList splashSpells = aiPlayables.getType("Instant").getColor(dcAI.splash);
|
||||||
splashSpells.addAll(AIPlayables.getType("Sorcery").getColor(dcAI.Splash));
|
splashSpells.addAll(aiPlayables.getType("Sorcery").getColor(dcAI.splash));
|
||||||
|
|
||||||
while ((cardsNeeded > 0) && (splashSpells.size() > 1)) {
|
while ((cardsNeeded > 0) && (splashSpells.size() > 1)) {
|
||||||
final Card c = splashSpells.get(MyRandom.getRandom().nextInt(splashSpells.size() - 1));
|
final Card c = splashSpells.get(MyRandom.getRandom().nextInt(splashSpells.size() - 1));
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
splashSpells.remove(c);
|
splashSpells.remove(c);
|
||||||
AIPlayables.remove(c);
|
aiPlayables.remove(c);
|
||||||
aiCardpool.remove(c);
|
aiCardpool.remove(c);
|
||||||
cardsNeeded--;
|
cardsNeeded--;
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardList lands = AIPlayables.getType("Land");
|
final CardList lands = aiPlayables.getType("Land");
|
||||||
if (lands.size() > 0) {
|
if (lands.size() > 0) {
|
||||||
final DeckColors AIdc = dcAI; // just for the filter
|
final DeckColors aiDC = dcAI; // just for the filter
|
||||||
|
|
||||||
lands.filter(new CardListFilter() {
|
lands.filter(new CardListFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean addCard(final Card c) {
|
public boolean addCard(final Card c) {
|
||||||
final ArrayList<Ability_Mana> maList = c.getManaAbility();
|
final ArrayList<Ability_Mana> maList = c.getManaAbility();
|
||||||
for (int j = 0; j < maList.size(); j++) {
|
for (int j = 0; j < maList.size(); j++) {
|
||||||
if (maList.get(j).canProduce(AIdc.Mana1) || maList.get(j).canProduce(AIdc.Mana2)) {
|
if (maList.get(j).canProduce(aiDC.mana1) || maList.get(j).canProduce(aiDC.mana2)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,16 +328,16 @@ public class SealedDeck {
|
|||||||
|
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
aiCardpool.remove(c);
|
aiCardpool.remove(c);
|
||||||
AIPlayables.remove(c);
|
aiPlayables.remove(c);
|
||||||
landsNeeded--;
|
landsNeeded--;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (landsNeeded > 0) // attempt to optimize basic land counts
|
if (landsNeeded > 0) {
|
||||||
// according to color representation
|
// attempt to optimize basic land counts
|
||||||
{
|
// according to color representation
|
||||||
final CCnt ClrCnts[] = { new CCnt("Plains", 0), new CCnt("Island", 0), new CCnt("Swamp", 0),
|
final CCnt[] clrCnts = { new CCnt("Plains", 0), new CCnt("Island", 0), new CCnt("Swamp", 0),
|
||||||
new CCnt("Mountain", 0), new CCnt("Forest", 0) };
|
new CCnt("Mountain", 0), new CCnt("Forest", 0) };
|
||||||
|
|
||||||
// count each card color using mana costs
|
// count each card color using mana costs
|
||||||
@@ -350,15 +350,15 @@ public class SealedDeck {
|
|||||||
final char c = mc.charAt(j);
|
final char c = mc.charAt(j);
|
||||||
|
|
||||||
if (c == 'W') {
|
if (c == 'W') {
|
||||||
ClrCnts[0].setCount(ClrCnts[0].getCount() + 1);
|
clrCnts[0].setCount(clrCnts[0].getCount() + 1);
|
||||||
} else if (c == 'U') {
|
} else if (c == 'U') {
|
||||||
ClrCnts[1].setCount(ClrCnts[1].getCount() + 1);
|
clrCnts[1].setCount(clrCnts[1].getCount() + 1);
|
||||||
} else if (c == 'B') {
|
} else if (c == 'B') {
|
||||||
ClrCnts[2].setCount(ClrCnts[2].getCount() + 1);
|
clrCnts[2].setCount(clrCnts[2].getCount() + 1);
|
||||||
} else if (c == 'R') {
|
} else if (c == 'R') {
|
||||||
ClrCnts[3].setCount(ClrCnts[3].getCount() + 1);
|
clrCnts[3].setCount(clrCnts[3].getCount() + 1);
|
||||||
} else if (c == 'G') {
|
} else if (c == 'G') {
|
||||||
ClrCnts[4].setCount(ClrCnts[4].getCount() + 1);
|
clrCnts[4].setCount(clrCnts[4].getCount() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,25 +366,25 @@ public class SealedDeck {
|
|||||||
// total of all ClrCnts
|
// total of all ClrCnts
|
||||||
int totalColor = 0;
|
int totalColor = 0;
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
totalColor += ClrCnts[i].getCount();
|
totalColor += clrCnts[i].getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
if (ClrCnts[i].getCount() > 0) { // calculate number of
|
if (clrCnts[i].getCount() > 0) { // calculate number of
|
||||||
// lands for
|
// lands for
|
||||||
// each color
|
// each color
|
||||||
final float p = (float) ClrCnts[i].getCount() / (float) totalColor;
|
final float p = (float) clrCnts[i].getCount() / (float) totalColor;
|
||||||
final int nLand = (int) (landsNeeded * p) + 1;
|
final int nLand = (int) (landsNeeded * p) + 1;
|
||||||
// tmpDeck += "nLand-" + ClrCnts[i].Color + ":" + nLand
|
// tmpDeck += "nLand-" + ClrCnts[i].Color + ":" + nLand
|
||||||
// + "\n";
|
// + "\n";
|
||||||
if (Constant.Runtime.DEV_MODE[0]) {
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
System.out.println("Basics[" + ClrCnts[i].getColor() + "]:" + nLand);
|
System.out.println("Basics[" + clrCnts[i].getColor() + "]:" + nLand);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j <= nLand; j++) {
|
for (int j = 0; j <= nLand; j++) {
|
||||||
final Card c = AllZone.getCardFactory().getCard(ClrCnts[i].getColor(),
|
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(),
|
||||||
AllZone.getComputerPlayer());
|
AllZone.getComputerPlayer());
|
||||||
c.setCurSetCode(this.LandSetCode[0]);
|
c.setCurSetCode(this.getLandSetCode()[0]);
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
landsNeeded--;
|
landsNeeded--;
|
||||||
}
|
}
|
||||||
@@ -392,10 +392,10 @@ public class SealedDeck {
|
|||||||
}
|
}
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (landsNeeded > 0) {
|
while (landsNeeded > 0) {
|
||||||
if (ClrCnts[n].getCount() > 0) {
|
if (clrCnts[n].getCount() > 0) {
|
||||||
final Card c = AllZone.getCardFactory().getCard(ClrCnts[n].getColor(),
|
final Card c = AllZone.getCardFactory().getCard(clrCnts[n].getColor(),
|
||||||
AllZone.getComputerPlayer());
|
AllZone.getComputerPlayer());
|
||||||
c.setCurSetCode(this.LandSetCode[0]);
|
c.setCurSetCode(this.getLandSetCode()[0]);
|
||||||
deck.add(c);
|
deck.add(c);
|
||||||
landsNeeded--;
|
landsNeeded--;
|
||||||
|
|
||||||
@@ -423,28 +423,42 @@ public class SealedDeck {
|
|||||||
return aiDeck;
|
return aiDeck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the landSetCode
|
||||||
|
*/
|
||||||
|
public String[] getLandSetCode() {
|
||||||
|
return landSetCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param landSetCode the landSetCode to set
|
||||||
|
*/
|
||||||
|
public void setLandSetCode(String[] landSetCode) {
|
||||||
|
this.landSetCode = landSetCode; // TODO: Add 0 to parameter's name.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class DeckColors.
|
* The Class DeckColors.
|
||||||
*/
|
*/
|
||||||
class DeckColors {
|
class DeckColors {
|
||||||
|
|
||||||
/** The Color1. */
|
/** The Color1. */
|
||||||
public String Color1 = "none";
|
private String color1 = "none";
|
||||||
|
|
||||||
/** The Color2. */
|
/** The Color2. */
|
||||||
public String Color2 = "none";
|
private String color2 = "none";
|
||||||
|
|
||||||
/** The Splash. */
|
/** The Splash. */
|
||||||
public String Splash = "none";
|
private String splash = "none";
|
||||||
|
|
||||||
/** The Mana1. */
|
/** The Mana1. */
|
||||||
public String Mana1 = "";
|
private String mana1 = "";
|
||||||
|
|
||||||
/** The Mana2. */
|
/** The Mana2. */
|
||||||
public String Mana2 = "";
|
private String mana2 = "";
|
||||||
|
|
||||||
/** The Mana s. */
|
/** The Mana s. */
|
||||||
public String ManaS = "";
|
private String manaS = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new deck colors.
|
* Instantiates a new deck colors.
|
||||||
@@ -457,8 +471,8 @@ public class SealedDeck {
|
|||||||
* the sp
|
* the sp
|
||||||
*/
|
*/
|
||||||
public DeckColors(final String c1, final String c2, final String sp) {
|
public DeckColors(final String c1, final String c2, final String sp) {
|
||||||
this.Color1 = c1;
|
this.color1 = c1;
|
||||||
this.Color2 = c2;
|
this.color2 = c2;
|
||||||
// Splash = sp;
|
// Splash = sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,13 +490,13 @@ public class SealedDeck {
|
|||||||
* the color
|
* the color
|
||||||
* @return the string
|
* @return the string
|
||||||
*/
|
*/
|
||||||
public String ColorToMana(final String color) {
|
public String colorToMana(final String color) {
|
||||||
final String Mana[] = { "W", "U", "B", "R", "G" };
|
final String[] mana = { "W", "U", "B", "R", "G" };
|
||||||
final String Clrs[] = { "white", "blue", "black", "red", "green" };
|
final String[] clrs = { "white", "blue", "black", "red", "green" };
|
||||||
|
|
||||||
for (int i = 0; i < Constant.Color.ONLY_COLORS.length; i++) {
|
for (int i = 0; i < Constant.Color.ONLY_COLORS.length; i++) {
|
||||||
if (Clrs[i].equals(color)) {
|
if (clrs[i].equals(color)) {
|
||||||
return Mana[i];
|
return mana[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,22 @@
|
|||||||
|
|
||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowFocusListener;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.AbstractListModel;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
|
||||||
@@ -18,91 +32,104 @@ import forge.gui.game.CardDetailPanel;
|
|||||||
import forge.gui.game.CardPicturePanel;
|
import forge.gui.game.CardPicturePanel;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
|
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.WindowEvent;
|
|
||||||
import java.awt.event.WindowFocusListener;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static java.util.Collections.unmodifiableList;
|
|
||||||
import static javax.swing.JOptionPane.*;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple class that shows a list of cards in a dialog with preview in its right part.
|
* A simple class that shows a list of cards in a dialog with preview in its
|
||||||
*
|
* right part.
|
||||||
|
*
|
||||||
* @author Forge
|
* @author Forge
|
||||||
* @version $Id: ListChooser.java 9708 2011-08-09 19:34:12Z jendave $
|
* @version $Id: ListChooser.java 9708 2011-08-09 19:34:12Z jendave $
|
||||||
*/
|
*/
|
||||||
public class CardListViewer {
|
public class CardListViewer {
|
||||||
|
|
||||||
//Data and number of choices for the list
|
// Data and number of choices for the list
|
||||||
private List<CardPrinted> list;
|
private final List<CardPrinted> list;
|
||||||
|
|
||||||
//Decoration
|
// Decoration
|
||||||
private String title;
|
private final String title;
|
||||||
|
|
||||||
//Flag: was the dialog already shown?
|
// Flag: was the dialog already shown?
|
||||||
private boolean called;
|
private boolean called;
|
||||||
//initialized before; listeners may be added to it
|
// initialized before; listeners may be added to it
|
||||||
private JList jList;
|
private final JList jList;
|
||||||
private CardDetailPanel detail;
|
private final CardDetailPanel detail;
|
||||||
private CardPicturePanel picture;
|
private final CardPicturePanel picture;
|
||||||
|
|
||||||
//Temporarily stored for event handlers during show
|
// Temporarily stored for event handlers during show
|
||||||
private JDialog dialog;
|
private JDialog dialog;
|
||||||
private JOptionPane optionPane;
|
private final JOptionPane optionPane;
|
||||||
private Action ok;
|
private final Action ok;
|
||||||
|
|
||||||
public CardListViewer(String title, List<CardPrinted> list) {
|
/**
|
||||||
|
* Instantiates a new card list viewer.
|
||||||
|
*
|
||||||
|
* @param title the title
|
||||||
|
* @param list the list
|
||||||
|
*/
|
||||||
|
public CardListViewer(final String title, final List<CardPrinted> list) {
|
||||||
this(title, "", list, null);
|
this(title, "", list, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CardListViewer(String title, String message, List<CardPrinted> list) {
|
/**
|
||||||
|
* Instantiates a new card list viewer.
|
||||||
|
*
|
||||||
|
* @param title the title
|
||||||
|
* @param message the message
|
||||||
|
* @param list the list
|
||||||
|
*/
|
||||||
|
public CardListViewer(final String title, final String message, final List<CardPrinted> list) {
|
||||||
this(title, message, list, null);
|
this(title, message, list, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CardListViewer(String title, String message, List<CardPrinted> list, Icon dialogIcon) {
|
/**
|
||||||
|
* Instantiates a new card list viewer.
|
||||||
|
*
|
||||||
|
* @param title the title
|
||||||
|
* @param message the message
|
||||||
|
* @param list the list
|
||||||
|
* @param dialogIcon the dialog icon
|
||||||
|
*/
|
||||||
|
public CardListViewer(final String title, final String message, final List<CardPrinted> list, final Icon dialogIcon) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.list = unmodifiableList(list);
|
this.list = Collections.unmodifiableList(list);
|
||||||
jList = new JList(new ChooserListModel());
|
this.jList = new JList(new ChooserListModel());
|
||||||
detail = new CardDetailPanel(null);
|
this.detail = new CardDetailPanel(null);
|
||||||
picture = new CardPicturePanel(null);
|
this.picture = new CardPicturePanel(null);
|
||||||
ok = new CloseAction(OK_OPTION, "OK");
|
this.ok = new CloseAction(JOptionPane.OK_OPTION, "OK");
|
||||||
|
|
||||||
Object[] options = new Object[]{new JButton(ok)};
|
final Object[] options = new Object[] { new JButton(this.ok) };
|
||||||
|
|
||||||
|
final JPanel threeCols = new JPanel();
|
||||||
|
threeCols.add(new JScrollPane(this.jList));
|
||||||
|
threeCols.add(this.picture);
|
||||||
|
threeCols.add(this.detail);
|
||||||
|
threeCols.setLayout(new java.awt.GridLayout(1, 3, 6, 0));
|
||||||
|
|
||||||
|
this.optionPane = new JOptionPane(new Object[] { message, threeCols }, JOptionPane.INFORMATION_MESSAGE,
|
||||||
|
JOptionPane.DEFAULT_OPTION, dialogIcon, options, options[0]);
|
||||||
|
|
||||||
JPanel threeCols = new JPanel();
|
|
||||||
threeCols.add(new JScrollPane(jList));
|
|
||||||
threeCols.add(picture);
|
|
||||||
threeCols.add(detail);
|
|
||||||
threeCols.setLayout( new java.awt.GridLayout(1, 3, 6, 0) );
|
|
||||||
|
|
||||||
optionPane = new JOptionPane(new Object[]{message, threeCols},
|
|
||||||
INFORMATION_MESSAGE, DEFAULT_OPTION, dialogIcon, options, options[0]);
|
|
||||||
|
|
||||||
// selection is here
|
// selection is here
|
||||||
jList.getSelectionModel().addListSelectionListener(new SelListener());
|
this.jList.getSelectionModel().addListSelectionListener(new SelListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the dialog and returns after the dialog was closed.
|
* Shows the dialog and returns after the dialog was closed.
|
||||||
*
|
*
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean show() {
|
public synchronized boolean show() {
|
||||||
if (called) throw new IllegalStateException("Already shown");
|
if (this.called) {
|
||||||
jList.setSelectedIndex(0);
|
throw new IllegalStateException("Already shown");
|
||||||
|
}
|
||||||
dialog = optionPane.createDialog(optionPane.getParent(), title);
|
this.jList.setSelectedIndex(0);
|
||||||
dialog.setSize(720,360);
|
|
||||||
dialog.addWindowFocusListener(new CardListFocuser());
|
this.dialog = this.optionPane.createDialog(this.optionPane.getParent(), this.title);
|
||||||
dialog.setVisible(true);
|
this.dialog.setSize(720, 360);
|
||||||
dialog.toFront();
|
this.dialog.addWindowFocusListener(new CardListFocuser());
|
||||||
|
this.dialog.setVisible(true);
|
||||||
dialog.dispose();
|
this.dialog.toFront();
|
||||||
called = true;
|
|
||||||
|
this.dialog.dispose();
|
||||||
|
this.called = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,59 +137,70 @@ public class CardListViewer {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 3871965346333840556L;
|
private static final long serialVersionUID = 3871965346333840556L;
|
||||||
|
|
||||||
public int getSize() { return list.size(); }
|
@Override
|
||||||
public Object getElementAt(int index) { return list.get(index); }
|
public int getSize() {
|
||||||
|
return CardListViewer.this.list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getElementAt(final int index) {
|
||||||
|
return CardListViewer.this.list.get(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CloseAction extends AbstractAction {
|
private class CloseAction extends AbstractAction {
|
||||||
|
|
||||||
private static final long serialVersionUID = -8426767786083886936L;
|
private static final long serialVersionUID = -8426767786083886936L;
|
||||||
private int value;
|
private final int value;
|
||||||
|
|
||||||
public CloseAction(int value, String label) {
|
public CloseAction(final int value, final String label) {
|
||||||
super(label);
|
super(label);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(final ActionEvent e) {
|
||||||
optionPane.setValue(value);
|
CardListViewer.this.optionPane.setValue(this.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CardListFocuser implements WindowFocusListener {
|
private class CardListFocuser implements WindowFocusListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowGainedFocus(final WindowEvent e) {
|
public void windowGainedFocus(final WindowEvent e) {
|
||||||
jList.grabFocus();
|
CardListViewer.this.jList.grabFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowLostFocus(final WindowEvent e) { } }
|
public void windowLostFocus(final WindowEvent e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class SelListener implements ListSelectionListener {
|
private class SelListener implements ListSelectionListener {
|
||||||
private Card[] cache = null;
|
private Card[] cache = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void valueChanged(final ListSelectionEvent e) {
|
public void valueChanged(final ListSelectionEvent e) {
|
||||||
int row = jList.getSelectedIndex();
|
final int row = CardListViewer.this.jList.getSelectedIndex();
|
||||||
// (String) jList.getSelectedValue();
|
// (String) jList.getSelectedValue();
|
||||||
if (row >= 0 && row < list.size()) {
|
if ((row >= 0) && (row < CardListViewer.this.list.size())) {
|
||||||
CardPrinted cp = list.get(row);
|
final CardPrinted cp = CardListViewer.this.list.get(row);
|
||||||
ensureCacheHas(row, cp);
|
this.ensureCacheHas(row, cp);
|
||||||
detail.setCard(cache[row]);
|
CardListViewer.this.detail.setCard(this.cache[row]);
|
||||||
picture.setCard(cp);
|
CardListViewer.this.picture.setCard(cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureCacheHas(int row, CardPrinted cp) {
|
private void ensureCacheHas(final int row, final CardPrinted cp) {
|
||||||
if (cache == null) { cache = new Card[list.size()]; }
|
if (this.cache == null) {
|
||||||
if (null == cache[row]) {
|
this.cache = new Card[CardListViewer.this.list.size()];
|
||||||
Card card = AllZone.getCardFactory().getCard(cp.getName(), null);
|
}
|
||||||
|
if (null == this.cache[row]) {
|
||||||
|
final Card card = AllZone.getCardFactory().getCard(cp.getName(), null);
|
||||||
card.setCurSetCode(cp.getSet());
|
card.setCurSetCode(cp.getSet());
|
||||||
card.setImageFilename(CardUtil.buildFilename(card));
|
card.setImageFilename(CardUtil.buildFilename(card));
|
||||||
cache[row] = card;
|
this.cache[row] = card;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,59 +1,67 @@
|
|||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ForgeAction.java
|
* ForgeAction.java
|
||||||
*
|
*
|
||||||
* Created on 02.09.2009
|
* Created on 02.09.2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
|
||||||
import forge.properties.ForgeProps;
|
import forge.properties.ForgeProps;
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class ForgeAction.
|
* The class ForgeAction.
|
||||||
*
|
*
|
||||||
* @author Clemens Koza
|
* @author Clemens Koza
|
||||||
* @version V0.0 02.09.2009
|
* @version V0.0 02.09.2009
|
||||||
*/
|
*/
|
||||||
public abstract class ForgeAction extends AbstractAction {
|
public abstract class ForgeAction extends AbstractAction {
|
||||||
|
|
||||||
/** Constant <code>serialVersionUID=-1881183151063146955L</code> */
|
/** Constant <code>serialVersionUID=-1881183151063146955L</code>. */
|
||||||
private static final long serialVersionUID = -1881183151063146955L;
|
private static final long serialVersionUID = -1881183151063146955L;
|
||||||
private String property;
|
private final String property;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ForgeAction.</p>
|
* <p>
|
||||||
*
|
* Constructor for ForgeAction.
|
||||||
* @param property A Property key containing the keys "/button" and "/menu".
|
* </p>
|
||||||
|
*
|
||||||
|
* @param property
|
||||||
|
* A Property key containing the keys "/button" and "/menu".
|
||||||
*/
|
*/
|
||||||
public ForgeAction(String property) {
|
public ForgeAction(final String property) {
|
||||||
super(ForgeProps.getLocalized(property + "/button"));
|
super(ForgeProps.getLocalized(property + "/button"));
|
||||||
this.property = property;
|
this.property = property;
|
||||||
putValue("buttonText", ForgeProps.getLocalized(property + "/button"));
|
this.putValue("buttonText", ForgeProps.getLocalized(property + "/button"));
|
||||||
putValue("menuText", ForgeProps.getLocalized(property + "/menu"));
|
this.putValue("menuText", ForgeProps.getLocalized(property + "/menu"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Getter for the field <code>property</code>.</p>
|
* <p>
|
||||||
*
|
* Getter for the field <code>property</code>.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
* @return a {@link java.lang.String} object.
|
* @return a {@link java.lang.String} object.
|
||||||
*/
|
*/
|
||||||
protected String getProperty() {
|
protected String getProperty() {
|
||||||
return property;
|
return this.property;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>setupButton.</p>
|
* <p>
|
||||||
|
* setupButton.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
|
* @param <T> a T object.
|
||||||
* @param button a T object.
|
* @param button a T object.
|
||||||
* @return a T object.
|
* @return a T object.
|
||||||
* @param <T> a T object.
|
|
||||||
*/
|
*/
|
||||||
public <T extends AbstractButton> T setupButton(T button) {
|
public <T extends AbstractButton> T setupButton(final T button) {
|
||||||
button.setAction(this);
|
button.setAction(this);
|
||||||
button.setText((String) getValue(button instanceof JMenuItem ? "menuText" : "buttonText"));
|
button.setText((String) this.getValue(button instanceof JMenuItem ? "menuText" : "buttonText"));
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,5 @@
|
|||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
import forge.AllZone;
|
|
||||||
import forge.Card;
|
|
||||||
import forge.properties.ForgeProps;
|
|
||||||
import forge.properties.NewConstants;
|
|
||||||
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JList;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.event.ListSelectionEvent;
|
|
||||||
import javax.swing.event.ListSelectionListener;
|
|
||||||
|
|
||||||
import net.slightlymagic.braids.util.UtilFunctions;
|
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
@@ -28,6 +14,19 @@ import java.util.Collection;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
|
||||||
|
import net.slightlymagic.braids.util.UtilFunctions;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.properties.ForgeProps;
|
||||||
|
import forge.properties.NewConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* GuiUtils class.
|
* GuiUtils class.
|
||||||
@@ -52,13 +51,13 @@ public final class GuiUtils {
|
|||||||
public static void setWidthToMax(final Collection<Component> components) {
|
public static void setWidthToMax(final Collection<Component> components) {
|
||||||
int maxWidth = 0;
|
int maxWidth = 0;
|
||||||
|
|
||||||
for (Component c : components) {
|
for (final Component c : components) {
|
||||||
if (c.getPreferredSize().getWidth() > maxWidth) {
|
if (c.getPreferredSize().getWidth() > maxWidth) {
|
||||||
maxWidth = (int) c.getPreferredSize().getWidth();
|
maxWidth = (int) c.getPreferredSize().getWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Component c : components) {
|
for (final Component c : components) {
|
||||||
c.setMinimumSize(new Dimension(maxWidth, (int) c.getPreferredSize().getHeight()));
|
c.setMinimumSize(new Dimension(maxWidth, (int) c.getPreferredSize().getHeight()));
|
||||||
c.setMaximumSize(new Dimension(maxWidth, (int) c.getPreferredSize().getHeight()));
|
c.setMaximumSize(new Dimension(maxWidth, (int) c.getPreferredSize().getHeight()));
|
||||||
c.setPreferredSize(new Dimension(maxWidth, (int) c.getPreferredSize().getHeight()));
|
c.setPreferredSize(new Dimension(maxWidth, (int) c.getPreferredSize().getHeight()));
|
||||||
@@ -117,7 +116,7 @@ public final class GuiUtils {
|
|||||||
* a int.
|
* a int.
|
||||||
*/
|
*/
|
||||||
public static void setFontSize(final Component component, final int newSize) {
|
public static void setFontSize(final Component component, final int newSize) {
|
||||||
Font oldFont = component.getFont();
|
final Font oldFont = component.getFont();
|
||||||
component.setFont(oldFont.deriveFont((float) newSize));
|
component.setFont(oldFont.deriveFont((float) newSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,8 +130,8 @@ public final class GuiUtils {
|
|||||||
* @return a {@link javax.swing.ImageIcon} object.
|
* @return a {@link javax.swing.ImageIcon} object.
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getIconFromFile(final String filename) {
|
public static ImageIcon getIconFromFile(final String filename) {
|
||||||
File base = ForgeProps.getFile(NewConstants.IMAGE_ICON);
|
final File base = ForgeProps.getFile(NewConstants.IMAGE_ICON);
|
||||||
File file = new File(base, filename);
|
final File file = new File(base, filename);
|
||||||
if (filename.equals("") || !file.exists()) {
|
if (filename.equals("") || !file.exists()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@@ -145,15 +144,17 @@ public final class GuiUtils {
|
|||||||
* getResizedIcon.
|
* getResizedIcon.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param filename String.
|
* @param filename
|
||||||
* @param scale Double.
|
* String.
|
||||||
|
* @param scale
|
||||||
|
* Double.
|
||||||
* @return {@link javax.swing.ImageIcon} object
|
* @return {@link javax.swing.ImageIcon} object
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getResizedIcon(final String filename, final double scale) {
|
public static ImageIcon getResizedIcon(final String filename, final double scale) {
|
||||||
ImageIcon icon = getIconFromFile(filename);
|
final ImageIcon icon = GuiUtils.getIconFromFile(filename);
|
||||||
|
|
||||||
int w = (int) (icon.getIconWidth() * scale);
|
final int w = (int) (icon.getIconWidth() * scale);
|
||||||
int h = (int) (icon.getIconHeight() * scale);
|
final int h = (int) (icon.getIconHeight() * scale);
|
||||||
|
|
||||||
return new ImageIcon(icon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH));
|
return new ImageIcon(icon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH));
|
||||||
}
|
}
|
||||||
@@ -163,13 +164,15 @@ public final class GuiUtils {
|
|||||||
* getResizedIcon.
|
* getResizedIcon.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param icon ImageIcon
|
* @param icon
|
||||||
* @param scale Double
|
* ImageIcon
|
||||||
|
* @param scale
|
||||||
|
* Double
|
||||||
* @return {@link javax.swing.ImageIcon} object
|
* @return {@link javax.swing.ImageIcon} object
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getResizedIcon(final ImageIcon icon, final double scale) {
|
public static ImageIcon getResizedIcon(final ImageIcon icon, final double scale) {
|
||||||
int w = (int) (icon.getIconWidth() * scale);
|
final int w = (int) (icon.getIconWidth() * scale);
|
||||||
int h = (int) (icon.getIconHeight() * scale);
|
final int h = (int) (icon.getIconHeight() * scale);
|
||||||
|
|
||||||
return new ImageIcon(icon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH));
|
return new ImageIcon(icon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH));
|
||||||
}
|
}
|
||||||
@@ -208,54 +211,44 @@ public final class GuiUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience for getChoices(message, 0, 1, choices).
|
* Convenience for getChoices(message, 0, 1, choices).
|
||||||
*
|
*
|
||||||
* @see #getChoices(String, int, int, Object...)
|
* @param <T> is automatically inferred.
|
||||||
*
|
* @param message a {@link java.lang.String} object.
|
||||||
* @param message
|
* @param choices a T object.
|
||||||
* a {@link java.lang.String} object.
|
|
||||||
* @param choices
|
|
||||||
* a T object.
|
|
||||||
* @param <T>
|
|
||||||
* is automatically inferred.
|
|
||||||
*
|
|
||||||
* @return null if choices is missing, empty, or if the users' choices are
|
* @return null if choices is missing, empty, or if the users' choices are
|
||||||
* empty; otherwise, returns the first item in the List returned by
|
* empty; otherwise, returns the first item in the List returned by
|
||||||
* getChoices.
|
* getChoices.
|
||||||
|
* @see #getChoices(String, int, int, Object...)
|
||||||
*/
|
*/
|
||||||
public static <T> T getChoiceOptional(final String message, final T... choices) {
|
public static <T> T getChoiceOptional(final String message, final T... choices) {
|
||||||
if (choices == null || choices.length == 0) {
|
if ((choices == null) || (choices.length == 0)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
List<T> choice = getChoices(message, 0, 1, choices);
|
final List<T> choice = GuiUtils.getChoices(message, 0, 1, choices);
|
||||||
return choice.isEmpty() ? null : choice.get(0);
|
return choice.isEmpty() ? null : choice.get(0);
|
||||||
} // getChoiceOptional(String,T...)
|
} // getChoiceOptional(String,T...)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like getChoiceOptional, but this takes an Iterator instead of a variable
|
* Like getChoiceOptional, but this takes an Iterator instead of a variable
|
||||||
* number of arguments.
|
* number of arguments.
|
||||||
*
|
*
|
||||||
*
|
* @param <T> is automatically inferred.
|
||||||
* @param message
|
* @param message a {@link java.lang.String} object.
|
||||||
* a {@link java.lang.String} object.
|
* @param choices an Iterator over T objects.
|
||||||
* @param choices
|
|
||||||
* an Iterator over T objects.
|
|
||||||
* @param <T>
|
|
||||||
* is automatically inferred.
|
|
||||||
*
|
|
||||||
* @return null if choices is missing, empty, or if the users' choices are
|
* @return null if choices is missing, empty, or if the users' choices are
|
||||||
* empty; otherwise, returns the first item in the List returned by
|
* empty; otherwise, returns the first item in the List returned by
|
||||||
* getChoices.
|
* getChoices.
|
||||||
*/
|
*/
|
||||||
public static <T> T getChoiceOptional(final String message, final Iterator<T> choices) {
|
public static <T> T getChoiceOptional(final String message, final Iterator<T> choices) {
|
||||||
if (choices == null | !choices.hasNext()) {
|
if ((choices == null) | !choices.hasNext()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this is an expensive operation; it would be better to
|
// TODO this is an expensive operation; it would be better to
|
||||||
// update getChoices to accept an Iterator.
|
// update getChoices to accept an Iterator.
|
||||||
T[] choicesArray = UtilFunctions.iteratorToArray(choices);
|
final T[] choicesArray = UtilFunctions.iteratorToArray(choices);
|
||||||
|
|
||||||
List<T> choice = getChoices(message, 0, 1, choicesArray);
|
final List<T> choice = GuiUtils.getChoices(message, 0, 1, choicesArray);
|
||||||
return choice.isEmpty() ? null : choice.get(0);
|
return choice.isEmpty() ? null : choice.get(0);
|
||||||
} // getChoiceOptional(String,Iterator<T>)
|
} // getChoiceOptional(String,Iterator<T>)
|
||||||
|
|
||||||
@@ -264,17 +257,14 @@ public final class GuiUtils {
|
|||||||
* <p>
|
* <p>
|
||||||
* getChoice.
|
* getChoice.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param message
|
* @param <T> a T object.
|
||||||
* a {@link java.lang.String} object.
|
* @param message a {@link java.lang.String} object.
|
||||||
* @param choices
|
* @param choices a T object.
|
||||||
* a T object.
|
|
||||||
* @param <T>
|
|
||||||
* a T object.
|
|
||||||
* @return a T object.
|
* @return a T object.
|
||||||
*/
|
*/
|
||||||
public static <T> T getChoice(final String message, final T... choices) {
|
public static <T> T getChoice(final String message, final T... choices) {
|
||||||
List<T> choice = getChoices(message, 1, 1, choices);
|
final List<T> choice = GuiUtils.getChoices(message, 1, 1, choices);
|
||||||
assert choice.size() == 1;
|
assert choice.size() == 1;
|
||||||
return choice.get(0);
|
return choice.get(0);
|
||||||
} // getChoice()
|
} // getChoice()
|
||||||
@@ -284,17 +274,14 @@ public final class GuiUtils {
|
|||||||
* <p>
|
* <p>
|
||||||
* getChoicesOptional.
|
* getChoicesOptional.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param message
|
* @param <T> a T object.
|
||||||
* a {@link java.lang.String} object.
|
* @param message a {@link java.lang.String} object.
|
||||||
* @param choices
|
* @param choices a T object.
|
||||||
* a T object.
|
|
||||||
* @param <T>
|
|
||||||
* a T object.
|
|
||||||
* @return a {@link java.util.List} object.
|
* @return a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public static <T> List<T> getChoicesOptional(final String message, final T... choices) {
|
public static <T> List<T> getChoicesOptional(final String message, final T... choices) {
|
||||||
return getChoices(message, 0, choices.length, choices);
|
return GuiUtils.getChoices(message, 0, choices.length, choices);
|
||||||
} // getChoice()
|
} // getChoice()
|
||||||
|
|
||||||
// returned Object will never be null
|
// returned Object will never be null
|
||||||
@@ -302,17 +289,14 @@ public final class GuiUtils {
|
|||||||
* <p>
|
* <p>
|
||||||
* getChoices.
|
* getChoices.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param message
|
* @param <T> a T object.
|
||||||
* a {@link java.lang.String} object.
|
* @param message a {@link java.lang.String} object.
|
||||||
* @param choices
|
* @param choices a T object.
|
||||||
* a T object.
|
|
||||||
* @param <T>
|
|
||||||
* a T object.
|
|
||||||
* @return a {@link java.util.List} object.
|
* @return a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public static <T> List<T> getChoices(final String message, final T... choices) {
|
public static <T> List<T> getChoices(final String message, final T... choices) {
|
||||||
return getChoices(message, 1, choices.length, choices);
|
return GuiUtils.getChoices(message, 1, choices.length, choices);
|
||||||
} // getChoice()
|
} // getChoice()
|
||||||
|
|
||||||
// returned Object will never be null
|
// returned Object will never be null
|
||||||
@@ -320,25 +304,21 @@ public final class GuiUtils {
|
|||||||
* <p>
|
* <p>
|
||||||
* getChoices.
|
* getChoices.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param message
|
* @param <T> a T object.
|
||||||
* a {@link java.lang.String} object.
|
* @param message a {@link java.lang.String} object.
|
||||||
* @param min
|
* @param min a int.
|
||||||
* a int.
|
* @param max a int.
|
||||||
* @param max
|
* @param choices a T object.
|
||||||
* a int.
|
|
||||||
* @param choices
|
|
||||||
* a T object.
|
|
||||||
* @param <T>
|
|
||||||
* a T object.
|
|
||||||
* @return a {@link java.util.List} object.
|
* @return a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public static <T> List<T> getChoices(final String message, final int min, final int max, final T... choices) {
|
public static <T> List<T> getChoices(final String message, final int min, final int max, final T... choices) {
|
||||||
ListChooser<T> c = new ListChooser<T>(message, min, max, choices);
|
final ListChooser<T> c = new ListChooser<T>(message, min, max, choices);
|
||||||
final JList list = c.getJList();
|
final JList list = c.getJList();
|
||||||
list.addListSelectionListener(new ListSelectionListener() {
|
list.addListSelectionListener(new ListSelectionListener() {
|
||||||
|
@Override
|
||||||
public void valueChanged(final ListSelectionEvent ev) {
|
public void valueChanged(final ListSelectionEvent ev) {
|
||||||
if (list.getSelectedValue() instanceof Card && AllZone.getDisplay() != null) {
|
if ((list.getSelectedValue() instanceof Card) && (AllZone.getDisplay() != null)) {
|
||||||
AllZone.getDisplay().setCard((Card) list.getSelectedValue());
|
AllZone.getDisplay().setCard((Card) list.getSelectedValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,8 +334,8 @@ public final class GuiUtils {
|
|||||||
* a fully laid-out frame
|
* a fully laid-out frame
|
||||||
*/
|
*/
|
||||||
public static void centerFrame(final Window frame) {
|
public static void centerFrame(final Window frame) {
|
||||||
Dimension screen = frame.getToolkit().getScreenSize();
|
final Dimension screen = frame.getToolkit().getScreenSize();
|
||||||
Rectangle bounds = frame.getBounds();
|
final Rectangle bounds = frame.getBounds();
|
||||||
bounds.width = frame.getWidth();
|
bounds.width = frame.getWidth();
|
||||||
bounds.height = frame.getHeight();
|
bounds.height = frame.getHeight();
|
||||||
bounds.x = (screen.width - bounds.width) / 2;
|
bounds.x = (screen.width - bounds.width) / 2;
|
||||||
@@ -367,18 +347,19 @@ public final class GuiUtils {
|
|||||||
* Attempts to create a font from a filename. Concise error reported if
|
* Attempts to create a font from a filename. Concise error reported if
|
||||||
* exceptions found.
|
* exceptions found.
|
||||||
*
|
*
|
||||||
* @param filename String
|
* @param filename
|
||||||
|
* String
|
||||||
* @return Font
|
* @return Font
|
||||||
*/
|
*/
|
||||||
public static Font newFont(final String filename) {
|
public static Font newFont(final String filename) {
|
||||||
File file = new File(filename);
|
final File file = new File(filename);
|
||||||
Font ttf = null;
|
Font ttf = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ttf = Font.createFont(Font.TRUETYPE_FONT, file);
|
ttf = Font.createFont(Font.TRUETYPE_FONT, file);
|
||||||
} catch (FontFormatException e) {
|
} catch (final FontFormatException e) {
|
||||||
System.err.println("GuiUtils > newFont: bad font format \"" + filename + "\"");
|
System.err.println("GuiUtils > newFont: bad font format \"" + filename + "\"");
|
||||||
} catch (IOException e) {
|
} catch (final IOException e) {
|
||||||
System.err.println("GuiUtils > newFont: can't find \"" + filename + "\"");
|
System.err.println("GuiUtils > newFont: can't find \"" + filename + "\"");
|
||||||
}
|
}
|
||||||
return ttf;
|
return ttf;
|
||||||
|
|||||||
@@ -6,279 +6,382 @@
|
|||||||
|
|
||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.event.ListSelectionEvent;
|
|
||||||
import javax.swing.event.ListSelectionListener;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.awt.event.WindowFocusListener;
|
import java.awt.event.WindowFocusListener;
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import javax.swing.AbstractAction;
|
||||||
import static java.util.Collections.unmodifiableList;
|
import javax.swing.AbstractListModel;
|
||||||
import static javax.swing.JOptionPane.*;
|
import javax.swing.Action;
|
||||||
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.WindowConstants;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple class that shows a list of choices in a dialog. Two properties influence the behavior of a list
|
* A simple class that shows a list of choices in a dialog. Two properties
|
||||||
* chooser: minSelection and maxSelection. These two give the allowed number of selected items for the dialog to be
|
* influence the behavior of a list chooser: minSelection and maxSelection.
|
||||||
|
* These two give the allowed number of selected items for the dialog to be
|
||||||
* closed.
|
* closed.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>If minSelection is 0, there will be a Cancel button.</li>
|
* <li>If minSelection is 0, there will be a Cancel button.</li>
|
||||||
* <li>If minSelection is 0 or 1, double-clicking a choice will also close the dialog.</li>
|
* <li>If minSelection is 0 or 1, double-clicking a choice will also close the
|
||||||
* <li>If the number of selections is out of bounds, the "OK" button is disabled.</li>
|
* dialog.</li>
|
||||||
* <li>The dialog was "committed" if "OK" was clicked or a choice was double clicked.</li>
|
* <li>If the number of selections is out of bounds, the "OK" button is
|
||||||
|
* disabled.</li>
|
||||||
|
* <li>The dialog was "committed" if "OK" was clicked or a choice was double
|
||||||
|
* clicked.</li>
|
||||||
* <li>The dialog was "canceled" if "Cancel" or "X" was clicked.</li>
|
* <li>The dialog was "canceled" if "Cancel" or "X" was clicked.</li>
|
||||||
* <li>If the dialog was canceled, the selection will be empty.</li>
|
* <li>If the dialog was canceled, the selection will be empty.</li>
|
||||||
* <li>
|
* <li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
|
* @param <T> the generic type
|
||||||
* @author Forge
|
* @author Forge
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class ListChooser<T> {
|
public class ListChooser<T> {
|
||||||
|
|
||||||
//Data and number of choices for the list
|
// Data and number of choices for the list
|
||||||
private List<T> list;
|
private List<T> list;
|
||||||
private int minChoices, maxChoices;
|
private int minChoices, maxChoices;
|
||||||
|
|
||||||
//Decoration
|
// Decoration
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
//Flag: was the dialog already shown?
|
// Flag: was the dialog already shown?
|
||||||
private boolean called;
|
private boolean called;
|
||||||
//initialized before; listeners may be added to it
|
// initialized before; listeners may be added to it
|
||||||
private JList jList;
|
private JList jList;
|
||||||
//Temporarily stored for event handlers during show
|
// Temporarily stored for event handlers during show
|
||||||
private JDialog d;
|
private JDialog d;
|
||||||
private JOptionPane p;
|
private JOptionPane p;
|
||||||
private Action ok, cancel;
|
private Action ok, cancel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param list a T object.
|
*
|
||||||
|
* @param title
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param list
|
||||||
|
* a T object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, T... list) {
|
public ListChooser(final String title, final T... list) {
|
||||||
this(title, 1, list);
|
this(title, 1, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param numChoices a int.
|
*
|
||||||
* @param list a T object.
|
* @param title
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param numChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a T object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, int numChoices, T... list) {
|
public ListChooser(final String title, final int numChoices, final T... list) {
|
||||||
this(title, numChoices, numChoices, list);
|
this(title, numChoices, numChoices, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param minChoices a int.
|
*
|
||||||
* @param maxChoices a int.
|
* @param title
|
||||||
* @param list a T object.
|
* a {@link java.lang.String} object.
|
||||||
|
* @param minChoices
|
||||||
|
* a int.
|
||||||
|
* @param maxChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a T object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, int minChoices, int maxChoices, T... list) {
|
public ListChooser(final String title, final int minChoices, final int maxChoices, final T... list) {
|
||||||
this(title, null, minChoices, maxChoices, list);
|
this(title, null, minChoices, maxChoices, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param message a {@link java.lang.String} object.
|
*
|
||||||
* @param list a T object.
|
* @param title
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param message
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param list
|
||||||
|
* a T object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, String message, T... list) {
|
public ListChooser(final String title, final String message, final T... list) {
|
||||||
this(title, message, 1, list);
|
this(title, message, 1, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param message a {@link java.lang.String} object.
|
*
|
||||||
* @param numChoices a int.
|
* @param title
|
||||||
* @param list a T object.
|
* a {@link java.lang.String} object.
|
||||||
|
* @param message
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param numChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a T object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, String message, int numChoices, T... list) {
|
public ListChooser(final String title, final String message, final int numChoices, final T... list) {
|
||||||
this(title, message, numChoices, numChoices, list);
|
this(title, message, numChoices, numChoices, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param message a {@link java.lang.String} object.
|
*
|
||||||
* @param minChoices a int.
|
* @param title
|
||||||
* @param maxChoices a int.
|
* a {@link java.lang.String} object.
|
||||||
* @param list a T object.
|
* @param message
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param minChoices
|
||||||
|
* a int.
|
||||||
|
* @param maxChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a T object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, String message, int minChoices, int maxChoices, T... list) {
|
public ListChooser(final String title, final String message, final int minChoices, final int maxChoices,
|
||||||
this(title, message, minChoices, maxChoices, asList(list));
|
final T... list) {
|
||||||
|
this(title, message, minChoices, maxChoices, Arrays.asList(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param list a {@link java.util.List} object.
|
*
|
||||||
|
* @param title
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param list
|
||||||
|
* a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, List<T> list) {
|
public ListChooser(final String title, final List<T> list) {
|
||||||
this(title, 1, list);
|
this(title, 1, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param numChoices a int.
|
*
|
||||||
* @param list a {@link java.util.List} object.
|
* @param title
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param numChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, int numChoices, List<T> list) {
|
public ListChooser(final String title, final int numChoices, final List<T> list) {
|
||||||
this(title, numChoices, numChoices, list);
|
this(title, numChoices, numChoices, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param minChoices a int.
|
*
|
||||||
* @param maxChoices a int.
|
* @param title
|
||||||
* @param list a {@link java.util.List} object.
|
* a {@link java.lang.String} object.
|
||||||
|
* @param minChoices
|
||||||
|
* a int.
|
||||||
|
* @param maxChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, int minChoices, int maxChoices, List<T> list) {
|
public ListChooser(final String title, final int minChoices, final int maxChoices, final List<T> list) {
|
||||||
this(title, null, minChoices, maxChoices, list);
|
this(title, null, minChoices, maxChoices, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param message a {@link java.lang.String} object.
|
*
|
||||||
* @param list a {@link java.util.List} object.
|
* @param title
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param message
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param list
|
||||||
|
* a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, String message, List<T> list) {
|
public ListChooser(final String title, final String message, final List<T> list) {
|
||||||
this(title, message, 1, list);
|
this(title, message, 1, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param message a {@link java.lang.String} object.
|
*
|
||||||
* @param numChoices a int.
|
* @param title
|
||||||
* @param list a {@link java.util.List} object.
|
* a {@link java.lang.String} object.
|
||||||
|
* @param message
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param numChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, String message, int numChoices, List<T> list) {
|
public ListChooser(final String title, final String message, final int numChoices, final List<T> list) {
|
||||||
this(title, message, numChoices, numChoices, list);
|
this(title, message, numChoices, numChoices, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructor for ListChooser.</p>
|
* <p>
|
||||||
*
|
* Constructor for ListChooser.
|
||||||
* @param title a {@link java.lang.String} object.
|
* </p>
|
||||||
* @param message a {@link java.lang.String} object.
|
*
|
||||||
* @param minChoices a int.
|
* @param title
|
||||||
* @param maxChoices a int.
|
* a {@link java.lang.String} object.
|
||||||
* @param list a {@link java.util.List} object.
|
* @param message
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param minChoices
|
||||||
|
* a int.
|
||||||
|
* @param maxChoices
|
||||||
|
* a int.
|
||||||
|
* @param list
|
||||||
|
* a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public ListChooser(String title, String message, int minChoices, int maxChoices, List<T> list) {
|
public ListChooser(final String title, final String message, final int minChoices, final int maxChoices,
|
||||||
|
final List<T> list) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.minChoices = minChoices;
|
this.minChoices = minChoices;
|
||||||
this.maxChoices = maxChoices;
|
this.maxChoices = maxChoices;
|
||||||
this.list = unmodifiableList(list);
|
this.list = Collections.unmodifiableList(list);
|
||||||
jList = new JList(new ChooserListModel());
|
this.jList = new JList(new ChooserListModel());
|
||||||
ok = new CloseAction(OK_OPTION, "OK");
|
this.ok = new CloseAction(JOptionPane.OK_OPTION, "OK");
|
||||||
ok.setEnabled(minChoices == 0);
|
this.ok.setEnabled(minChoices == 0);
|
||||||
cancel = new CloseAction(CANCEL_OPTION, "Cancel");
|
this.cancel = new CloseAction(JOptionPane.CANCEL_OPTION, "Cancel");
|
||||||
|
|
||||||
Object[] options;
|
Object[] options;
|
||||||
if (minChoices == 0) options = new Object[]{new JButton(ok), new JButton(cancel)};
|
if (minChoices == 0) {
|
||||||
else options = new Object[]{new JButton(ok)};
|
options = new Object[] { new JButton(this.ok), new JButton(this.cancel) };
|
||||||
if (maxChoices == 1) { jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); }
|
} else {
|
||||||
|
options = new Object[] { new JButton(this.ok) };
|
||||||
|
}
|
||||||
|
if (maxChoices == 1) {
|
||||||
|
this.jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
}
|
||||||
|
|
||||||
p = new JOptionPane(new Object[]{message, new JScrollPane(jList)}, QUESTION_MESSAGE, DEFAULT_OPTION,
|
this.p = new JOptionPane(new Object[] { message, new JScrollPane(this.jList) }, JOptionPane.QUESTION_MESSAGE,
|
||||||
null, options, options[0]);
|
JOptionPane.DEFAULT_OPTION, null, options, options[0]);
|
||||||
jList.getSelectionModel().addListSelectionListener(new SelListener());
|
this.jList.getSelectionModel().addListSelectionListener(new SelListener());
|
||||||
jList.addMouseListener(new DblListener());
|
this.jList.addMouseListener(new DblListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>getChoices.</p>
|
* <p>
|
||||||
*
|
* getChoices.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
* @return a {@link java.util.List} object.
|
* @return a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public List<T> getChoices() {
|
public List<T> getChoices() {
|
||||||
return list;
|
return this.list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the JList used in the list chooser. this is useful for registering listeners before showing the
|
* Returns the JList used in the list chooser. this is useful for
|
||||||
* dialog.
|
* registering listeners before showing the dialog.
|
||||||
*
|
*
|
||||||
* @return a {@link javax.swing.JList} object.
|
* @return a {@link javax.swing.JList} object.
|
||||||
*/
|
*/
|
||||||
public JList getJList() {
|
public JList getJList() {
|
||||||
return jList;
|
return this.jList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the dialog and returns after the dialog was closed.
|
* Shows the dialog and returns after the dialog was closed.
|
||||||
*
|
*
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean show() {
|
public synchronized boolean show() {
|
||||||
if (called) throw new IllegalStateException("Already shown");
|
if (this.called) {
|
||||||
|
throw new IllegalStateException("Already shown");
|
||||||
|
}
|
||||||
Integer value;
|
Integer value;
|
||||||
do {
|
do {
|
||||||
d = p.createDialog(p.getParent(), title);
|
this.d = this.p.createDialog(this.p.getParent(), this.title);
|
||||||
if (minChoices != 0) d.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
if (this.minChoices != 0) {
|
||||||
jList.setSelectedIndex(0);
|
this.d.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
d.addWindowFocusListener(new WindowFocusListener() {
|
}
|
||||||
@Override public void windowGainedFocus(final WindowEvent e) { jList.grabFocus(); }
|
this.jList.setSelectedIndex(0);
|
||||||
@Override public void windowLostFocus(final WindowEvent e) { }
|
this.d.addWindowFocusListener(new WindowFocusListener() {
|
||||||
|
@Override
|
||||||
|
public void windowGainedFocus(final WindowEvent e) {
|
||||||
|
ListChooser.this.jList.grabFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowLostFocus(final WindowEvent e) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
d.setVisible(true);
|
this.d.setVisible(true);
|
||||||
d.dispose();
|
this.d.dispose();
|
||||||
value = (Integer) p.getValue();
|
value = (Integer) this.p.getValue();
|
||||||
if (value == null || value != OK_OPTION) jList.clearSelection();
|
if ((value == null) || (value != JOptionPane.OK_OPTION)) {
|
||||||
//can't stop closing by ESC, so repeat if cancelled
|
this.jList.clearSelection();
|
||||||
} while (minChoices != 0 && value != OK_OPTION);
|
// can't stop closing by ESC, so repeat if cancelled
|
||||||
//this assert checks if we really don't return on a cancel if input is mandatory
|
}
|
||||||
assert minChoices == 0 || value == OK_OPTION;
|
} while ((this.minChoices != 0) && (value != JOptionPane.OK_OPTION));
|
||||||
called = true;
|
// this assert checks if we really don't return on a cancel if input is
|
||||||
return value != null && value == OK_OPTION;
|
// mandatory
|
||||||
|
assert (this.minChoices == 0) || (value == JOptionPane.OK_OPTION);
|
||||||
|
this.called = true;
|
||||||
|
return (value != null) && (value == JOptionPane.OK_OPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the dialog was closed by pressing "OK" or double clicking an option the last time
|
* Returns if the dialog was closed by pressing "OK" or double clicking an
|
||||||
|
* option the last time.
|
||||||
*
|
*
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public boolean isCommitted() {
|
public boolean isCommitted() {
|
||||||
if (!called) throw new IllegalStateException("not yet shown");
|
if (!this.called) {
|
||||||
return (Integer) p.getValue() == OK_OPTION;
|
throw new IllegalStateException("not yet shown");
|
||||||
|
}
|
||||||
|
return (Integer) this.p.getValue() == JOptionPane.OK_OPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the selected indices as a list of integers
|
* Returns the selected indices as a list of integers.
|
||||||
*
|
*
|
||||||
* @return a {@link java.util.List} object.
|
* @return a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public List<Integer> getSelectedIndices() {
|
public List<Integer> getSelectedIndices() {
|
||||||
if (!called) throw new IllegalStateException("not yet shown");
|
if (!this.called) {
|
||||||
final int[] indices = jList.getSelectedIndices();
|
throw new IllegalStateException("not yet shown");
|
||||||
|
}
|
||||||
|
final int[] indices = this.jList.getSelectedIndices();
|
||||||
return new AbstractList<Integer>() {
|
return new AbstractList<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
@@ -286,20 +389,23 @@ public class ListChooser<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer get(int index) {
|
public Integer get(final int index) {
|
||||||
return indices[index];
|
return indices[index];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the selected values as a list of objects. no casts are necessary when retrieving the objects.
|
* Returns the selected values as a list of objects. no casts are necessary
|
||||||
*
|
* when retrieving the objects.
|
||||||
|
*
|
||||||
* @return a {@link java.util.List} object.
|
* @return a {@link java.util.List} object.
|
||||||
*/
|
*/
|
||||||
public List<T> getSelectedValues() {
|
public List<T> getSelectedValues() {
|
||||||
if (!called) throw new IllegalStateException("not yet shown");
|
if (!this.called) {
|
||||||
final Object[] selected = jList.getSelectedValues();
|
throw new IllegalStateException("not yet shown");
|
||||||
|
}
|
||||||
|
final Object[] selected = this.jList.getSelectedValues();
|
||||||
return new AbstractList<T>() {
|
return new AbstractList<T>() {
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
@@ -308,82 +414,95 @@ public class ListChooser<T> {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public T get(int index) {
|
public T get(final int index) {
|
||||||
return (T) selected[index];
|
return (T) selected[index];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the (minimum) selected index, or -1
|
* Returns the (minimum) selected index, or -1.
|
||||||
*
|
*
|
||||||
* @return a int.
|
* @return a int.
|
||||||
*/
|
*/
|
||||||
public int getSelectedIndex() {
|
public int getSelectedIndex() {
|
||||||
if (!called) throw new IllegalStateException("not yet shown");
|
if (!this.called) {
|
||||||
return jList.getSelectedIndex();
|
throw new IllegalStateException("not yet shown");
|
||||||
|
}
|
||||||
|
return this.jList.getSelectedIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the (first) selected value, or null
|
* Returns the (first) selected value, or null.
|
||||||
*
|
*
|
||||||
* @return a T object.
|
* @return a T object.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T getSelectedValue() {
|
public T getSelectedValue() {
|
||||||
if (!called) throw new IllegalStateException("not yet shown");
|
if (!this.called) {
|
||||||
return (T) jList.getSelectedValue();
|
throw new IllegalStateException("not yet shown");
|
||||||
|
}
|
||||||
|
return (T) this.jList.getSelectedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>commit.</p>
|
* <p>
|
||||||
|
* commit.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
private void commit() {
|
private void commit() {
|
||||||
if (ok.isEnabled()) p.setValue(OK_OPTION);
|
if (this.ok.isEnabled()) {
|
||||||
|
this.p.setValue(JOptionPane.OK_OPTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ChooserListModel extends AbstractListModel {
|
private class ChooserListModel extends AbstractListModel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3871965346333840556L;
|
private static final long serialVersionUID = 3871965346333840556L;
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return list.size();
|
return ListChooser.this.list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Object getElementAt(int index) {
|
public Object getElementAt(final int index) {
|
||||||
return list.get(index);
|
return ListChooser.this.list.get(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CloseAction extends AbstractAction {
|
private class CloseAction extends AbstractAction {
|
||||||
|
|
||||||
private static final long serialVersionUID = -8426767786083886936L;
|
private static final long serialVersionUID = -8426767786083886936L;
|
||||||
private int value;
|
private final int value;
|
||||||
|
|
||||||
public CloseAction(int value, String label) {
|
public CloseAction(final int value, final String label) {
|
||||||
super(label);
|
super(label);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(final ActionEvent e) {
|
||||||
p.setValue(value);
|
ListChooser.this.p.setValue(this.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SelListener implements ListSelectionListener {
|
private class SelListener implements ListSelectionListener {
|
||||||
|
|
||||||
public void valueChanged(ListSelectionEvent e) {
|
@Override
|
||||||
int num = jList.getSelectedIndices().length;
|
public void valueChanged(final ListSelectionEvent e) {
|
||||||
ok.setEnabled(num >= minChoices && num <= maxChoices);
|
final int num = ListChooser.this.jList.getSelectedIndices().length;
|
||||||
|
ListChooser.this.ok
|
||||||
|
.setEnabled((num >= ListChooser.this.minChoices) && (num <= ListChooser.this.maxChoices));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DblListener extends MouseAdapter {
|
private class DblListener extends MouseAdapter {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(final MouseEvent e) {
|
||||||
if (e.getClickCount() == 2) commit();
|
if (e.getClickCount() == 2) {
|
||||||
|
ListChooser.this.commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
import javax.swing.*;
|
import java.awt.Rectangle;
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link JLabel} with support for multi-line text that wraps when the line
|
* A {@link JLabel} with support for multi-line text that wraps when the line
|
||||||
@@ -33,7 +34,7 @@ import java.awt.*;
|
|||||||
* {@link MultiLineLabelUI}, the default UI delegate of this component. The text
|
* {@link MultiLineLabelUI}, the default UI delegate of this component. The text
|
||||||
* in the label can be horizontally and vertically aligned, relative to the
|
* in the label can be horizontally and vertically aligned, relative to the
|
||||||
* bounds of the component.
|
* bounds of the component.
|
||||||
*
|
*
|
||||||
* @author Samuel Sjoberg, http://samuelsjoberg.com
|
* @author Samuel Sjoberg, http://samuelsjoberg.com
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
@@ -47,12 +48,12 @@ public class MultiLineLabel extends JLabel {
|
|||||||
/**
|
/**
|
||||||
* Horizontal text alignment.
|
* Horizontal text alignment.
|
||||||
*/
|
*/
|
||||||
private int halign = LEFT;
|
private int halign = SwingConstants.LEFT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vertical text alignment.
|
* Vertical text alignment.
|
||||||
*/
|
*/
|
||||||
private int valign = CENTER;
|
private int valign = SwingConstants.CENTER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache to save heap allocations.
|
* Cache to save heap allocations.
|
||||||
@@ -64,66 +65,70 @@ public class MultiLineLabel extends JLabel {
|
|||||||
*/
|
*/
|
||||||
public MultiLineLabel() {
|
public MultiLineLabel() {
|
||||||
super();
|
super();
|
||||||
setUI(MultiLineLabelUI.labelUI);
|
this.setUI(MultiLineLabelUI.getLabelUI());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new label with <code>text</code> value.
|
* Creates a new label with <code>text</code> value.
|
||||||
*
|
*
|
||||||
* @param text the value of the label
|
* @param text
|
||||||
|
* the value of the label
|
||||||
*/
|
*/
|
||||||
public MultiLineLabel(String text) {
|
public MultiLineLabel(final String text) {
|
||||||
this();
|
this();
|
||||||
setText(text);
|
this.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* @return a {@link java.awt.Rectangle} object.
|
* @return a {@link java.awt.Rectangle} object.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Rectangle getBounds() {
|
public Rectangle getBounds() {
|
||||||
if (bounds == null) {
|
if (this.bounds == null) {
|
||||||
bounds = new Rectangle();
|
this.bounds = new Rectangle();
|
||||||
}
|
}
|
||||||
return super.getBounds(bounds);
|
return super.getBounds(this.bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the vertical text alignment.
|
* Set the vertical text alignment.
|
||||||
*
|
*
|
||||||
* @param alignment vertical alignment
|
* @param alignment
|
||||||
|
* vertical alignment
|
||||||
*/
|
*/
|
||||||
public void setVerticalTextAlignment(int alignment) {
|
public void setVerticalTextAlignment(final int alignment) {
|
||||||
firePropertyChange("verticalTextAlignment", valign, alignment);
|
this.firePropertyChange("verticalTextAlignment", this.valign, alignment);
|
||||||
valign = alignment;
|
this.valign = alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the horizontal text alignment.
|
* Set the horizontal text alignment.
|
||||||
*
|
*
|
||||||
* @param alignment horizontal alignment
|
* @param alignment
|
||||||
|
* horizontal alignment
|
||||||
*/
|
*/
|
||||||
public void setHorizontalTextAlignment(int alignment) {
|
public void setHorizontalTextAlignment(final int alignment) {
|
||||||
firePropertyChange("horizontalTextAlignment", halign, alignment);
|
this.firePropertyChange("horizontalTextAlignment", this.halign, alignment);
|
||||||
halign = alignment;
|
this.halign = alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the vertical text alignment.
|
* Get the vertical text alignment.
|
||||||
*
|
*
|
||||||
* @return vertical text alignment
|
* @return vertical text alignment
|
||||||
*/
|
*/
|
||||||
public int getVerticalTextAlignment() {
|
public int getVerticalTextAlignment() {
|
||||||
return valign;
|
return this.valign;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the horizontal text alignment.
|
* Get the horizontal text alignment.
|
||||||
*
|
*
|
||||||
* @return horizontal text alignment
|
* @return horizontal text alignment
|
||||||
*/
|
*/
|
||||||
public int getHorizontalTextAlignment() {
|
public int getHorizontalTextAlignment() {
|
||||||
return halign;
|
return this.halign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,11 @@
|
|||||||
*/
|
*/
|
||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
import javax.swing.*;
|
import java.awt.Dimension;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import java.awt.FontMetrics;
|
||||||
import javax.swing.plaf.LabelUI;
|
import java.awt.Graphics;
|
||||||
import javax.swing.plaf.basic.BasicLabelUI;
|
import java.awt.Insets;
|
||||||
import javax.swing.text.*;
|
import java.awt.Rectangle;
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.awt.event.ComponentListener;
|
import java.awt.event.ComponentListener;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
@@ -36,6 +35,20 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.LabelUI;
|
||||||
|
import javax.swing.plaf.basic.BasicLabelUI;
|
||||||
|
import javax.swing.text.BadLocationException;
|
||||||
|
import javax.swing.text.Document;
|
||||||
|
import javax.swing.text.Element;
|
||||||
|
import javax.swing.text.PlainDocument;
|
||||||
|
import javax.swing.text.Segment;
|
||||||
|
import javax.swing.text.Utilities;
|
||||||
|
import javax.swing.text.View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Label UI delegate that supports multiple lines and line wrapping. Hard line
|
* Label UI delegate that supports multiple lines and line wrapping. Hard line
|
||||||
@@ -49,6 +62,7 @@ import java.util.List;
|
|||||||
* <p/>
|
* <p/>
|
||||||
* Example of usage:
|
* Example of usage:
|
||||||
* <p/>
|
* <p/>
|
||||||
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* JLabel myLabel = new JLabel();
|
* JLabel myLabel = new JLabel();
|
||||||
* myLabel.setUI(MultiLineLabelUI.labelUI);
|
* myLabel.setUI(MultiLineLabelUI.labelUI);
|
||||||
@@ -61,7 +75,7 @@ import java.util.List;
|
|||||||
* by overriding {@link #paintEnabledText(JLabel, Graphics, String, int, int)}
|
* by overriding {@link #paintEnabledText(JLabel, Graphics, String, int, int)}
|
||||||
* and {@link #paintDisabledText(JLabel, Graphics, String, int, int)}. This
|
* and {@link #paintDisabledText(JLabel, Graphics, String, int, int)}. This
|
||||||
* class is designed to be easily extended by subclasses.
|
* class is designed to be easily extended by subclasses.
|
||||||
*
|
*
|
||||||
* @author Samuel Sjoberg, http://samuelsjoberg.com
|
* @author Samuel Sjoberg, http://samuelsjoberg.com
|
||||||
* @version 1.3.0
|
* @version 1.3.0
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +84,7 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
/**
|
/**
|
||||||
* Shared instance of the UI delegate.
|
* Shared instance of the UI delegate.
|
||||||
*/
|
*/
|
||||||
public static LabelUI labelUI = new MultiLineLabelUI();
|
private static LabelUI labelUI = new MultiLineLabelUI();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client property key used to store the calculated wrapped lines on the
|
* Client property key used to store the calculated wrapped lines on the
|
||||||
@@ -79,187 +93,213 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
public static final String PROPERTY_KEY = "WrappedText";
|
public static final String PROPERTY_KEY = "WrappedText";
|
||||||
|
|
||||||
// Static references to avoid heap allocations.
|
// Static references to avoid heap allocations.
|
||||||
/** Constant <code>paintIconR</code> */
|
/** Constant <code>paintIconR</code>. */
|
||||||
protected static Rectangle paintIconR = new Rectangle();
|
private static Rectangle paintIconR = new Rectangle();
|
||||||
/** Constant <code>paintTextR</code> */
|
|
||||||
protected static Rectangle paintTextR = new Rectangle();
|
/** Constant <code>paintTextR</code>. */
|
||||||
/** Constant <code>paintViewR</code> */
|
private static Rectangle paintTextR = new Rectangle();
|
||||||
protected static Rectangle paintViewR = new Rectangle();
|
|
||||||
/** Constant <code>paintViewInsets</code> */
|
/** Constant <code>paintViewR</code>. */
|
||||||
protected static Insets paintViewInsets = new Insets(0, 0, 0, 0);
|
private static Rectangle paintViewR = new Rectangle();
|
||||||
|
|
||||||
|
/** Constant <code>paintViewInsets</code>. */
|
||||||
|
private static Insets paintViewInsets = new Insets(0, 0, 0, 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Font metrics of the JLabel being rendered.
|
* Font metrics of the JLabel being rendered.
|
||||||
*/
|
*/
|
||||||
protected FontMetrics metrics;
|
private FontMetrics metrics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default size of the lines list.
|
* Default size of the lines list.
|
||||||
*/
|
*/
|
||||||
protected static int defaultSize = 4;
|
private static int defaultSize = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the shared UI instance.
|
* Get the shared UI instance.
|
||||||
* @param c
|
*
|
||||||
|
* @param c the c
|
||||||
* @return a ComponentUI
|
* @return a ComponentUI
|
||||||
*/
|
*/
|
||||||
public static ComponentUI createUI(JComponent c) {
|
public static ComponentUI createUI(final JComponent c) {
|
||||||
return labelUI;
|
return MultiLineLabelUI.getLabelUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
protected void uninstallDefaults(JLabel c) {
|
@Override
|
||||||
|
protected void uninstallDefaults(final JLabel c) {
|
||||||
super.uninstallDefaults(c);
|
super.uninstallDefaults(c);
|
||||||
clearCache(c);
|
this.clearCache(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
protected void installListeners(JLabel c) {
|
@Override
|
||||||
|
protected void installListeners(final JLabel c) {
|
||||||
super.installListeners(c);
|
super.installListeners(c);
|
||||||
c.addComponentListener(this);
|
c.addComponentListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
protected void uninstallListeners(JLabel c) {
|
@Override
|
||||||
|
protected void uninstallListeners(final JLabel c) {
|
||||||
super.uninstallListeners(c);
|
super.uninstallListeners(c);
|
||||||
c.removeComponentListener(this);
|
c.removeComponentListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the wrapped line cache.
|
* Clear the wrapped line cache.
|
||||||
*
|
*
|
||||||
* @param l the label containing a cached value
|
* @param l
|
||||||
|
* the label containing a cached value
|
||||||
*/
|
*/
|
||||||
protected void clearCache(JLabel l) {
|
protected void clearCache(final JLabel l) {
|
||||||
l.putClientProperty(PROPERTY_KEY, null);
|
l.putClientProperty(MultiLineLabelUI.PROPERTY_KEY, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void propertyChange(PropertyChangeEvent e) {
|
@Override
|
||||||
|
public void propertyChange(final PropertyChangeEvent e) {
|
||||||
super.propertyChange(e);
|
super.propertyChange(e);
|
||||||
final String name = e.getPropertyName();
|
final String name = e.getPropertyName();
|
||||||
if (name.equals("text") || "font".equals(name)) {
|
if (name.equals("text") || "font".equals(name)) {
|
||||||
clearCache((JLabel) e.getSource());
|
this.clearCache((JLabel) e.getSource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the paint rectangles for the icon and text for the passed
|
* Calculate the paint rectangles for the icon and text for the passed
|
||||||
* label.
|
* label.
|
||||||
*
|
*
|
||||||
* @param l a label
|
* @param l
|
||||||
* @param fm the font metrics to use, or <code>null</code> to get the font
|
* a label
|
||||||
* metrics from the label
|
* @param fm
|
||||||
* @param width label width
|
* the font metrics to use, or <code>null</code> to get the font
|
||||||
* @param height label height
|
* metrics from the label
|
||||||
|
* @param width
|
||||||
|
* label width
|
||||||
|
* @param height
|
||||||
|
* label height
|
||||||
*/
|
*/
|
||||||
protected void updateLayout(JLabel l, FontMetrics fm, int width, int height) {
|
protected void updateLayout(final JLabel l, FontMetrics fm, final int width, final int height) {
|
||||||
if (fm == null) {
|
if (fm == null) {
|
||||||
fm = l.getFontMetrics(l.getFont());
|
fm = l.getFontMetrics(l.getFont());
|
||||||
}
|
}
|
||||||
metrics = fm;
|
this.metrics = fm;
|
||||||
|
|
||||||
String text = l.getText();
|
final String text = l.getText();
|
||||||
Icon icon = l.getIcon();
|
final Icon icon = l.getIcon();
|
||||||
Insets insets = l.getInsets(paintViewInsets);
|
final Insets insets = l.getInsets(MultiLineLabelUI.paintViewInsets);
|
||||||
|
|
||||||
paintViewR.x = insets.left;
|
MultiLineLabelUI.paintViewR.x = insets.left;
|
||||||
paintViewR.y = insets.top;
|
MultiLineLabelUI.paintViewR.y = insets.top;
|
||||||
paintViewR.width = width - (insets.left + insets.right);
|
MultiLineLabelUI.paintViewR.width = width - (insets.left + insets.right);
|
||||||
paintViewR.height = height - (insets.top + insets.bottom);
|
MultiLineLabelUI.paintViewR.height = height - (insets.top + insets.bottom);
|
||||||
|
|
||||||
paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
|
MultiLineLabelUI.paintIconR.x = 0;
|
||||||
paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
|
MultiLineLabelUI.paintIconR.y = 0;
|
||||||
|
MultiLineLabelUI.paintIconR.width = 0;
|
||||||
|
MultiLineLabelUI.paintIconR.height = 0;
|
||||||
|
MultiLineLabelUI.paintTextR.x = 0;
|
||||||
|
MultiLineLabelUI.paintTextR.y = 0;
|
||||||
|
MultiLineLabelUI.paintTextR.width = 0;
|
||||||
|
MultiLineLabelUI.paintTextR.height = 0;
|
||||||
|
|
||||||
layoutCL(l, fm, text, icon, paintViewR, paintIconR, paintTextR);
|
this.layoutCL(l, fm, text, icon, MultiLineLabelUI.paintViewR, MultiLineLabelUI.paintIconR,
|
||||||
|
MultiLineLabelUI.paintTextR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>prepareGraphics.</p>
|
* <p>
|
||||||
*
|
* prepareGraphics.
|
||||||
* @param g a {@link java.awt.Graphics} object.
|
* </p>
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
* a {@link java.awt.Graphics} object.
|
||||||
*/
|
*/
|
||||||
protected void prepareGraphics(Graphics g) {
|
protected void prepareGraphics(final Graphics g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void paint(Graphics g, JComponent c) {
|
@Override
|
||||||
|
public void paint(final Graphics g, final JComponent c) {
|
||||||
|
|
||||||
// parent's update method fills the background
|
// parent's update method fills the background
|
||||||
prepareGraphics(g);
|
this.prepareGraphics(g);
|
||||||
|
|
||||||
JLabel label = (JLabel) c;
|
final JLabel label = (JLabel) c;
|
||||||
String text = label.getText();
|
final String text = label.getText();
|
||||||
Icon icon = (label.isEnabled()) ? label.getIcon() : label
|
final Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
|
||||||
.getDisabledIcon();
|
|
||||||
|
|
||||||
if ((icon == null) && (text == null)) {
|
if ((icon == null) && (text == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontMetrics fm = g.getFontMetrics();
|
final FontMetrics fm = g.getFontMetrics();
|
||||||
|
|
||||||
updateLayout(label, fm, c.getWidth(), c.getHeight());
|
this.updateLayout(label, fm, c.getWidth(), c.getHeight());
|
||||||
|
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
|
icon.paintIcon(c, g, MultiLineLabelUI.paintIconR.x, MultiLineLabelUI.paintIconR.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
View v = (View) c.getClientProperty("html");
|
final View v = (View) c.getClientProperty("html");
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
// HTML view disables multi-line painting.
|
// HTML view disables multi-line painting.
|
||||||
v.paint(g, paintTextR);
|
v.paint(g, MultiLineLabelUI.paintTextR);
|
||||||
} else {
|
} else {
|
||||||
// Paint the multi line text
|
// Paint the multi line text
|
||||||
paintTextLines(g, label, fm);
|
this.paintTextLines(g, label, fm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paint the wrapped text lines.
|
* Paint the wrapped text lines.
|
||||||
*
|
*
|
||||||
* @param g graphics component to paint on
|
* @param g
|
||||||
* @param label the label being painted
|
* graphics component to paint on
|
||||||
* @param fm font metrics for current font
|
* @param label
|
||||||
|
* the label being painted
|
||||||
|
* @param fm
|
||||||
|
* font metrics for current font
|
||||||
*/
|
*/
|
||||||
protected void paintTextLines(Graphics g, JLabel label, FontMetrics fm) {
|
protected void paintTextLines(final Graphics g, final JLabel label, final FontMetrics fm) {
|
||||||
List<String> lines = getTextLines(label);
|
final List<String> lines = this.getTextLines(label);
|
||||||
|
|
||||||
// Available component height to paint on.
|
// Available component height to paint on.
|
||||||
int height = getAvailableHeight(label);
|
final int height = this.getAvailableHeight(label);
|
||||||
|
|
||||||
int textHeight = lines.size() * fm.getHeight();
|
int textHeight = lines.size() * fm.getHeight();
|
||||||
while (textHeight > height) {
|
while (textHeight > height) {
|
||||||
// Remove one line until no. of visible lines is found.
|
// Remove one line until no. of visible lines is found.
|
||||||
textHeight -= fm.getHeight();
|
textHeight -= fm.getHeight();
|
||||||
}
|
}
|
||||||
paintTextR.height = Math.min(textHeight, height);
|
MultiLineLabelUI.paintTextR.height = Math.min(textHeight, height);
|
||||||
paintTextR.y = alignmentY(label, fm, paintTextR);
|
MultiLineLabelUI.paintTextR.y = this.alignmentY(label, fm, MultiLineLabelUI.paintTextR);
|
||||||
|
|
||||||
int textX = paintTextR.x;
|
final int textX = MultiLineLabelUI.paintTextR.x;
|
||||||
int textY = paintTextR.y;
|
int textY = MultiLineLabelUI.paintTextR.y;
|
||||||
|
|
||||||
for (Iterator<String> it = lines.iterator(); it.hasNext()
|
for (final Iterator<String> it = lines.iterator(); it.hasNext()
|
||||||
&& paintTextR.contains(textX, textY + getAscent(fm)); textY += fm
|
&& MultiLineLabelUI.paintTextR.contains(textX, textY + MultiLineLabelUI.getAscent(fm)); textY += fm
|
||||||
.getHeight()) {
|
.getHeight()) {
|
||||||
|
|
||||||
String text = it.next().trim();
|
String text = it.next().trim();
|
||||||
|
|
||||||
if (it.hasNext()
|
if (it.hasNext()
|
||||||
&& !paintTextR.contains(textX, textY + fm.getHeight()
|
&& !MultiLineLabelUI.paintTextR.contains(textX,
|
||||||
+ getAscent(fm))) {
|
textY + fm.getHeight() + MultiLineLabelUI.getAscent(fm))) {
|
||||||
// The last visible row, add a clip indication.
|
// The last visible row, add a clip indication.
|
||||||
text = clip(text, fm, paintTextR);
|
text = this.clip(text, fm, MultiLineLabelUI.paintTextR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = alignmentX(label, fm, text, paintTextR);
|
final int x = this.alignmentX(label, fm, text, MultiLineLabelUI.paintTextR);
|
||||||
|
|
||||||
if (label.isEnabled()) {
|
if (label.isEnabled()) {
|
||||||
paintEnabledText(label, g, text, x, textY);
|
this.paintEnabledText(label, g, text, x, textY);
|
||||||
} else {
|
} else {
|
||||||
paintDisabledText(label, g, text, x, textY);
|
this.paintDisabledText(label, g, text, x, textY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,25 +307,29 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
/**
|
/**
|
||||||
* Returns the available height to paint text on. This is the height of the
|
* Returns the available height to paint text on. This is the height of the
|
||||||
* passed component with insets subtracted.
|
* passed component with insets subtracted.
|
||||||
*
|
*
|
||||||
* @param l a component
|
* @param l
|
||||||
|
* a component
|
||||||
* @return the available height
|
* @return the available height
|
||||||
*/
|
*/
|
||||||
protected int getAvailableHeight(JLabel l) {
|
protected int getAvailableHeight(final JLabel l) {
|
||||||
l.getInsets(paintViewInsets);
|
l.getInsets(MultiLineLabelUI.paintViewInsets);
|
||||||
return l.getHeight() - paintViewInsets.top - paintViewInsets.bottom;
|
return l.getHeight() - MultiLineLabelUI.paintViewInsets.top - MultiLineLabelUI.paintViewInsets.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a clip indication to the string. It is important that the string
|
* Add a clip indication to the string. It is important that the string
|
||||||
* length does not exceed the length or the original string.
|
* length does not exceed the length or the original string.
|
||||||
*
|
*
|
||||||
* @param text the to be painted
|
* @param text
|
||||||
* @param fm font metrics
|
* the to be painted
|
||||||
* @param bounds the text bounds
|
* @param fm
|
||||||
|
* font metrics
|
||||||
|
* @param bounds
|
||||||
|
* the text bounds
|
||||||
* @return the clipped string
|
* @return the clipped string
|
||||||
*/
|
*/
|
||||||
protected String clip(String text, FontMetrics fm, Rectangle bounds) {
|
protected String clip(final String text, final FontMetrics fm, final Rectangle bounds) {
|
||||||
// Fast and lazy way to insert a clip indication is to simply replace
|
// Fast and lazy way to insert a clip indication is to simply replace
|
||||||
// the last characters in the string with the clip indication.
|
// the last characters in the string with the clip indication.
|
||||||
// A better way would be to use metrics and calculate how many (if any)
|
// A better way would be to use metrics and calculate how many (if any)
|
||||||
@@ -299,65 +343,74 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
/**
|
/**
|
||||||
* Establish the vertical text alignment. The default alignment is to center
|
* Establish the vertical text alignment. The default alignment is to center
|
||||||
* the text in the label.
|
* the text in the label.
|
||||||
*
|
*
|
||||||
* @param label the label to paint
|
* @param label
|
||||||
* @param fm font metrics
|
* the label to paint
|
||||||
* @param bounds the text bounds rectangle
|
* @param fm
|
||||||
|
* font metrics
|
||||||
|
* @param bounds
|
||||||
|
* the text bounds rectangle
|
||||||
* @return the vertical text alignment, defaults to CENTER.
|
* @return the vertical text alignment, defaults to CENTER.
|
||||||
*/
|
*/
|
||||||
protected int alignmentY(JLabel label, FontMetrics fm, Rectangle bounds) {
|
protected int alignmentY(final JLabel label, final FontMetrics fm, final Rectangle bounds) {
|
||||||
final int height = getAvailableHeight(label);
|
final int height = this.getAvailableHeight(label);
|
||||||
int textHeight = bounds.height;
|
final int textHeight = bounds.height;
|
||||||
|
|
||||||
if (label instanceof MultiLineLabel) {
|
if (label instanceof MultiLineLabel) {
|
||||||
int align = ((MultiLineLabel) label).getVerticalTextAlignment();
|
final int align = ((MultiLineLabel) label).getVerticalTextAlignment();
|
||||||
switch (align) {
|
switch (align) {
|
||||||
case JLabel.TOP:
|
case SwingConstants.TOP:
|
||||||
return getAscent(fm) + paintViewInsets.top;
|
return MultiLineLabelUI.getAscent(fm) + MultiLineLabelUI.paintViewInsets.top;
|
||||||
case JLabel.BOTTOM:
|
case SwingConstants.BOTTOM:
|
||||||
return getAscent(fm) + height - paintViewInsets.top
|
return (((MultiLineLabelUI.getAscent(fm) + height) - MultiLineLabelUI.paintViewInsets.top) + MultiLineLabelUI.paintViewInsets.bottom)
|
||||||
+ paintViewInsets.bottom - textHeight;
|
- textHeight;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center alignment
|
// Center alignment
|
||||||
int textY = paintViewInsets.top + (height - textHeight) / 2
|
final int textY = MultiLineLabelUI.paintViewInsets.top + ((height - textHeight) / 2)
|
||||||
+ getAscent(fm);
|
+ MultiLineLabelUI.getAscent(fm);
|
||||||
return Math.max(textY, getAscent(fm) + paintViewInsets.top);
|
return Math.max(textY, MultiLineLabelUI.getAscent(fm) + MultiLineLabelUI.paintViewInsets.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>getAscent.</p>
|
* <p>
|
||||||
*
|
* getAscent.
|
||||||
* @param fm a {@link java.awt.FontMetrics} object.
|
* </p>
|
||||||
|
*
|
||||||
|
* @param fm
|
||||||
|
* a {@link java.awt.FontMetrics} object.
|
||||||
* @return a int.
|
* @return a int.
|
||||||
*/
|
*/
|
||||||
private static int getAscent(FontMetrics fm) {
|
private static int getAscent(final FontMetrics fm) {
|
||||||
return fm.getAscent() + fm.getLeading();
|
return fm.getAscent() + fm.getLeading();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establish the horizontal text alignment. The default alignment is left
|
* Establish the horizontal text alignment. The default alignment is left
|
||||||
* aligned text.
|
* aligned text.
|
||||||
*
|
*
|
||||||
* @param label the label to paint
|
* @param label
|
||||||
* @param fm font metrics
|
* the label to paint
|
||||||
* @param s the string to paint
|
* @param fm
|
||||||
* @param bounds the text bounds rectangle
|
* font metrics
|
||||||
|
* @param s
|
||||||
|
* the string to paint
|
||||||
|
* @param bounds
|
||||||
|
* the text bounds rectangle
|
||||||
* @return the x-coordinate to use when painting for proper alignment
|
* @return the x-coordinate to use when painting for proper alignment
|
||||||
*/
|
*/
|
||||||
protected int alignmentX(JLabel label, FontMetrics fm, String s,
|
protected int alignmentX(final JLabel label, final FontMetrics fm, final String s, final Rectangle bounds) {
|
||||||
Rectangle bounds) {
|
|
||||||
if (label instanceof MultiLineLabel) {
|
if (label instanceof MultiLineLabel) {
|
||||||
int align = ((MultiLineLabel) label).getHorizontalTextAlignment();
|
final int align = ((MultiLineLabel) label).getHorizontalTextAlignment();
|
||||||
switch (align) {
|
switch (align) {
|
||||||
case JLabel.RIGHT:
|
case SwingConstants.RIGHT:
|
||||||
return bounds.x + paintViewR.width - fm.stringWidth(s);
|
return (bounds.x + MultiLineLabelUI.paintViewR.width) - fm.stringWidth(s);
|
||||||
case JLabel.CENTER:
|
case SwingConstants.CENTER:
|
||||||
return bounds.x + paintViewR.width / 2 - fm.stringWidth(s) / 2;
|
return (bounds.x + (MultiLineLabelUI.paintViewR.width / 2)) - (fm.stringWidth(s) / 2);
|
||||||
default:
|
default:
|
||||||
return bounds.x;
|
return bounds.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bounds.x;
|
return bounds.x;
|
||||||
@@ -367,15 +420,15 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
* Check the given string to see if it should be rendered as HTML. Code
|
* Check the given string to see if it should be rendered as HTML. Code
|
||||||
* based on implementation found in
|
* based on implementation found in
|
||||||
* <code>BasicHTML.isHTMLString(String)</code> in future JDKs.
|
* <code>BasicHTML.isHTMLString(String)</code> in future JDKs.
|
||||||
*
|
*
|
||||||
* @param s the string
|
* @param s
|
||||||
|
* the string
|
||||||
* @return <code>true</code> if string is HTML, otherwise <code>false</code>
|
* @return <code>true</code> if string is HTML, otherwise <code>false</code>
|
||||||
*/
|
*/
|
||||||
private static boolean isHTMLString(String s) {
|
private static boolean isHTMLString(final String s) {
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
if ((s.length() >= 6) && (s.charAt(0) == '<')
|
if ((s.length() >= 6) && (s.charAt(0) == '<') && (s.charAt(5) == '>')) {
|
||||||
&& (s.charAt(5) == '>')) {
|
final String tag = s.substring(1, 5);
|
||||||
String tag = s.substring(1, 5);
|
|
||||||
return tag.equalsIgnoreCase("html");
|
return tag.equalsIgnoreCase("html");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,11 +436,12 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public Dimension getPreferredSize(JComponent c) {
|
@Override
|
||||||
Dimension d = super.getPreferredSize(c);
|
public Dimension getPreferredSize(final JComponent c) {
|
||||||
JLabel label = (JLabel) c;
|
final Dimension d = super.getPreferredSize(c);
|
||||||
|
final JLabel label = (JLabel) c;
|
||||||
|
|
||||||
if (isHTMLString(label.getText())) {
|
if (MultiLineLabelUI.isHTMLString(label.getText())) {
|
||||||
return d; // HTML overrides everything and we don't need to process
|
return d; // HTML overrides everything and we don't need to process
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,19 +452,19 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
if (c.getParent() != null) {
|
if (c.getParent() != null) {
|
||||||
// Ensure that preferred width never exceeds the available width
|
// Ensure that preferred width never exceeds the available width
|
||||||
// (including its border insets) of the parent container.
|
// (including its border insets) of the parent container.
|
||||||
Insets insets = c.getParent().getInsets();
|
final Insets insets = c.getParent().getInsets();
|
||||||
Dimension size = c.getParent().getSize();
|
final Dimension size = c.getParent().getSize();
|
||||||
if (size.width > 0) {
|
if (size.width > 0) {
|
||||||
// If width isn't set component shouldn't adjust.
|
// If width isn't set component shouldn't adjust.
|
||||||
d.width = size.width - insets.left - insets.right;
|
d.width = size.width - insets.left - insets.right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLayout(label, null, d.width, d.height);
|
this.updateLayout(label, null, d.width, d.height);
|
||||||
|
|
||||||
// The preferred height is either the preferred height of the text
|
// The preferred height is either the preferred height of the text
|
||||||
// lines, or the height of the icon.
|
// lines, or the height of the icon.
|
||||||
d.height = Math.max(d.height, getPreferredHeight(label));
|
d.height = Math.max(d.height, this.getPreferredHeight(label));
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@@ -418,93 +472,102 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
/**
|
/**
|
||||||
* The preferred height of the label is the height of the lines with added
|
* The preferred height of the label is the height of the lines with added
|
||||||
* top and bottom insets.
|
* top and bottom insets.
|
||||||
*
|
*
|
||||||
* @param label the label
|
* @param label
|
||||||
|
* the label
|
||||||
* @return the preferred height of the wrapped lines.
|
* @return the preferred height of the wrapped lines.
|
||||||
*/
|
*/
|
||||||
protected int getPreferredHeight(JLabel label) {
|
protected int getPreferredHeight(final JLabel label) {
|
||||||
int numOfLines = getTextLines(label).size();
|
final int numOfLines = this.getTextLines(label).size();
|
||||||
Insets insets = label.getInsets(paintViewInsets);
|
final Insets insets = label.getInsets(MultiLineLabelUI.paintViewInsets);
|
||||||
return numOfLines * metrics.getHeight() + insets.top + insets.bottom;
|
return (numOfLines * this.metrics.getHeight()) + insets.top + insets.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the lines of text contained in the text label. The prepared lines is
|
* Get the lines of text contained in the text label. The prepared lines is
|
||||||
* cached as a client property, accessible via {@link #PROPERTY_KEY}.
|
* cached as a client property, accessible via {@link #PROPERTY_KEY}.
|
||||||
*
|
*
|
||||||
* @param l the label
|
* @param l
|
||||||
|
* the label
|
||||||
* @return the text lines of the label.
|
* @return the text lines of the label.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected List<String> getTextLines(JLabel l) {
|
protected List<String> getTextLines(final JLabel l) {
|
||||||
List<String> lines = (List<String>) l.getClientProperty(PROPERTY_KEY);
|
List<String> lines = (List<String>) l.getClientProperty(MultiLineLabelUI.PROPERTY_KEY);
|
||||||
if (lines == null) {
|
if (lines == null) {
|
||||||
lines = prepareLines(l);
|
lines = this.prepareLines(l);
|
||||||
l.putClientProperty(PROPERTY_KEY, lines);
|
l.putClientProperty(MultiLineLabelUI.PROPERTY_KEY, lines);
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void componentHidden(ComponentEvent e) {
|
@Override
|
||||||
|
public void componentHidden(final ComponentEvent e) {
|
||||||
// Don't care
|
// Don't care
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void componentMoved(ComponentEvent e) {
|
@Override
|
||||||
|
public void componentMoved(final ComponentEvent e) {
|
||||||
// Don't care
|
// Don't care
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void componentResized(ComponentEvent e) {
|
@Override
|
||||||
clearCache((JLabel) e.getSource());
|
public void componentResized(final ComponentEvent e) {
|
||||||
|
this.clearCache((JLabel) e.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void componentShown(ComponentEvent e) {
|
@Override
|
||||||
|
public void componentShown(final ComponentEvent e) {
|
||||||
// Don't care
|
// Don't care
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the text lines for rendering. The lines are wrapped to fit in the
|
* Prepare the text lines for rendering. The lines are wrapped to fit in the
|
||||||
* current available space for text. Explicit line breaks are preserved.
|
* current available space for text. Explicit line breaks are preserved.
|
||||||
*
|
*
|
||||||
* @param l the label to render
|
* @param l
|
||||||
|
* the label to render
|
||||||
* @return a list of text lines to render
|
* @return a list of text lines to render
|
||||||
*/
|
*/
|
||||||
protected List<String> prepareLines(JLabel l) {
|
protected List<String> prepareLines(final JLabel l) {
|
||||||
List<String> lines = new ArrayList<String>(defaultSize);
|
final List<String> lines = new ArrayList<String>(MultiLineLabelUI.defaultSize);
|
||||||
String text = l.getText();
|
final String text = l.getText();
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return null; // Null guard
|
return null; // Null guard
|
||||||
}
|
}
|
||||||
PlainDocument doc = new PlainDocument();
|
final PlainDocument doc = new PlainDocument();
|
||||||
try {
|
try {
|
||||||
doc.insertString(0, text, null);
|
doc.insertString(0, text, null);
|
||||||
} catch (BadLocationException e) {
|
} catch (final BadLocationException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Element root = doc.getDefaultRootElement();
|
final Element root = doc.getDefaultRootElement();
|
||||||
for (int i = 0, j = root.getElementCount(); i < j; i++) {
|
for (int i = 0, j = root.getElementCount(); i < j; i++) {
|
||||||
wrap(lines, root.getElement(i));
|
this.wrap(lines, root.getElement(i));
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If necessary, wrap the text into multiple lines.
|
* If necessary, wrap the text into multiple lines.
|
||||||
*
|
*
|
||||||
* @param lines line array in which to store the wrapped lines
|
* @param lines
|
||||||
* @param elem the document element containing the text content
|
* line array in which to store the wrapped lines
|
||||||
|
* @param elem
|
||||||
|
* the document element containing the text content
|
||||||
*/
|
*/
|
||||||
protected void wrap(List<String> lines, Element elem) {
|
protected void wrap(final List<String> lines, final Element elem) {
|
||||||
int p1 = elem.getEndOffset();
|
final int p1 = elem.getEndOffset();
|
||||||
Document doc = elem.getDocument();
|
final Document doc = elem.getDocument();
|
||||||
for (int p0 = elem.getStartOffset(); p0 < p1; ) {
|
for (int p0 = elem.getStartOffset(); p0 < p1;) {
|
||||||
int p = calculateBreakPosition(doc, p0, p1);
|
final int p = this.calculateBreakPosition(doc, p0, p1);
|
||||||
try {
|
try {
|
||||||
lines.add(doc.getText(p0, p - p0));
|
lines.add(doc.getText(p0, p - p0));
|
||||||
} catch (BadLocationException e) {
|
} catch (final BadLocationException e) {
|
||||||
throw new Error("Can't get line text. p0=" + p0 + " p=" + p);
|
throw new Error("Can't get line text. p0=" + p0 + " p=" + p);
|
||||||
}
|
}
|
||||||
p0 = (p == p0) ? p1 : p;
|
p0 = (p == p0) ? p1 : p;
|
||||||
@@ -513,32 +576,47 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the position on which to break (wrap) the line.
|
* Calculate the position on which to break (wrap) the line.
|
||||||
*
|
*
|
||||||
* @param doc the document
|
* @param doc
|
||||||
* @param p0 start position
|
* the document
|
||||||
* @param p1 end position
|
* @param p0
|
||||||
|
* start position
|
||||||
|
* @param p1
|
||||||
|
* end position
|
||||||
* @return the actual end position, will be <code>p1</code> if content does
|
* @return the actual end position, will be <code>p1</code> if content does
|
||||||
* not need to wrap, otherwise it will be less than <code>p1</code>.
|
* not need to wrap, otherwise it will be less than <code>p1</code>.
|
||||||
*/
|
*/
|
||||||
protected int calculateBreakPosition(Document doc, int p0, int p1) {
|
protected int calculateBreakPosition(final Document doc, final int p0, final int p1) {
|
||||||
Segment segment = SegmentCache.getSegment();
|
final Segment segment = SegmentCache.getSegment();
|
||||||
try {
|
try {
|
||||||
doc.getText(p0, p1 - p0, segment);
|
doc.getText(p0, p1 - p0, segment);
|
||||||
} catch (BadLocationException e) {
|
} catch (final BadLocationException e) {
|
||||||
throw new Error("Can't get line text");
|
throw new Error("Can't get line text");
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = paintTextR.width;
|
final int width = MultiLineLabelUI.paintTextR.width;
|
||||||
int p = p0
|
final int p = p0 + Utilities.getBreakLocation(segment, this.metrics, 0, width, null, p0);
|
||||||
+ Utilities.getBreakLocation(segment, metrics, 0, width, null,
|
|
||||||
p0);
|
|
||||||
SegmentCache.releaseSegment(segment);
|
SegmentCache.releaseSegment(segment);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the labelUI
|
||||||
|
*/
|
||||||
|
public static LabelUI getLabelUI() {
|
||||||
|
return labelUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param labelUI the labelUI to set
|
||||||
|
*/
|
||||||
|
public static void setLabelUI(LabelUI labelUI) {
|
||||||
|
MultiLineLabelUI.labelUI = labelUI; // TODO: Add 0 to parameter's name.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static singleton {@link Segment} cache.
|
* Static singleton {@link Segment} cache.
|
||||||
*
|
*
|
||||||
* @author Samuel Sjoberg
|
* @author Samuel Sjoberg
|
||||||
* @see javax.swing.text.SegmentCache
|
* @see javax.swing.text.SegmentCache
|
||||||
*/
|
*/
|
||||||
@@ -547,7 +625,7 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
/**
|
/**
|
||||||
* Reused segments.
|
* Reused segments.
|
||||||
*/
|
*/
|
||||||
private ArrayList<Segment> segments = new ArrayList<Segment>(2);
|
private final ArrayList<Segment> segments = new ArrayList<Segment>(2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton instance.
|
* Singleton instance.
|
||||||
@@ -563,13 +641,13 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
/**
|
/**
|
||||||
* Returns a <code>Segment</code>. When done, the <code>Segment</code>
|
* Returns a <code>Segment</code>. When done, the <code>Segment</code>
|
||||||
* should be recycled by invoking {@link #releaseSegment(Segment)}.
|
* should be recycled by invoking {@link #releaseSegment(Segment)}.
|
||||||
*
|
*
|
||||||
* @return a <code>Segment</code>.
|
* @return a <code>Segment</code>.
|
||||||
*/
|
*/
|
||||||
public static Segment getSegment() {
|
public static Segment getSegment() {
|
||||||
int size = cache.segments.size();
|
final int size = SegmentCache.cache.segments.size();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
return cache.segments.remove(size - 1);
|
return SegmentCache.cache.segments.remove(size - 1);
|
||||||
}
|
}
|
||||||
return new Segment();
|
return new Segment();
|
||||||
}
|
}
|
||||||
@@ -578,11 +656,13 @@ public class MultiLineLabelUI extends BasicLabelUI implements ComponentListener
|
|||||||
* Releases a <code>Segment</code>. A segment should not be used after
|
* Releases a <code>Segment</code>. A segment should not be used after
|
||||||
* it is released, and a segment should never be released more than
|
* it is released, and a segment should never be released more than
|
||||||
* once.
|
* once.
|
||||||
|
*
|
||||||
|
* @param segment the segment
|
||||||
*/
|
*/
|
||||||
public static void releaseSegment(Segment segment) {
|
public static void releaseSegment(final Segment segment) {
|
||||||
segment.array = null;
|
segment.array = null;
|
||||||
segment.count = 0;
|
segment.count = 0;
|
||||||
cache.segments.add(segment);
|
SegmentCache.cache.segments.add(segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import javax.swing.JDialog;
|
|||||||
import javax.swing.JProgressBar;
|
import javax.swing.JProgressBar;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.WindowConstants;
|
||||||
|
|
||||||
import net.slightlymagic.braids.util.UtilFunctions;
|
import net.slightlymagic.braids.util.UtilFunctions;
|
||||||
import net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor;
|
import net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor;
|
||||||
@@ -13,7 +14,7 @@ import forge.Gui_ProgressBarWindow;
|
|||||||
* GUI Progress Monitor that displays the ETA (Estimated Time of Arrival or
|
* GUI Progress Monitor that displays the ETA (Estimated Time of Arrival or
|
||||||
* completion) on some platforms and supports one or multiple phases of
|
* completion) on some platforms and supports one or multiple phases of
|
||||||
* progress.
|
* progress.
|
||||||
*
|
*
|
||||||
* In this implementation, each phase opens a new dialog.
|
* In this implementation, each phase opens a new dialog.
|
||||||
*/
|
*/
|
||||||
public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
|
public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
|
||||||
@@ -22,54 +23,65 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
|
|||||||
private transient String title;
|
private transient String title;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience for
|
* Convenience for MultiPhaseProgressMonitorWithETA(title, numPhases,
|
||||||
* MultiPhaseProgressMonitorWithETA(title, numPhases, totalUnitsFirstPhase,
|
* totalUnitsFirstPhase, minUIUpdateIntervalSec, null).
|
||||||
* minUIUpdateIntervalSec, null).
|
|
||||||
*
|
*
|
||||||
|
* @param neoTitle the title to give the dialog box(es)
|
||||||
|
* @param numPhases the total number of phases to expect
|
||||||
|
* @param totalUnitsFirstPhase the total number of units that will be processed in the first
|
||||||
|
* phase
|
||||||
|
* @param minUIUpdateIntervalSec the approximate interval at which to update the dialog box in
|
||||||
|
* seconds
|
||||||
* @see #MultiPhaseProgressMonitorWithETA(String,int,long,float,float[])
|
* @see #MultiPhaseProgressMonitorWithETA(String,int,long,float,float[])
|
||||||
*
|
|
||||||
* @param neoTitle the title to give the dialog box(es)
|
|
||||||
*
|
|
||||||
* @param numPhases the total number of phases to expect
|
|
||||||
*
|
|
||||||
* @param totalUnitsFirstPhase the total number of units that will be
|
|
||||||
* processed in the first phase
|
|
||||||
*
|
|
||||||
* @param minUIUpdateIntervalSec the approximate interval at which to
|
|
||||||
* update the dialog box in seconds
|
|
||||||
*/
|
*/
|
||||||
public MultiPhaseProgressMonitorWithETA(final String neoTitle, final int numPhases,
|
public MultiPhaseProgressMonitorWithETA(final String neoTitle, final int numPhases,
|
||||||
final long totalUnitsFirstPhase, final float minUIUpdateIntervalSec) // NOPMD by Braids on 8/18/11 11:16 PM
|
final long totalUnitsFirstPhase, final float minUIUpdateIntervalSec) // NOPMD
|
||||||
|
// by
|
||||||
|
// Braids
|
||||||
|
// on
|
||||||
|
// 8/18/11
|
||||||
|
// 11:16
|
||||||
|
// PM
|
||||||
{
|
{
|
||||||
this(neoTitle, numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, null);
|
this(neoTitle, numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a GUI progress monitor and open its first dialog.
|
* Create a GUI progress monitor and open its first dialog.
|
||||||
*
|
*
|
||||||
* Like all swing components, this constructor must be invoked from the
|
* Like all swing components, this constructor must be invoked from the
|
||||||
* swing Event Dispatching Thread. The rest of the methods of this class
|
* swing Event Dispatching Thread. The rest of the methods of this class are
|
||||||
* are exempt from this requirement.
|
* exempt from this requirement.
|
||||||
*
|
*
|
||||||
* @param neoTitle the title to give the dialog box(es)
|
* @param neoTitle
|
||||||
*
|
* the title to give the dialog box(es)
|
||||||
* @param numPhases the total number of phases to expect
|
*
|
||||||
*
|
* @param numPhases
|
||||||
* @param totalUnitsFirstPhase the total number of units that will be
|
* the total number of phases to expect
|
||||||
* processed in the first phase
|
*
|
||||||
*
|
* @param totalUnitsFirstPhase
|
||||||
* @param minUIUpdateIntervalSec the approximate interval at which to
|
* the total number of units that will be processed in the first
|
||||||
* update the dialog box in seconds
|
* phase
|
||||||
*
|
*
|
||||||
* @param phaseWeights see BaseProgressMonitor
|
* @param minUIUpdateIntervalSec
|
||||||
*
|
* the approximate interval at which to update the dialog box in
|
||||||
|
* seconds
|
||||||
|
*
|
||||||
|
* @param phaseWeights
|
||||||
|
* see BaseProgressMonitor
|
||||||
|
*
|
||||||
* @see BaseProgressMonitor#BaseProgressMonitor(int,long,float,float[])
|
* @see BaseProgressMonitor#BaseProgressMonitor(int,long,float,float[])
|
||||||
*/
|
*/
|
||||||
public MultiPhaseProgressMonitorWithETA(final String neoTitle, final int numPhases,
|
public MultiPhaseProgressMonitorWithETA(final String neoTitle, final int numPhases,
|
||||||
final long totalUnitsFirstPhase, final float minUIUpdateIntervalSec, // NOPMD by Braids on 8/18/11 11:16 PM
|
final long totalUnitsFirstPhase, final float minUIUpdateIntervalSec, // NOPMD
|
||||||
final float[] phaseWeights)
|
// by
|
||||||
{
|
// Braids
|
||||||
super(numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec,
|
// on
|
||||||
phaseWeights);
|
// 8/18/11
|
||||||
|
// 11:16
|
||||||
|
// PM
|
||||||
|
final float[] phaseWeights) {
|
||||||
|
super(numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, phaseWeights);
|
||||||
|
|
||||||
if (!SwingUtilities.isEventDispatchThread()) {
|
if (!SwingUtilities.isEventDispatchThread()) {
|
||||||
throw new IllegalStateException("must be called from within an event dispatch thread");
|
throw new IllegalStateException("must be called from within an event dispatch thread");
|
||||||
@@ -77,80 +89,105 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
|
|||||||
|
|
||||||
this.title = neoTitle;
|
this.title = neoTitle;
|
||||||
|
|
||||||
if (totalUnitsFirstPhase > 0 && dialog == null) {
|
if ((totalUnitsFirstPhase > 0) && (this.dialog == null)) {
|
||||||
throw new IllegalStateException("dialog is null");
|
throw new IllegalStateException("dialog is null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For developer testing.
|
* For developer testing.
|
||||||
*
|
*
|
||||||
* @param args ignored
|
* @param args
|
||||||
|
* ignored
|
||||||
*/
|
*/
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
|
|
||||||
System.out.println("Initializing..."); // NOPMD by Braids on 8/18/11 11:13 PM
|
System.out.println("Initializing..."); // NOPMD by Braids on 8/18/11
|
||||||
|
// 11:13 PM
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:16 PM
|
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on
|
||||||
public void run() {
|
// 8/18/11 11:16 PM
|
||||||
|
|
||||||
final int totalUnitsFirstPhase = 5000; // NOPMD by Braids on 8/18/11 11:16 PM
|
|
||||||
final MultiPhaseProgressMonitorWithETA monitor =
|
|
||||||
new MultiPhaseProgressMonitorWithETA("Testing 2 phases", 2, totalUnitsFirstPhase, 1.0f,
|
|
||||||
new float[] {2, 1});
|
|
||||||
|
|
||||||
final SwingWorker<Object, Object> worker = new SwingWorker<Object, Object>() {
|
|
||||||
@Override
|
@Override
|
||||||
public Object doInBackground() {
|
public void run() {
|
||||||
|
|
||||||
System.out.println("Running..."); // NOPMD by Braids on 8/18/11 11:14 PM
|
final int totalUnitsFirstPhase = 5000; // NOPMD by
|
||||||
|
// Braids on
|
||||||
|
// 8/18/11 11:16
|
||||||
|
// PM
|
||||||
|
final MultiPhaseProgressMonitorWithETA monitor = new MultiPhaseProgressMonitorWithETA(
|
||||||
|
"Testing 2 phases", 2, totalUnitsFirstPhase, 1.0f, new float[] { 2, 1 });
|
||||||
|
|
||||||
for (int i = 0; i <= totalUnitsFirstPhase; i++) {
|
final SwingWorker<Object, Object> worker = new SwingWorker<Object, Object>() {
|
||||||
monitor.incrementUnitsCompletedThisPhase(1);
|
@Override
|
||||||
|
public Object doInBackground() {
|
||||||
|
|
||||||
System.out.print("\ri = " + i); // NOPMD by Braids on 8/18/11 11:14 PM
|
System.out.println("Running..."); // NOPMD by
|
||||||
|
// Braids on
|
||||||
|
// 8/18/11
|
||||||
|
// 11:14 PM
|
||||||
|
|
||||||
try {
|
for (int i = 0; i <= totalUnitsFirstPhase; i++) {
|
||||||
Thread.sleep(1);
|
monitor.incrementUnitsCompletedThisPhase(1);
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
// blank
|
System.out.print("\ri = " + i); // NOPMD by
|
||||||
|
// Braids on
|
||||||
|
// 8/18/11
|
||||||
|
// 11:14 PM
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch (final InterruptedException ignored) {
|
||||||
|
// blank
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(); // NOPMD by Braids on
|
||||||
|
// 8/18/11 11:14 PM
|
||||||
|
|
||||||
|
final int totalUnitsSecondPhase = 2000; // NOPMD
|
||||||
|
// by
|
||||||
|
// Braids
|
||||||
|
// on
|
||||||
|
// 8/18/11
|
||||||
|
// 11:17
|
||||||
|
// PM
|
||||||
|
monitor.markCurrentPhaseAsComplete(totalUnitsSecondPhase);
|
||||||
|
|
||||||
|
for (int i = 0; i <= totalUnitsSecondPhase; i++) {
|
||||||
|
monitor.incrementUnitsCompletedThisPhase(1);
|
||||||
|
|
||||||
|
System.out.print("\ri = " + i); // NOPMD by
|
||||||
|
// Braids on
|
||||||
|
// 8/18/11
|
||||||
|
// 11:14 PM
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch (final InterruptedException ignored) {
|
||||||
|
// blank
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor.markCurrentPhaseAsComplete(0);
|
||||||
|
|
||||||
|
System.out.println(); // NOPMD by Braids on
|
||||||
|
// 8/18/11 11:14 PM
|
||||||
|
System.out.println("Done!"); // NOPMD by Braids
|
||||||
|
// on 8/18/11 11:14
|
||||||
|
// PM
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
System.out.println(); // NOPMD by Braids on 8/18/11 11:14 PM
|
|
||||||
|
|
||||||
final int totalUnitsSecondPhase = 2000; // NOPMD by Braids on 8/18/11 11:17 PM
|
};
|
||||||
monitor.markCurrentPhaseAsComplete(totalUnitsSecondPhase);
|
|
||||||
|
|
||||||
for (int i = 0; i <= totalUnitsSecondPhase; i++) {
|
worker.execute();
|
||||||
monitor.incrementUnitsCompletedThisPhase(1);
|
|
||||||
|
|
||||||
System.out.print("\ri = " + i); // NOPMD by Braids on 8/18/11 11:14 PM
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
// blank
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor.markCurrentPhaseAsComplete(0);
|
|
||||||
|
|
||||||
System.out.println(); // NOPMD by Braids on 8/18/11 11:14 PM
|
|
||||||
System.out.println("Done!"); // NOPMD by Braids on 8/18/11 11:14 PM
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
|
||||||
|
|
||||||
worker.execute();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor#setTotalUnitsThisPhase(long)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
/**
|
/**
|
||||||
* @param numUnits cannot be higher than Integer.MAX_VALUE
|
* @param numUnits cannot be higher than Integer.MAX_VALUE
|
||||||
@@ -166,38 +203,52 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
|
|||||||
|
|
||||||
if (numUnits > 0) {
|
if (numUnits > 0) {
|
||||||
// dialog must exist before we exit this method.
|
// dialog must exist before we exit this method.
|
||||||
UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { // NOPMD by Braids on 8/18/11 11:17 PM
|
UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { // NOPMD
|
||||||
public void run() {
|
// by
|
||||||
// (Re)create the progress bar.
|
// Braids
|
||||||
if (dialog != null) {
|
// on
|
||||||
dialog.dispose();
|
// 8/18/11
|
||||||
dialog = null;
|
// 11:17
|
||||||
}
|
// PM
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// (Re)create the progress bar.
|
||||||
|
if (MultiPhaseProgressMonitorWithETA.this.dialog != null) {
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog.dispose();
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog = null;
|
||||||
|
}
|
||||||
|
|
||||||
dialog = new Gui_ProgressBarWindow();
|
MultiPhaseProgressMonitorWithETA.this.dialog = new Gui_ProgressBarWindow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM
|
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on
|
||||||
public void run() {
|
// 8/18/11 11:18 PM
|
||||||
dialog.setTitle(title);
|
@Override
|
||||||
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
public void run() {
|
||||||
dialog.setVisible(true);
|
MultiPhaseProgressMonitorWithETA.this.dialog
|
||||||
dialog.setResizable(true);
|
.setTitle(MultiPhaseProgressMonitorWithETA.this.title);
|
||||||
dialog.getProgressBar().setIndeterminate(false);
|
MultiPhaseProgressMonitorWithETA.this.dialog
|
||||||
dialog.setProgressRange(0, (int) numUnits);
|
.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
dialog.reset();
|
MultiPhaseProgressMonitorWithETA.this.dialog.setVisible(true);
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog.setResizable(true);
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog.getProgressBar().setIndeterminate(false);
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog.setProgressRange(0, (int) numUnits);
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog.reset();
|
||||||
|
|
||||||
final JProgressBar bar = dialog.getProgressBar();
|
final JProgressBar bar = MultiPhaseProgressMonitorWithETA.this.dialog.getProgressBar();
|
||||||
bar.setString("");
|
bar.setString("");
|
||||||
bar.setStringPainted(true);
|
bar.setStringPainted(true);
|
||||||
bar.setValue(0);
|
bar.setValue(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor#incrementUnitsCompletedThisPhase(long)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
/**
|
/**
|
||||||
* @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#incrementUnitsCompletedThisPhase(long)
|
* @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#incrementUnitsCompletedThisPhase(long)
|
||||||
@@ -205,86 +256,92 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
|
|||||||
public final void incrementUnitsCompletedThisPhase(final long numUnits) {
|
public final void incrementUnitsCompletedThisPhase(final long numUnits) {
|
||||||
super.incrementUnitsCompletedThisPhase(numUnits);
|
super.incrementUnitsCompletedThisPhase(numUnits);
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM
|
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on
|
||||||
public void run() {
|
// 8/18/11 11:18 PM
|
||||||
for (int i = 0; i < numUnits; i++) {
|
@Override
|
||||||
dialog.increment();
|
public void run() {
|
||||||
}
|
for (int i = 0; i < numUnits; i++) {
|
||||||
}
|
MultiPhaseProgressMonitorWithETA.this.dialog.increment();
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (shouldUpdateUI()) {
|
if (this.shouldUpdateUI()) {
|
||||||
|
|
||||||
if ((getNumPhases() > 1)) {
|
if ((this.getNumPhases() > 1)) {
|
||||||
displayUpdate(
|
this.displayUpdate("Phase " + this.getCurrentPhase() + ". "
|
||||||
"Phase " + getCurrentPhase() + ". "
|
// + getUnitsCompletedSoFarThisPhase() + " units processed. "
|
||||||
//+ getUnitsCompletedSoFarThisPhase() + " units processed. "
|
// + "Overall: " + getTotalPercentCompleteAsString() +
|
||||||
//+ "Overall: " + getTotalPercentCompleteAsString() + "% complete, "
|
// "% complete, "
|
||||||
+ "Overall ETA in " + getRelativeETAAsString() + "."
|
+ "Overall ETA in " + this.getRelativeETAAsString() + ".");
|
||||||
);
|
} else {
|
||||||
}
|
this.displayUpdate(
|
||||||
else {
|
// "Overall: " +
|
||||||
displayUpdate(
|
this.getUnitsCompletedSoFarThisPhase() + " units processed; "
|
||||||
//"Overall: " +
|
// + "(" + getTotalPercentCompleteAsString() + "%); "
|
||||||
getUnitsCompletedSoFarThisPhase() + " units processed; "
|
+ "ETA in " + this.getRelativeETAAsString() + ".");
|
||||||
//+ "(" + getTotalPercentCompleteAsString() + "%); "
|
|
||||||
+ "ETA in " + getRelativeETAAsString() + "."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCurrentPhase() == getNumPhases()
|
if ((this.getCurrentPhase() == this.getNumPhases())
|
||||||
&& getUnitsCompletedSoFarThisPhase() >= getTotalUnitsThisPhase())
|
&& (this.getUnitsCompletedSoFarThisPhase() >= this.getTotalUnitsThisPhase())) {
|
||||||
{
|
this.displayUpdate("Done!");
|
||||||
displayUpdate("Done!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the message inside the progress dialog; does not always work on
|
* Shows the message inside the progress dialog; does not always work on all
|
||||||
* all platforms.
|
* platforms.
|
||||||
*
|
*
|
||||||
* @param message the message to display
|
* @param message
|
||||||
|
* the message to display
|
||||||
*/
|
*/
|
||||||
public final void displayUpdate(final String message) {
|
public final void displayUpdate(final String message) {
|
||||||
|
|
||||||
final Runnable proc = new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM
|
final Runnable proc = new Runnable() { // NOPMD by Braids on 8/18/11
|
||||||
|
// 11:18 PM
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// i've been having trouble getting the dialog to display its title.
|
// i've been having trouble getting the dialog to display its
|
||||||
dialog.setTitle(title);
|
// title.
|
||||||
|
MultiPhaseProgressMonitorWithETA.this.dialog.setTitle(MultiPhaseProgressMonitorWithETA.this.title);
|
||||||
|
|
||||||
JProgressBar bar = dialog.getProgressBar();
|
final JProgressBar bar = MultiPhaseProgressMonitorWithETA.this.dialog.getProgressBar();
|
||||||
bar.setString(message);
|
bar.setString(message);
|
||||||
|
|
||||||
justUpdatedUI();
|
MultiPhaseProgressMonitorWithETA.this.justUpdatedUI();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (SwingUtilities.isEventDispatchThread()) {
|
if (SwingUtilities.isEventDispatchThread()) {
|
||||||
proc.run();
|
proc.run();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
SwingUtilities.invokeLater(proc);
|
SwingUtilities.invokeLater(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor#dispose()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void dispose() {
|
public final void dispose() {
|
||||||
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM
|
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on
|
||||||
public void run() {
|
// 8/18/11 11:18 PM
|
||||||
getDialog().dispose();
|
@Override
|
||||||
}
|
public void run() {
|
||||||
});
|
MultiPhaseProgressMonitorWithETA.this.getDialog().dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the dialog.
|
||||||
|
*
|
||||||
* @return the JDialog for the current phase; use this judiciously to
|
* @return the JDialog for the current phase; use this judiciously to
|
||||||
* manipulate the dialog directly.
|
* manipulate the dialog directly.
|
||||||
*/
|
*/
|
||||||
public final JDialog getDialog() {
|
public final JDialog getDialog() {
|
||||||
return dialog;
|
return this.dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
/** Forge Card Game */
|
/** Forge Card Game. */
|
||||||
package forge.gui;
|
package forge.gui;
|
||||||
|
|
||||||
|
|||||||
@@ -935,7 +935,7 @@ public class Gui_HomeScreen {
|
|||||||
|
|
||||||
for (int i = 0; i < Constant.Color.BASIC_LANDS.length; i++) {
|
for (int i = 0; i < Constant.Color.BASIC_LANDS.length; i++) {
|
||||||
for (int j = 0; j < 18; j++) {
|
for (int j = 0; j < 18; j++) {
|
||||||
deck.addSideboard(Constant.Color.BASIC_LANDS[i] + "|" + sd.LandSetCode[0]);
|
deck.addSideboard(Constant.Color.BASIC_LANDS[i] + "|" + sd.getLandSetCode()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ public class OldGuiNewGame extends JFrame implements NewConstants, NewConstants.
|
|||||||
|
|
||||||
for (int i = 0; i < Constant.Color.BASIC_LANDS.length; i++) {
|
for (int i = 0; i < Constant.Color.BASIC_LANDS.length; i++) {
|
||||||
for (int j = 0; j < 18; j++) {
|
for (int j = 0; j < 18; j++) {
|
||||||
deck.addSideboard(Constant.Color.BASIC_LANDS[i] + "|" + sd.LandSetCode[0]);
|
deck.addSideboard(Constant.Color.BASIC_LANDS[i] + "|" + sd.getLandSetCode()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user