|
From: Frederick W. <fre...@us...> - 2012-01-21 15:16:55
|
LocalisedText.properties | 5 -
data/Properties.xml | 3
rails/ui/swing/GameStatus.java | 87 ++++++++++-------
rails/ui/swing/GridPanel.java | 202 +++++++++++++++++++++++++++++++++++++++--
rails/ui/swing/ORPanel.java | 18 +++
5 files changed, 269 insertions(+), 46 deletions(-)
New commits:
commit 28785080ae640691e138d8aaceb9d1c726630b22
Author: Frederick Weld <fre...@gm...>
Date: Sat Jan 21 16:10:54 2012 +0100
Introduced new option to enable/disable table borders in grid panels
By default, borders are disabled (but highlighting is always enabled).
diff --git a/LocalisedText.properties b/LocalisedText.properties
index 6deba63..ee42f0c 100644
--- a/LocalisedText.properties
+++ b/LocalisedText.properties
@@ -170,6 +170,7 @@ ComponentManagerNotReconfigured=Cannot reconfigure the ComponentManager.
ComponentManagerNotYetConfigured=ComponentManager has not yet been configured.
Config.infoText.locale=<html>te_ST shows local text keys. <br> Requires restart.</html>
Config.infoText.default_players=Enter player names separated by commas.
+Config.infoText.gridPanel.tableBorders=Grid layouts are used for the Status Window and the panel of the Operating Round Window.
Config.infoText.map.displayCurrentRoutes=If enabled, optimal train routes are displayed for the company which is currently taking its turn.
Config.infoText.map.highlightHexes=<html>If enabled, parts of the map are highlighted depending on the position of the mouse pointer:<ul><li><b>Private companies:</b> Point to the name of a private company in order to highlight the locations associated with it (e.g., its reserved hex).<ul><li>If you point to a set of private companies (in the player or company holding), the locations of all contained private companies are highlighted</ul><li><b>Minor & Public Companies:</b> Point to the name of the company in order to highlight the locations associated with it (home and destination).</ul></html>
Config.infoText.sound.backgroundMusic.stockRound=<html>Enter assignment of music files (mp3) to phases.<ul><li>Separate the assignments by commas.<li>Each assignment has the syntax phaseName=complete file path<li>Default music is defined by omitting "phaseName=" in the assignment.</ul><strong>Examples:</strong><ul><li>Set default music: <br><code>c:\SR-default.mp3</code><li>Set phase-dependent music and a default (for trains above 6): <br><code>2=c:\SR-2.mp3,3=c:\SR-3.mp3,4=c:\SR-4.mp3,5=c:\SR-5.mp3,6=c:\SR-6.mp3,c:\SR-D.mp3</code></ul> </html>
@@ -179,6 +180,7 @@ Config.label.default_players=Default players
Config.label.font.ui.name=Font selection
Config.label.font.ui.scale=Font scaling
Config.label.font.ui.style=Font style
+Config.label.gridPanel.tableBorders=Display borders in grid layouts
Config.label.local.player.name=Local player (for pbem)
Config.label.locale=Language setting
Config.label.map.autoscroll=Map autoscroll
@@ -210,7 +212,8 @@ Config.label.save.filename.extension=Filename extension
Config.label.save.recovery.active=Automatic save
Config.label.save.recovery.filepath=Automatic save filepath
Config.toolTip.local.player.name=Player name used as suffix for game save
-Config.section.Format=Format/Colors
+Config.section.Appearance=Appearance
+Config.section.Format=Format
Config.section.General=General
Config.section.Log=Log
Config.section.Font=Fonts
diff --git a/data/Properties.xml b/data/Properties.xml
index 6f89262..015513b 100644
--- a/data/Properties.xml
+++ b/data/Properties.xml
@@ -44,6 +44,9 @@
<Section name="Format">
<Property name="money_format" type="STRING" />
<Property name="or.number_format" type="LIST" values="simple,composite" />
+ </Section>
+ <Section name="Appearance">
+ <Property name="gridPanel.tableBorders" type="LIST" values="disabled,enabled"/>
<Property name="route.colour.1" type="COLOR"
initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" />
<Property name="route.colour.2" type="COLOR"
diff --git a/rails/ui/swing/GridPanel.java b/rails/ui/swing/GridPanel.java
index 5cbd1da..4941867 100644
--- a/rails/ui/swing/GridPanel.java
+++ b/rails/ui/swing/GridPanel.java
@@ -13,6 +13,7 @@ import javax.swing.border.CompoundBorder;
import org.apache.log4j.Logger;
+import rails.common.parser.Config;
import rails.game.*;
import rails.game.model.ModelObject;
import rails.game.state.BooleanState;
@@ -62,12 +63,21 @@ implements ActionListener, KeyListener {
Logger.getLogger(GridPanel.class.getPackage().getName());
private JComponent highlightedComp = null;
- protected Color tableBorderColor = Color.DARK_GRAY;
- protected Color cellOutlineColor = Color.GRAY;
- protected Color highlightedBorderColor = Color.RED;
+ protected Color tableBorderColor;
+ protected Color cellOutlineColor;
+ protected Color highlightedBorderColor;
public GridPanel() {
-
+ //initialize border colors according to the configuration
+ if ("enabled".equals(Config.get("gridPanel.tableBorders"))) {
+ tableBorderColor = Color.DARK_GRAY;
+ cellOutlineColor = Color.GRAY;
+ highlightedBorderColor = Color.RED;
+ } else {
+ tableBorderColor = getBackground();
+ cellOutlineColor = getBackground();
+ highlightedBorderColor = Color.RED;
+ }
}
public void redisplay() {
commit 82883c227ce803b4cf44a9c96c6c3739e363bc97
Author: Frederick Weld <fre...@gm...>
Date: Sat Jan 21 15:56:51 2012 +0100
Fixed game status table layout for more pretty display with borders
A lot of existing wide/narrow-gap issues became apparent when using
table borders. Issues are now fixed.
diff --git a/rails/ui/swing/GameStatus.java b/rails/ui/swing/GameStatus.java
index bb7dcb5..c2e51b3 100644
--- a/rails/ui/swing/GameStatus.java
+++ b/rails/ui/swing/GameStatus.java
@@ -259,18 +259,20 @@ public class GameStatus extends GridPanel implements ActionListener {
rowVisibilityObservers = new RowVisibility[nc];
addField(new Caption(LocalText.getText("COMPANY")), 0, 0, 1, 2,
- WIDE_RIGHT + WIDE_BOTTOM, true);
+ WIDE_BOTTOM, true);
addField(new Caption(LocalText.getText("PLAYERS")),
- certPerPlayerXOffset, 0, np, 1, 0, true);
+ certPerPlayerXOffset, 0, np, 1, WIDE_LEFT + WIDE_RIGHT, true);
for (int i = 0; i < np; i++) {
playerIndex.put(players[i], new Integer(i));
f = upperPlayerCaption[i] = new Caption(players[i].getNameAndPriority());
- addField(f, certPerPlayerXOffset + i, 1, 1, 1, WIDE_BOTTOM, true);
+ int wideGapPosition = WIDE_BOTTOM +
+ ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
+ addField(f, certPerPlayerXOffset + i, 1, 1, 1, wideGapPosition, true);
}
addField(new Caption(LocalText.getText("BANK_SHARES")),
- certInIPOXOffset, 0, 2, 1, WIDE_LEFT + WIDE_RIGHT, true);
+ certInIPOXOffset, 0, 2, 1, WIDE_RIGHT, true);
addField(new Caption(LocalText.getText("IPO")), certInIPOXOffset, 1, 1,
- 1, WIDE_LEFT + WIDE_BOTTOM, true);
+ 1, WIDE_BOTTOM, true);
addField(new Caption(LocalText.getText("POOL")), certInPoolXOffset, 1,
1, 1, WIDE_RIGHT + WIDE_BOTTOM, true);
@@ -333,7 +335,7 @@ public class GameStatus extends GridPanel implements ActionListener {
gameUIManager.getORUIManager(),c,false);
f.addMouseListener(companyCaptionMouseClickListener);
f.setToolTipText(LocalText.getText("NetworkInfoDialogTitle",c.getName()));
- addField(f, 0, certPerPlayerYOffset + i, 1, 1, WIDE_RIGHT, visible);
+ addField(f, 0, certPerPlayerYOffset + i, 1, 1, 0, visible);
for (int j = 0; j < np; j++) {
f =
@@ -341,18 +343,19 @@ public class GameStatus extends GridPanel implements ActionListener {
new Field(
players[j].getPortfolio().getShareModel(
c));
+ int wideGapPosition = ((j==0)? WIDE_LEFT : 0) + ((j==np-1)? WIDE_RIGHT : 0);
addField(f, certPerPlayerXOffset + j, certPerPlayerYOffset + i,
- 1, 1, 0, visible);
+ 1, 1, wideGapPosition, visible);
f =
certPerPlayerButton[i][j] =
new ClickField("", SELL_CMD,
LocalText.getText("ClickForSell"),
this, buySellGroup);
addField(f, certPerPlayerXOffset + j, certPerPlayerYOffset + i,
- 1, 1, 0, false);
+ 1, 1, wideGapPosition, false);
}
f = certInIPO[i] = new Field(ipo.getShareModel(c));
- addField(f, certInIPOXOffset, certInIPOYOffset + i, 1, 1, WIDE_LEFT, visible);
+ addField(f, certInIPOXOffset, certInIPOYOffset + i, 1, 1, 0, visible);
f =
certInIPOButton[i] =
new ClickField(
@@ -360,8 +363,10 @@ public class GameStatus extends GridPanel implements ActionListener {
BUY_FROM_IPO_CMD,
LocalText.getText("ClickToSelectForBuying"),
this, buySellGroup);
- addField(f, certInIPOXOffset, certInIPOYOffset + i, 1, 1, WIDE_LEFT, false);
- certInIPO[i].setPreferredSize(certInIPOButton[i].getPreferredSize());
+ addField(f, certInIPOXOffset, certInIPOYOffset + i, 1, 1, 0, false);
+
+ //no size alignment as button size could also be smaller than the field's one
+ //certInIPO[i].setPreferredSize(certInIPOButton[i].getPreferredSize());
f = certInPool[i] = new Field(pool.getShareModel(c));
addField(f, certInPoolXOffset, certInPoolYOffset + i, 1, 1,
@@ -375,7 +380,8 @@ public class GameStatus extends GridPanel implements ActionListener {
this, buySellGroup);
addField(f, certInPoolXOffset, certInPoolYOffset + i, 1, 1,
WIDE_RIGHT, false);
- certInPool[i].setPreferredSize(certInIPOButton[i].getPreferredSize());/* sic */
+ //no size alignment as button size could also be smaller than the field's one
+ //certInPool[i].setPreferredSize(certInIPOButton[i].getPreferredSize());/* sic */
if (compCanHoldOwnShares) {
f =
@@ -450,7 +456,6 @@ public class GameStatus extends GridPanel implements ActionListener {
addField (f, rightsXOffset, rightsYOffset + i, 1, 1, 0, visible);
}
-
f = new Caption(c.getName());
f.setForeground(c.getFgColour());
f.setBackground(c.getBgColour());
@@ -464,11 +469,13 @@ public class GameStatus extends GridPanel implements ActionListener {
// Player possessions
addField(new Caption(LocalText.getText("CASH")), 0, playerCashYOffset,
- 1, 1, WIDE_TOP + WIDE_RIGHT, true);
+ 1, 1, WIDE_TOP , true);
for (int i = 0; i < np; i++) {
f = playerCash[i] = new Field(players[i].getCashModel());
+ int wideGapPosition = WIDE_TOP +
+ ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
addField(f, playerCashXOffset + i, playerCashYOffset, 1, 1,
- WIDE_TOP, true);
+ wideGapPosition, true);
f =
playerCashButton[i] =
new ClickField(
@@ -477,11 +484,11 @@ public class GameStatus extends GridPanel implements ActionListener {
LocalText.getText("CorrectCashToolTip"),
this, buySellGroup);
addField(f, playerCashXOffset + i, playerCashYOffset, 1, 1,
- WIDE_TOP, false);
+ wideGapPosition, false);
}
- addField(new Caption("Privates"), 0, playerPrivatesYOffset, 1, 1,
- WIDE_RIGHT, false);
+ addField(new Caption(LocalText.getText("PRIVATES")), 0, playerPrivatesYOffset, 1, 1,
+ 0, true);
for (int i = 0; i < np; i++) {
f =
playerPrivates[i] =
@@ -490,65 +497,71 @@ public class GameStatus extends GridPanel implements ActionListener {
HexHighlightMouseListener.addMouseListener(f,
gameUIManager.getORUIManager(),
players[i].getPortfolio());
+ int wideGapPosition = ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
addField(f, playerPrivatesXOffset + i, playerPrivatesYOffset, 1, 1,
- 0, true);
+ wideGapPosition, true);
}
addField(new Caption(LocalText.getText("WORTH")), 0,
- playerWorthYOffset, 1, 1, WIDE_RIGHT, true);
+ playerWorthYOffset, 1, 1, 0, true);
for (int i = 0; i < np; i++) {
f = playerWorth[i] = new Field(players[i].getWorthModel());
- addField(f, playerWorthXOffset + i, playerWorthYOffset, 1, 1, 0, true);
+ int wideGapPosition = ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
+ addField(f, playerWorthXOffset + i, playerWorthYOffset, 1, 1, wideGapPosition, true);
}
addField(new Caption(LocalText.getText("ORWORTHINCR")), 0,
- playerORWorthIncreaseYOffset, 1, 1, WIDE_RIGHT, true);
+ playerORWorthIncreaseYOffset, 1, 1, 0, true);
for (int i = 0; i < np; i++) {
f = playerORWorthIncrease[i] = new Field(players[i].getLastORWorthIncrease());
- addField(f, playerORWorthIncreaseXOffset + i, playerORWorthIncreaseYOffset, 1, 1, 0, true);
+ int wideGapPosition = ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
+ addField(f, playerORWorthIncreaseXOffset + i, playerORWorthIncreaseYOffset, 1, 1, wideGapPosition, true);
}
addField(new Caption("Certs"), 0, playerCertCountYOffset, 1, 1,
- WIDE_RIGHT + WIDE_TOP, true);
+ WIDE_TOP, true);
for (int i = 0; i < np; i++) {
f =
playerCertCount[i] =
new Field(players[i].getCertCountModel(), false, true);
+ int wideGapPosition = WIDE_TOP +
+ ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
addField(f, playerCertCountXOffset + i, playerCertCountYOffset, 1,
- 1, WIDE_TOP, true);
+ 1, wideGapPosition, true);
}
-
+
for (int i = 0; i < np; i++) {
f = lowerPlayerCaption[i] = new Caption(players[i].getName());
- addField(f, i + 1, playerCertCountYOffset + 1, 1, 1, WIDE_TOP, true);
+ int wideGapPosition = WIDE_TOP +
+ ((i==0)? WIDE_LEFT : 0) + ((i==np-1)? WIDE_RIGHT : 0);
+ addField(f, i + 1, playerCertCountYOffset + 1, 1, 1, wideGapPosition, true);
}
// Certificate Limit
addField(new Caption(LocalText.getText("LIMIT")), certLimitXOffset - 1,
- certLimitYOffset, 1, 1, WIDE_TOP + WIDE_LEFT, true);
+ certLimitYOffset, 1, 1, WIDE_TOP, true);
addField(new Field(gameUIManager.getGameManager().getPlayerCertificateLimitModel()),
certLimitXOffset,
- certLimitYOffset, 1, 1, WIDE_TOP, true);
+ certLimitYOffset, 1, 1, WIDE_TOP + WIDE_RIGHT, true);
// Phase
addField(new Caption(LocalText.getText("PHASE")), phaseXOffset - 1,
- phaseYOffset, 1, 1, WIDE_TOP + WIDE_LEFT, true);
+ phaseYOffset, 1, 1, WIDE_TOP, true);
addField(new Field(gameUIManager.getGameManager().getPhaseManager().getCurrentPhaseModel()),
phaseXOffset,
phaseYOffset, 1, 1, WIDE_TOP, true);
// Bank
addField(new Caption(LocalText.getText("BANK")), bankCashXOffset - 1,
- bankCashYOffset - 1, 1, 2, WIDE_TOP + WIDE_LEFT, true);
+ bankCashYOffset - 1, 1, 2, WIDE_TOP, true);
addField(new Caption(LocalText.getText("CASH")), bankCashXOffset,
- bankCashYOffset - 1, 1, 1, WIDE_TOP, true);
+ bankCashYOffset - 1, 1, 1, WIDE_TOP + WIDE_RIGHT, true);
bankCash = new Field(bank.getCashModel());
- addField(bankCash, bankCashXOffset, bankCashYOffset, 1, 1, 0, true);
+ addField(bankCash, bankCashXOffset, bankCashYOffset, 1, 1, WIDE_RIGHT, true);
// Trains
addField(new Caption(LocalText.getText("TRAINS")),
- poolTrainsXOffset - 1, poolTrainsYOffset - 1, 1, 2, WIDE_TOP
- + WIDE_LEFT, true);
+ poolTrainsXOffset - 1, poolTrainsYOffset - 1, 1, 2, WIDE_TOP, true);
addField(new Caption(LocalText.getText("USED")), poolTrainsXOffset,
poolTrainsYOffset - 1, 1, 1, WIDE_TOP, true);
poolTrains = new Field(pool.getTrainsModel());
@@ -570,6 +583,10 @@ public class GameStatus extends GridPanel implements ActionListener {
addField(futureTrains, futureTrainsXOffset, futureTrainsYOffset,
futureTrainsWidth, 1, 0, true);
+ // dummy field for nice rendering of table borders
+ addField (new Caption(""), certInIPOXOffset, newTrainsYOffset + 1,
+ poolTrainsXOffset - certInIPOXOffset, 2, 0, true);
+
// Train cost overview
String text = gameUIManager.getGameManager().getTrainManager().getTrainCostOverview();
addField (f = new Caption("<html>" + text + "</html>"), poolTrainsXOffset, newTrainsYOffset + 1,
diff --git a/rails/ui/swing/GridPanel.java b/rails/ui/swing/GridPanel.java
index 58f4ae6..5cbd1da 100644
--- a/rails/ui/swing/GridPanel.java
+++ b/rails/ui/swing/GridPanel.java
@@ -130,7 +130,12 @@ implements ActionListener, KeyListener {
comp.setVisible(visible);
}
- public void setHighlight(JComponent comp,boolean isToBeHighlighted) {
+ /**
+ * highlights given component by altering its border's attributes
+ * If another component had been highlighted before, it's highlighting is first
+ * undone before highlighting the new given component.
+ */
+ protected void setHighlight(JComponent comp,boolean isToBeHighlighted) {
//quit if nothing is to be done
if (isToBeHighlighted && comp == highlightedComp) return;
removeHighlight();
@@ -144,7 +149,7 @@ implements ActionListener, KeyListener {
}
}
- public void removeHighlight() {
+ protected void removeHighlight() {
if (highlightedComp == null) return;
if (highlightedComp.getBorder() instanceof FieldBorder) {
FieldBorder fb = (FieldBorder)highlightedComp.getBorder();
@@ -153,7 +158,7 @@ implements ActionListener, KeyListener {
}
highlightedComp = null;
}
-
+
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_F1) {
HelpWindow.displayHelp(GameManager.getInstance().getHelp());
@@ -276,13 +281,13 @@ implements ActionListener, KeyListener {
public void paintBorder(Component c,Graphics g, int x, int y, int width,int height) {
Graphics2D g2d = (Graphics2D)g;
+ Stroke oldStroke = g2d.getStroke();
+ g2d.setStroke(new BasicStroke(thickness));
if (isHighlighted) {
g2d.setColor(highlightedBorderColor);
} else {
g2d.setColor(borderColor);
}
- Stroke oldStroke = g2d.getStroke();
- g2d.setStroke(new BasicStroke(thickness));
g2d.drawRect(x, y, width-1, height-1);
g2d.setStroke(oldStroke);
}
diff --git a/rails/ui/swing/ORPanel.java b/rails/ui/swing/ORPanel.java
index 4a0d059..ffeabf8 100644
--- a/rails/ui/swing/ORPanel.java
+++ b/rails/ui/swing/ORPanel.java
@@ -792,7 +792,6 @@ implements ActionListener, KeyListener, RevenueListener {
//clear all highlighting (president column and beyond)
resetActions();
- removeHighlight();
}
@@ -917,6 +916,8 @@ implements ActionListener, KeyListener, RevenueListener {
}
undoButton.setEnabled(false);
+ removeHighlight();
+
}
public void resetORCompanyTurn(int orCompIndex) {
@@ -1233,7 +1234,6 @@ implements ActionListener, KeyListener, RevenueListener {
//clear all highlighting (president column and beyond)
resetActions();
- removeHighlight();
button1.setEnabled(false);
commit fa6e193f977764f5ba4d3d02d0da50c516629109
Author: Frederick Weld <fre...@gm...>
Date: Sat Jan 21 14:15:34 2012 +0100
Introduced highlighting and table borders for Status Win & ORPanel
Instead of insets as parts of GridBag constraints, GridPanel now
attaches dynamic borders to the fields.
This has enabled the following:
- GridPanel table borders are visualized without any effort - making
the panels much nicer
- GridPanel cells (fields,...) can now be highlighted by altering
their dynamic borders
- even inner borders (margins) used for the highlight outline box
- design corresponds to the one used for displaying selected
tiles in the hex map
diff --git a/rails/ui/swing/GridPanel.java b/rails/ui/swing/GridPanel.java
index 661c8b3..58f4ae6 100644
--- a/rails/ui/swing/GridPanel.java
+++ b/rails/ui/swing/GridPanel.java
@@ -7,18 +7,25 @@ import java.util.*;
import java.util.List;
import javax.swing.*;
+import javax.swing.border.AbstractBorder;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
import org.apache.log4j.Logger;
import rails.game.*;
import rails.game.model.ModelObject;
import rails.game.state.BooleanState;
+import rails.ui.swing.elements.Caption;
+import rails.ui.swing.elements.ClickField;
import rails.ui.swing.elements.Field;
import rails.ui.swing.elements.ViewObject;
public abstract class GridPanel extends JPanel
implements ActionListener, KeyListener {
+ private static final long serialVersionUID = 1L;
+
protected static final int NARROW_GAP = 1;
protected static final int WIDE_GAP = 3;
protected static final int WIDE_LEFT = 1;
@@ -54,6 +61,14 @@ implements ActionListener, KeyListener {
protected static Logger log =
Logger.getLogger(GridPanel.class.getPackage().getName());
+ private JComponent highlightedComp = null;
+ protected Color tableBorderColor = Color.DARK_GRAY;
+ protected Color cellOutlineColor = Color.GRAY;
+ protected Color highlightedBorderColor = Color.RED;
+
+ public GridPanel() {
+
+ }
public void redisplay() {
revalidate();
@@ -74,19 +89,35 @@ implements ActionListener, KeyListener {
protected void addField(JComponent comp, int x, int y, int width, int height,
int wideGapPositions, boolean visible) {
- int padTop, padLeft, padBottom, padRight;
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.weightx = gbc.weighty = 0.5;
gbc.fill = GridBagConstraints.BOTH;
- padTop = (wideGapPositions & WIDE_TOP) > 0 ? WIDE_GAP : NARROW_GAP;
- padLeft = (wideGapPositions & WIDE_LEFT) > 0 ? WIDE_GAP : NARROW_GAP;
+ gbc.insets = new Insets(0,0,0,0);
+
+ //special handling of clickfields as their compound border does not fit
+ //to this field border logic
+ if ((comp instanceof ClickField)) {
+ comp.setBorder(BorderFactory.createLineBorder(new Color(0,0,0,0),1));
+ }
+
+ int padTop, padLeft, padBottom, padRight;
+ padTop = (wideGapPositions & WIDE_TOP) > 0 ? WIDE_GAP - NARROW_GAP : 0;
+ padLeft = (wideGapPositions & WIDE_LEFT) > 0 ? WIDE_GAP - NARROW_GAP : 0;
padBottom =
- (wideGapPositions & WIDE_BOTTOM) > 0 ? WIDE_GAP : NARROW_GAP;
- padRight = (wideGapPositions & WIDE_RIGHT) > 0 ? WIDE_GAP : NARROW_GAP;
- gbc.insets = new Insets(padTop, padLeft, padBottom, padRight);
+ (wideGapPositions & WIDE_BOTTOM) > 0 ? WIDE_GAP - NARROW_GAP : 0;
+ padRight = (wideGapPositions & WIDE_RIGHT) > 0 ? WIDE_GAP - NARROW_GAP : 0;
+
+ //set field borders
+ //- inner border: the field's native border
+ //- outline border: the field's outline (in narrow_gap thickness)
+ //- outer border: grid table lines (in wide_gap - narrow_gap thickness)
+
+ comp.setBorder(new FieldBorder(comp.getBorder(),
+ new DynamicSymmetricBorder(cellOutlineColor,NARROW_GAP),
+ new DynamicAsymmetricBorder(tableBorderColor,padTop,padLeft,padBottom,padRight)));
gridPanel.add(comp, gbc);
@@ -98,6 +129,30 @@ implements ActionListener, KeyListener {
if (fields != null && fields[x][y] == null) fields[x][y] = comp;
comp.setVisible(visible);
}
+
+ public void setHighlight(JComponent comp,boolean isToBeHighlighted) {
+ //quit if nothing is to be done
+ if (isToBeHighlighted && comp == highlightedComp) return;
+ removeHighlight();
+ if (isToBeHighlighted) {
+ if (comp.getBorder() instanceof FieldBorder) {
+ FieldBorder fb = (FieldBorder)comp.getBorder();
+ fb.setHighlight(isToBeHighlighted);
+ comp.repaint();
+ }
+ highlightedComp = comp;
+ }
+ }
+
+ public void removeHighlight() {
+ if (highlightedComp == null) return;
+ if (highlightedComp.getBorder() instanceof FieldBorder) {
+ FieldBorder fb = (FieldBorder)highlightedComp.getBorder();
+ fb.setHighlight(false);
+ highlightedComp.repaint();
+ }
+ highlightedComp = null;
+ }
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_F1) {
@@ -169,4 +224,122 @@ implements ActionListener, KeyListener {
}
}
+ /**
+ * Wrapper for three level compound borders and directly accessing border constituents
+ * @author Frederick Weld
+ *
+ */
+ private class FieldBorder extends CompoundBorder {
+ private static final long serialVersionUID = 1L;
+ Border nativeInnerBorder;
+ DynamicAsymmetricBorder highlightedInnerBorder;
+ DynamicSymmetricBorder outlineBorder;
+ DynamicAsymmetricBorder outerBorder;
+ public FieldBorder(Border innerBorder,DynamicSymmetricBorder outlineBorder,DynamicAsymmetricBorder outerBorder) {
+ super(new CompoundBorder(outerBorder,outlineBorder),innerBorder);
+ this.nativeInnerBorder = innerBorder;
+ this.outlineBorder = outlineBorder;
+ this.outerBorder = outerBorder;
+ this.highlightedInnerBorder = new DynamicAsymmetricBorder(
+ highlightedBorderColor,
+ nativeInnerBorder.getBorderInsets(null).top,
+ nativeInnerBorder.getBorderInsets(null).left,
+ nativeInnerBorder.getBorderInsets(null).bottom,
+ nativeInnerBorder.getBorderInsets(null).right);
+ }
+ public void setHighlight(boolean isToBeHighlighted) {
+ outlineBorder.setHighlight(isToBeHighlighted);
+ this.insideBorder = isToBeHighlighted ?
+ highlightedInnerBorder : nativeInnerBorder;
+ }
+ }
+
+ /**
+ * A line border providing methods for changing the look
+ * @author Frederick Weld
+ *
+ */
+ private class DynamicSymmetricBorder extends AbstractBorder {
+ private static final long serialVersionUID = 1L;
+ private int thickness;
+ private Color borderColor;
+ private boolean isHighlighted = false;
+ public DynamicSymmetricBorder (Color borderColor,int thickness) {
+ this.thickness = thickness;
+ this.borderColor = borderColor;
+ }
+ public void setHighlight(boolean isToBeHighlighted) {
+ if (isHighlighted != isToBeHighlighted) {
+ isHighlighted = isToBeHighlighted;
+ }
+ }
+
+ public void paintBorder(Component c,Graphics g, int x, int y, int width,int height) {
+ Graphics2D g2d = (Graphics2D)g;
+ if (isHighlighted) {
+ g2d.setColor(highlightedBorderColor);
+ } else {
+ g2d.setColor(borderColor);
+ }
+ Stroke oldStroke = g2d.getStroke();
+ g2d.setStroke(new BasicStroke(thickness));
+ g2d.drawRect(x, y, width-1, height-1);
+ g2d.setStroke(oldStroke);
+ }
+
+ public Insets getBorderInsets (Component c) {
+ return new Insets(thickness,thickness,thickness,thickness);
+ }
+
+ public boolean isBorderOpaque() {
+ return true;
+ }
+ }
+ /**
+ * An asymmetric line border providing methods for changing the look
+ * @author Frederick Weld
+ *
+ */
+ private class DynamicAsymmetricBorder extends AbstractBorder {
+ private static final long serialVersionUID = 1L;
+ private int padTop, padLeft, padBottom, padRight;
+ private Color borderColor;
+ public DynamicAsymmetricBorder (Color borderColor,int padTop, int padLeft, int padBottom, int padRight) {
+ this.padTop = padTop;
+ this.padLeft = padLeft;
+ this.padBottom = padBottom;
+ this.padRight = padRight;
+ this.borderColor = borderColor;
+ }
+ public void paintBorder(Component c,Graphics g, int x, int y, int width,int height) {
+ Graphics2D g2d = (Graphics2D)g;
+ g2d.setColor(borderColor);
+ Stroke oldStroke = g2d.getStroke();
+ if (padTop > 0) {
+ g2d.setStroke(new BasicStroke(padTop));
+ g2d.fillRect(x, y, width, padTop);
+ }
+ if (padLeft > 0) {
+ g2d.setStroke(new BasicStroke(padLeft));
+ g2d.fillRect(x, y, padLeft, height);
+ }
+ if (padBottom > 0) {
+ g2d.setStroke(new BasicStroke(padBottom));
+ g2d.fillRect(x, y+height-padBottom, width, padBottom);
+ }
+ if (padRight > 0) {
+ g2d.setStroke(new BasicStroke(padRight));
+ g2d.fillRect(x+width-padRight, y, padRight, height);
+ }
+ g2d.setStroke(oldStroke);
+ }
+
+ public Insets getBorderInsets (Component c) {
+ return new Insets(padTop,padLeft,padBottom,padRight);
+ }
+
+ public boolean isBorderOpaque() {
+ return true;
+ }
+ }
}
diff --git a/rails/ui/swing/ORPanel.java b/rails/ui/swing/ORPanel.java
index 8a47981..4a0d059 100644
--- a/rails/ui/swing/ORPanel.java
+++ b/rails/ui/swing/ORPanel.java
@@ -491,7 +491,7 @@ implements ActionListener, KeyListener, RevenueListener {
HexHighlightMouseListener.addMouseListener(f,
orUIManager,c.getPortfolio());
addField(f, privatesXOffset, privatesYOffset + i, 1, 1,
- WIDE_RIGHT, visible);
+ 0, visible);
f =
newPrivatesCost[i] =
@@ -792,6 +792,7 @@ implements ActionListener, KeyListener, RevenueListener {
//clear all highlighting (president column and beyond)
resetActions();
+ removeHighlight();
}
@@ -1002,7 +1003,9 @@ implements ActionListener, KeyListener, RevenueListener {
this.orComp = orComp;
this.orCompIndex = orCompIndex;
president[orCompIndex].setHighlight(true);
-
+
+ removeHighlight();
+
buttonOC.clearPossibleActions();
button1.clearPossibleActions();
button2.clearPossibleActions();
@@ -1016,10 +1019,11 @@ implements ActionListener, KeyListener, RevenueListener {
updateCurrentRoutes(false);
}
-
+
public void initTileLayingStep() {
tileCaption.setHighlight(true);
+ setHighlight(tiles[orCompIndex],true);
button1.setVisible(false);
}
@@ -1027,6 +1031,7 @@ implements ActionListener, KeyListener, RevenueListener {
public void initTokenLayingStep() {
tokenCaption.setHighlight(true);
+ setHighlight(tokens[orCompIndex],true);
button1.setEnabled(false);
button1.setVisible(false);
button3.setEnabled(false);
@@ -1036,6 +1041,7 @@ implements ActionListener, KeyListener, RevenueListener {
public void initRevenueEntryStep(int orCompIndex, SetDividend action) {
revenueCaption.setHighlight(true);
+ setHighlight(revenueSelect[orCompIndex],true);
revenueSelect[orCompIndex].setValue(action.getPresetRevenue());
setSelect(revenue[orCompIndex], revenueSelect[orCompIndex], true);
@@ -1074,6 +1080,8 @@ implements ActionListener, KeyListener, RevenueListener {
public void initPayoutStep(int orCompIndex, SetDividend action,
boolean withhold, boolean split, boolean payout) {
+ setHighlight(revenue[orCompIndex],true);
+
SetDividend clonedAction;
setSelect(revenue[orCompIndex], revenueSelect[orCompIndex], false);
@@ -1120,6 +1128,7 @@ implements ActionListener, KeyListener, RevenueListener {
public void initTrainBuying(boolean enabled) {
trainCaption.setHighlight(true);
+ setHighlight(trains[orCompIndex],true);
button1.setText(LocalText.getText("BUY_TRAIN"));
button1.setActionCommand(BUY_TRAIN_CMD);
@@ -1149,6 +1158,7 @@ implements ActionListener, KeyListener, RevenueListener {
button2.setEnabled(enabled);
button2.setVisible(enabled);
privatesCaption.setHighlight(enabled);
+ setHighlight(privates[orCompIndex],enabled);
} else {
button2.setVisible(false);
}
@@ -1201,6 +1211,7 @@ implements ActionListener, KeyListener, RevenueListener {
repayLoans.setEnabled(true);
loansCaption.setHighlight(true);
+ setHighlight(compLoans[orCompIndex],true);
button1.setText(LocalText.getText("RepayLoans"));
button1.setActionCommand(REPAY_LOANS_CMD);
@@ -1222,6 +1233,7 @@ implements ActionListener, KeyListener, RevenueListener {
//clear all highlighting (president column and beyond)
resetActions();
+ removeHighlight();
button1.setEnabled(false);
|