⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statuspanel.java

📁 ErGo是一个很早的Java通用围棋服务器(IGS/NNGS)客户端程序。有全部源码和文档
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    }

    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 + -