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

📄 multibox.java

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

    public void updateInternal () { // small enough that redraw whole thing
      getPreferredSize();
      offg.setColor(parent.unselectedBackground);
      offg.fillRect(0, 0, preferredSize.width, preferredSize.height);
      FontMetrics fg = offg.getFontMetrics();
      for (int i = 0; i < parent.columns(); ++i) {
	offg.setColor(parent.unselectedText);
	offg.drawString(parent.headingAt(i), parent.pixposition(i),
			parent.toplinepix());
	int linewidth = fg.stringWidth(parent.headingAt(i));
	offg.setColor(parent.selectedBackground);
	offg.drawLine(parent.pixposition(i) + LIP, 
		      preferredSize.height - BAR_HEIGHT,   
		      parent.pixposition(i) + linewidth - LIP, 
		      preferredSize.height - BAR_HEIGHT); 
      }
    }

    public void reJig () {		// call when width changes - i.e. font.
      offi = null;		// provoke us to remake offscreen.
      repaint();
    }

    public void update(Graphics g) {
      if (g == null)
	return;
      if (offi == null) {
	offi = createImage(parent.pixwidth(), parent.lineheight() + EXTRA_HEIGHT);
	offg = offi.getGraphics();
	offg.setFont(parent.listFont);
	updateInternal();		// uI called if color changes.
      }
      int realwidth = parent.listCanvas.getSize().width; 
      width = getSize().width;
      height = getSize().height;
      g.clipRect(0, 0, realwidth, height);
      g.drawImage(offi, -xoffset, 0, null);
      if (realwidth > parent.pixwidth()) {
	g.setColor(parent.unselectedBackground);
	g.fillRect(parent.pixwidth() + xoffset, 0, 
		   realwidth - parent.pixwidth(),
		   parent.lineheight() + EXTRA_HEIGHT);
      }
    }

    public void paint(Graphics g) {
      update(g);
    }

    public Dimension getPreferredSize () {
      preferredSize.width = parent.pixwidth();
      preferredSize.height = parent.lineheight() + EXTRA_HEIGHT;
      return preferredSize;
    }

    public Dimension getMinimumSize () {
      return getPreferredSize();
    }
  }  // end inner class MultiHeadingCanvas

  /** LineData is the internal storage per item used by MultiBox. It contains an
    * Object, theUseful, which is storage for client(of MultiBox)--based
    * information; for example, ServerPlayerContainer uses it to store
    * ServerPlayers. field contains a string for each text field of the item,
    * plus a final extra "field" which is non-null to represent "activity" of the
    * item.
    **/
  class LineData {
    Object theUseful;
    String[] fields;

    LineData(Object theUseful1, String[] fields1) {
      // near copy-constructor, just to inhibit nasty fiddlings
      // with fields, without proper channels....
      theUseful = theUseful1;
      fields = new String[fields1.length];
      for (int i = 0; i < fields1.length; ++i) {
	fields[i] = fields1[i];
      }
    }
  }

  // Moved these out of MultiListCanvas to satisfy the compiler.
  private static final int BITMAP_YINC = 10;
  private static final int BITMAP_YINIT = 20;

  /** MultiListCanvas draws the actual list for a MultiBox.
    * It also reaches out into the MultiBox to manage scrollbars.
    * The reVScroll() method should be called to inform the vertical
    * scrollbar of changes in list contents.
    * It intercepts reshape() requests to determine its own size.
    * It can draw a single selection, and also examines the final
    * "invisible" field of each line for nullness, to decide whether to
    * mark the line as "active", currently represented by cross-hatching.
    **/

  class MultiListCanvas extends Canvas {
    private MultiBox parent;
    private Graphics offg;
    private Image offi;

    private int xoffset, yoffset;
    public int yoffset () { return yoffset; }
    public int xoffset () { return xoffset; }

    private Dimension preferredSize = new Dimension();
    //  private int width, height;
    private int bitmapheight = BITMAP_YINIT;
    private Image hatcher;
    private Image hatchers;

    MultiListCanvas(MultiBox parent1) {
      parent = parent1;
      addComponentListener(new sizeListener());
      //    allocateOff();
    }

    private void expandInternal () {
      bitmapheight += BITMAP_YINC;
      allocateOff();
    }

    private void allocateOff () {
      offi = createImage(parent.pixwidth(), parent.lineheight() * bitmapheight);
      //    System.out.println(" "+offi + parent.pixwidth() + " " + parent.lineheight()*bitmapheight);
      if (offi == null)
	return;			//during constructor??
      int bmcx = parent.pixposition(1) - parent.gutter();
      int bmcy = parent.lineheight();
      int[] bmh = new int[bmcx * bmcy];
      int[] bmhs = new int[bmcx * bmcy];
      int utrgb = parent.unselectedText.getRGB();
      int strgb = parent.selectedText.getRGB();
      for (int i = 0; i < bmcy; ++ i) {
	for (int j = 0; j < bmcx; ++ j) {
	  if ((i + j) % 5 == 0) {
	    bmh[i * bmcx + j] = utrgb;
	    bmhs[i * bmcx + j] = strgb;
	  }
	}
      }
      hatcher = createImage(new MemoryImageSource(bmcx, bmcy, bmh, 0, bmcx));
      hatchers = createImage(new MemoryImageSource(bmcx, bmcy, bmhs, 0, bmcx));
      offg = offi.getGraphics();
      offg.setFont(parent.listFont);
      updateInternal();
    }

    public void reJig () {		// call when width changes - i.e. font.
      allocateOff();
      repaint();
    }

    public void updateInternal () { // small enough that redraw whole thing
      getPreferredSize();
      updateInternal(0, parent.lines() - 1);
    }

    public void updateLine(int line) {
      if (line < 0 || line >= parent.lines())
	return;
      updateInternal(line, line);
    }

    public void updateInternal(int topline, int bottomline) {
      if (offg == null
	  || (bottomline - topline) < 0)
	return;
      //    System.out.println("uI "+topline+" "+bottomline);
      getPreferredSize();
      if (parent.lines() > bitmapheight) { // if exceeded dimensions of offscreen,
	// expand it, and change request to complete redraw....
	expandInternal();
	topline = 0;
	bottomline = parent.lines() - 1;
      }
      int selected = parent.getSelectedIndex();
      offg.setColor(parent.unselectedBackground);
      if (selected >= topline && selected <= bottomline) {
	// The selected item is in the visible area...
	// +++ Why two calls to fillRect() here?  Seems could just clear the
	//     whole thing since the selected item area gets colored in later.
	offg.fillRect(0, topline * parent.lineheight(), preferredSize.width,
		      (selected - topline) * parent.lineheight());
	offg.fillRect(0, (selected + 1) * parent.lineheight(), preferredSize.width,
		      (bottomline - selected) * parent.lineheight());
	offg.setColor(parent.selectedBackground);
	offg.fillRect(0, selected * parent.lineheight(), preferredSize.width,
		      parent.lineheight());
      }
      else {			// draw unselected region background
	offg.fillRect(0, topline * parent.lineheight(), preferredSize.width,
		      (1 + bottomline - topline) * parent.lineheight());
      }
      offg.setColor(parent.unselectedText);
      FontMetrics fm = getFontMetrics(parent.listFont);
      for (int i = topline; i <= bottomline; ++i) {
	if (i == selected)
	  offg.setColor(parent.selectedText);
	// hatch drawing moved up for improved visibility.
	if (parent.fieldAt(i, parent.columns()) != null) {
	  if (i == selected)
	    offg.drawImage(hatchers, 0, i * parent.lineheight(), this);
	  else 
	    offg.drawImage(hatcher, 0, i * parent.lineheight(), this);
	}

	for (int j = 0; j < parent.columns(); ++j) {
	  int spos = parent.pixposition(j); // default is left justify.
	  String format = parent.formatAt(j);
	  if (format.equals("r")) {
	    spos = parent.pixposition(j + 1) - parent.gutter() -
	      fm.stringWidth(parent.fieldAt(i, j));
	  }
	  // +++ This is repeatedly calling fieldAt, which calls lineDataAt,
	  //     which calls Vector.elementAt, which is notoriously slow.
	  //     Should call lineDataAt once per line only.
	  offg.drawString(parent.fieldAt(i, j), spos,
			  parent.toplinepix() + i * parent.lineheight());
	}				// end each column
	// now deal with activity
	if (i == selected)
	  offg.setColor(parent.unselectedText);
      }				// end each line
      int topreppos = topline * parent.lineheight() - yoffset;
      if (bottomline == parent.lines() - 1) // if showing bottom line, do blank too 
	repaint(0 - xoffset, topreppos, getSize().width, getSize().height - topreppos);
      else 
	repaint(0 - xoffset, topreppos, getSize().width, 
		(1 + bottomline - topline) * parent.lineheight() );
    }

    public void update(Graphics g) {
      if (g == null)
	return;
      int width = getSize().width;
      int height = getSize().height;
      if (offi == null)
	allocateOff();
      //    g.drawImage(offi, -xoffset, -yoffset, null);
      //    System.out.println(" "+width+" "+parent.pixwidth());
      //    System.out.println(" "+height+" "+parent.pixheight());
      if (width > parent.pixwidth()) { // draw the bit off to the right
	int pw = parent.pixwidth() - xoffset;
	int sw = (width - parent.pixwidth());
	int selected = parent.getSelectedIndex();
	//      System.out.println(" "+pw+" "+sw+" "+selected);
	g.setColor(parent.unselectedBackground);
	if (selected >= 0) {
	  g.fillRect(pw, -yoffset, sw, selected * parent.lineheight());
	  g.fillRect(pw, (selected + 1) * parent.lineheight() - yoffset, sw, 
		     (parent.lines() - selected) * parent.lineheight());
	  g.setColor(parent.selectedBackground);
	  g.fillRect(pw, selected * parent.lineheight() - yoffset, sw,
		     parent.lineheight());
	}
	else {
	  g.fillRect(pw, -yoffset, sw, parent.pixheight());
	}
      }
      int bp = parent.pixheight() - yoffset; // bottom pixel of list posn
      if (height > bp) {			   // draw the bit off the bottom
	g.setColor(parent.unselectedBackground);
	g.fillRect(0, bp, width, height - bp);
      }
      Rectangle atrect = new Rectangle(-xoffset, -yoffset, parent.pixwidth(),
				       parent.pixheight());
      Rectangle cliprect = g.getClipBounds();
      if (cliprect == null)
	return;			// if the bastard won't give us a clipRect.
      atrect = atrect.intersection(g.getClipBounds());
      g.clipRect(atrect.x, atrect.y, atrect.width, atrect.height);
      g.drawImage(offi, -xoffset, -yoffset, null);
    }

    public void paint(Graphics g) {
      update(g);
    }

    public void scroll(int xposition, int yposition) {
      int si = parent.scroll_increment();
      xoffset = xposition * si; yoffset = yposition * si;
      repaint();
    } 

    public Dimension getPreferredSize () {
      preferredSize.height = parent.lineheight() * parent.visLines();
      preferredSize.width = parent.pixwidth();
      return preferredSize;
    }
    class sizeListener extends ComponentAdapter {
      public void componentResized(ComponentEvent ce) {
	Rectangle rect = getBounds();
	int maxxval = parent.pixwidth();
	if (xoffset > maxxval)
	  xoffset = maxxval;
	if (xoffset < 0)
	  xoffset = 0;
	parent.hScroll.setValues(xoffset, rect.width, 0, maxxval);
	parent.hScroll.setBlockIncrement(rect.width);
	reVScroll();
	update(getGraphics());
	}
      }

    public void reVScroll () {
      int height = getSize().height;
      int si = parent.scroll_increment();
      int maxyval = parent.pixheight();
      if (yoffset > maxyval)
	yoffset = maxyval;
      if (yoffset < 0)
	yoffset = 0;
      parent.vScroll.setValues(yoffset / si, height / si, 0, maxyval / si);    
      // This Math.max is because X complains if the scrollbar increment is < 1.
      // The right solution is probably to ensure that the window can't be resized
      // smaller than one line + headings.  -sigue
      parent.vScroll.setBlockIncrement(Math.max(1, (height - parent.lineheight()) / si));
      parent.setVisLines(getSize().height / parent.lineheight());
    }
  }

} // end class MultiBox

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -