📄 statuspanel.java
字号:
}
public Dimension getMinimumSize () {
return getPreferredSize();
}
} // end inner class PlayerStatusCanvas
///
/// CurrentMoveCanvas
///
class CurrentMoveCanvas extends ErgoCanvas {
private String widthString = "#123 C19 (Ko @ C18)"; // plus a stone width
public void paint (Graphics g) {
needsRedisplay = true;
update(g);
}
public void update (Graphics g) {
if (getSize().height != height || getSize().width != width) {
width = getSize().width;
height = getSize().height;
}
// Clear entire canvas
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
g.setColor(getForeground());
int y = margin + metrics.getAscent();
// Draw the current move
Move m = gwin.game.getCurrentMove();
if (m.moveNumber() < 0)
g.drawString("---", margin, y);
else if (m instanceof GameResultMove)
g.drawString(m.toString(), margin, y);
else {
String movenum = "#" + (m.moveNumber() + 1) + " ";
int x = margin;
g.drawString(movenum, x, y);
x += metrics.stringWidth(movenum);
Image im = (m.color() == Move.BLACK) ? bsmall : wsmall;
g.drawImage(im, x, y - metrics.getAscent(), this);
x += im.getWidth(this) + 5;
g.drawString(m.toString()
+ ((ko == null) ? "" : " (Ko @ " + ko + ")"), x, y);
}
}
public Dimension getPreferredSize () {
return new Dimension(metrics.stringWidth(widthString) + margin * 2
+ bsmall.getWidth(this),
metrics.getHeight() + margin * 2);
}
public Dimension getMinimumSize () {
return getPreferredSize();
}
} // end inner class CurrentMoveCanvas
///
/// MessagesCanvas - Displays "Adjourned", "Game Over", and result messages
///
class MessagesCanvas extends ErgoCanvas {
public void paint (Graphics g) {
update(g);
}
public void update (Graphics g) {
if (getSize().height != height || getSize().width != width) {
width = getSize().width;
height = getSize().height;
}
// Clear entire canvas
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
g.setColor(getForeground());
int fh = metrics.getHeight();
int upperbase = margin + metrics.getAscent();
int lowerbase = upperbase + fh;
int midbase = upperbase + (fh / 2);
if (gwin.game.scoringMode()) {
int bscore = gwin.game.blackTerritory();
int wscore = gwin.game.whiteTerritory();
int bcapt = gwin.game.capturedBlack();
int wcapt = gwin.game.capturedWhite();
double komi = gwin.game.komi();
String bstring = (bscore + "+" + wcapt + "=" + (bscore + wcapt));
String wstring = (wscore + "+" + bcapt + "+" + komi
+ "=" + (wscore + bcapt + komi));
g.drawImage(btiny, margin, margin, this);
g.drawString(bstring, margin + btiny.getWidth(this) + 5, upperbase);
g.drawImage(wtiny, margin,
height - wtiny.getHeight(this) - margin, this);
g.drawString(wstring, margin + wtiny.getWidth(this) + 5, lowerbase);
}
else if (gwin.gameStatus == GameWindow.ADJOURNED) {
g.setColor(Color.red);
g.drawString("Adjourned",
(width / 2) - (metrics.stringWidth("Adjourned") / 2),
midbase);
}
else if (gwin.gameStatus == GameWindow.GAMEOVER) {
g.setColor(Color.red);
g.drawString("Game Over",
(width / 2) - (metrics.stringWidth("Game Over") / 2),
upperbase);
String result = gwin.game.SGFresult();
g.drawString(result, (width / 2) - (metrics.stringWidth(result) / 2),
lowerbase);
}
else {
if (gwin.game.isFree()) {
g.setColor(Color.red);
// +++ Display whether or not it's a teaching game here (and/or in title)
String s = "FREE GAME";
g.drawString(s, (width / 2) - (metrics.stringWidth(s) / 2), midbase);
g.setColor(getForeground());
}
}
g.setColor(getForeground());
}
// The width we return here isn't very important, as the canvas will
// be widened by the ColumnLayout it is added to.
public Dimension getPreferredSize () {
return new Dimension(metrics.stringWidth("My dog has fleas."), // uh huh
metrics.getHeight() * 2 + margin * 2);
}
public Dimension getMinimumSize () {
return getPreferredSize();
}
} // end inner class MessagesCanvas
///
/// GameStatusCanvas - Displays komi, handicap, and byo-yomi
///
class GameStatusCanvas extends ErgoCanvas {
public void paint (Graphics g) {
update(g);
}
public void update (Graphics g) {
if (getSize().height != height || getSize().width != width) {
width = getSize().width;
height = getSize().height;
}
// Clear entire canvas
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
g.setColor(getForeground());
int fh = metrics.getHeight();
int base1 = margin + metrics.getAscent();
int base2 = base1 + fh;
int base3 = base2 + fh;
g.drawString("Handicap: " + gwin.game.handicap(), margin, base1);
g.drawString("Komi: " + gwin.game.komi(), margin, base2);
int byotime = gwin.game.byotime();
g.drawString("Byo-yomi: " + ((byotime == -1) ? "None" : "" + byotime), margin, base3);
}
// The width we return here isn't very important, as the canvas will
// be widened by the ColumnLayout it is added to.
public Dimension getPreferredSize () {
return new Dimension(metrics.stringWidth("My dog has fleas."), // uh huh
metrics.getHeight() * 3 + margin * 2);
}
public Dimension getMinimumSize () {
return getPreferredSize();
}
} // end inner class GameStatusCanvas
} // end class StatusPanel
/**
* TimerCanvas displays both the black and white countdown timers
* and the stones left to play in byo yomi (if any).
*
* For now the entire canvas is repainted each time update() is called.
*/
class TimerCanvas extends ErgoCanvas implements Optionizable, PopupContributor {
private Timer timer = new Timer(1000);
private int seconds = 0;
private int threshold = 60; // Change to Color.red when seconds < this.
private int stones = -1; // -1 if not in byo yomi yet.
private String widthString = "-0:00:00 (25)";
private Image offscreen;
private char[] buffer = new char[13]; // to hold "-9:00:00 (25)"
private String timerString = "Timer font";
private Font timerFont = null;
private boolean addtime;
private SimpleServerConnection conn;
private TimerCanvas () {} // Disallow zero arg constructor
/** @param addtime boolean specifying whether to add the "addtime" menu items
* to the popup menu.
*/
public TimerCanvas (SimpleServerConnection conn, boolean addtime) {
this.conn = conn;
this.addtime = addtime;
try {
ergo.Ergo.opser.expressOwnership(timerString, Optionizer.TYPE_FONT, this, null);
timerFont = ergo.Ergo.opser.getFontOption(timerString);
}
catch (Exception e) {
timerFont = new Font("SansSerif", Font.PLAIN, 18); // meta default
}
timer.start();
stopTicking();
setFont(timerFont);
}
// Called when the window is closed.
//
public void commitSuicide () {
startTicking();
timer.stop();
}
// support the Optionizable interface.
//
public void optionEvent (String keyword, Object value) {
if (ergo.Ergo.opser.isSameKey(keyword, timerString)) {
timerFont = (Font)value;
setFont(timerFont);
}
}
public void setTime (int seconds, int stones) {
this.seconds = seconds;
this.stones = stones;
repaint();
}
// +++ This causes a security exception in browsers. Should probably be
// using wait() and notify() here. I assume those don't cause an exception.
public void stopTicking () {
timer.suspend();
}
public void startTicking () {
timer.resume();
}
/**
* Put the time left into the form h...h:mm:ss.
* Returns the index in chars of the first character to be displayed.
*/
private int toChars (char[] chars, int interval) {
try {
int x;
int remaining = Math.abs(interval);
int index = chars.length - 1;
// what a mess...
int hours = remaining / 3600;
int left = remaining % 3600;
int minutes = left / 60;
int seconds = left % 60;
chars[index--] = Util.DIGITS[seconds % 10];
chars[index--] = Util.DIGITS[seconds / 10];
chars[index--] = ':';
chars[index--] = Util.DIGITS[minutes % 10];
chars[index--] = Util.DIGITS[minutes / 10];
if (hours > 0) {
chars[index--] = ':';
String s = Integer.toString(hours);
for (int i = s.length() -1; i >= 0; i--)
chars[index--] = s.charAt(i);
}
if (interval < 0)
chars[index--] = '-';
return index + 1;
}
catch (ArrayIndexOutOfBoundsException e) {
return 0; // Just draw what we got. Truncate the rest.
}
}
public void paint (Graphics g) {
update(g);
}
public void update (Graphics g) {
Graphics og = null;
if (getSize().width != width || getSize().height != height) {
width = getSize().width;
height = getSize().height;
if (offscreen != null) offscreen.flush();
offscreen = createImage(width, height);
og = offscreen.getGraphics();
}
if (og == null)
og = offscreen.getGraphics();
og.setColor(getBackground());
og.fillRect(0, 0, width, height);
FontMetrics met = og.getFontMetrics();
int fh = met.getHeight();
// Draw it.
og.setColor(getForeground());
int bbase = (height - fh) / 2 + met.getAscent();
int x1 = 0;
if (seconds <= 60) og.setColor(Color.red);
int startIndex = Math.max(0, toChars(buffer, seconds));
og.drawChars(buffer, startIndex, buffer.length - startIndex, x1, bbase);
int x2 = x1 + met.charsWidth(buffer, startIndex,
buffer.length - startIndex);
og.setColor(getForeground());
if (stones != -1)
og.drawString(" (" + stones + ")", x2, bbase);
g.drawImage(offscreen, 0, 0, this);
}
public Dimension getMinimumSize () {
return getPreferredSize();
}
public Dimension getPreferredSize () {
Dimension d = new Dimension();
FontMetrics m = getFontMetrics(getFont());
d.width = m.stringWidth(widthString);
d.height = m.getHeight() + 4;
return d;
}
// Return the diameter of the stone image that should be drawn next to
// this timer, based on the size of the timer font. 2 is a fudge-factor.
// The image looks best if it's a bit bigger than the font height.
//
public int getStoneDiameter () {
return getFontMetrics(getFont()).getHeight() + 2;
}
public void tick (Timer t) {
--seconds;
repaint();
}
class Timer extends Thread {
private int interval;
public Timer (int interval) {
this.interval = interval;
setDaemon(true);
}
public void run () {
while (true) {
try {
sleep(interval);
}
catch (InterruptedException e) {}
TimerCanvas.this.tick(this);
}
}
} // end inner class Timer
//
// Implement the PopupContributor interface.
//
public boolean allowMoreItems (Component soure) {
return true;
}
private class AddtimeCommand extends MenuCommand {
int minutes;
public AddtimeCommand (int minutes) {
super("addtime " + minutes);
this.minutes = minutes;
}
public void executeCommand (Object source) {
conn.send("addtime " + minutes, true);
}
} // end inner class AddtimeCommand
private AddtimeCommand addtime1 = null;
private AddtimeCommand addtime2 = null;
private AddtimeCommand addtime5 = null;
public void populatePopupMenu (PopupMenu p, Component origin, int x, int y) {
if (addtime) {
if (p.countItems() > 0)
p.addSeparator();
if (addtime1 == null) {
addtime1 = new AddtimeCommand(1);
addtime2 = new AddtimeCommand(2);
addtime5 = new AddtimeCommand(5);
}
// I figure since the only time these items will appear in the menu is when you
// click on your opponent's clock it won't be too clunky to have three of them.
p.add(addtime1);
p.add(addtime2);
p.add(addtime5);
}
}
} // end class TimerCanvas
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -