📄 multibox.java
字号:
package ergo.ui;
// $Id: MultiBox.java,v 1.4 1999/08/13 01:20:09 sigue Exp $
/*
* Copyright (C) 1999 Carl L. Gay and Antranig M. Basman.
* See the file copyright.txt, distributed with this software,
* for further information.
*/
import ergo.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.MemoryImageSource;
import java.util.Hashtable;
import java.util.Vector;
public class MultiBox extends Panel {
// format is l,l,l, and wwww. etc.
private static final int AT_LEFT = 1;
private static final int AT_RIGHT = 2;
private static final int AT_CENTER = 3;
// Stashed parameters
private MultiCallBackable mcb; // You MCB!!!
private String[] Format, Widther, Headings;
private int sortMethod;
// static dimensional quantities
private int columns;
private int[] pixposition;
private int toplinepix;
private int lineheight;
public int columns () { return columns; }
public int toplinepix () { return toplinepix; }
public int lineheight () { return lineheight; }
public int pixwidth () { return pixposition[columns]; }
public int pixheight () { return lineheight*lines(); }
public int pixposition (int column) { return pixposition[column]; }
public int scroll_increment () { return lineheight(); } // An option, sigue :)
private boolean initted = false;
// appearance parameters, access functions+parameters one day....
public Font listFont = new Font("Dialog", Font.PLAIN, 14);
public Color unselectedText = Color.black;
public Color unselectedBackground = Color.white;
public Color selectedBackground = Color.darkGray;
public Color selectedText = Color.white;
public void setColorVec (Color[] colors) {
unselectedText = colors[0];
unselectedBackground = colors[1];
selectedText = colors[2];
selectedBackground = colors[3];
listCanvas.repaint();
headingCanvas.repaint();
}
public void setFont (Font f) {
super.setFont(f);
listFont = f;
calcColumns();
listCanvas.reJig();
headingCanvas.reJig();
invalidate();
}
// semi-static layout parameters
private int GUTTER = 10;
public int gutter () { return GUTTER; }
private int vislines;
public int visLines () { return vislines; }
public void setVisLines (int vl1) { vislines = vl1; }
// internal components
// various reasons these are public - they talk to each other a little....
public Scrollbar hScroll, vScroll;
public MultiListCanvas listCanvas;
public MultiHeadingCanvas headingCanvas;
private Dimension BigDimension;
private BorderLayout layout;
// private Dimension preferredSize=new Dimension();
// the selection - currently only single selection allowed....
private int selectedIndex = -1;
public int getSelectedIndex () { return selectedIndex; }
// the dynamic contents of the box
public int lines () { return lineDatap.size(); }
private Vector lineDatap = new Vector();
private Hashtable reverseLook = new Hashtable(20);
public LineData reverseLook (Object useful) {
return (LineData) reverseLook.get(useful);
}
public LineData lineDataAt (int row) {
return (LineData) lineDatap.elementAt(row);
}
public String fieldAt (int row, int column) {
return lineDataAt(row).fields[column];
}
public String headingAt (int column) {
return Headings[column];
}
public String formatAt (int column) {
return Format[column];
}
// One day, we may have lhand headings too....
// extra parameter may be required......
public MultiBox (MultiCallBackable mcb1, String[] Format1, String[] Widther1, String[] Headings1, int vislines1, int initSortMethod) throws Exception {
mcb = mcb1;
vislines = vislines1;
Format = Format1;
Widther = Widther1;
Headings = Headings1;
sortMethod = initSortMethod;
init();
}
private void calcColumns () {
FontMetrics metrics = getFontMetrics(listFont);
if (metrics == null)
return;
pixposition[0] = GUTTER / 2; // properness
for (int i = 1; i <= columns; ++i) {
int t = pixposition[i - 1]; // surprising hack to work around JIT bug in
// IBM build o114-19971122 JDK!
pixposition[i] = (t + Math.max(metrics.stringWidth(Headings[i - 1]),
metrics.stringWidth(Widther[i - 1]))
+ GUTTER);
}
pixposition[columns] -= GUTTER / 2;
lineheight = metrics.getHeight();
toplinepix = metrics.getLeading() + metrics.getAscent();
}
private boolean init () {
// Font currentFont=getFont();
/* Font savedFont = g.getFont();
Graphics g=getGraphics();
g.setFont(window.SMALLFONT);*/
columns = Format.length;
Debug.asser(Format.length == Widther.length
&& Format.length == Headings.length,
"MultiBox: Mismatch of argument lengths");
pixposition = new int[columns + 1];
calcColumns();
hScroll = new Scrollbar(Scrollbar.HORIZONTAL);
vScroll = new Scrollbar(Scrollbar.VERTICAL);
listCanvas = new MultiListCanvas(this);
listCanvas.addMouseListener( new mouseListener());
// ListCanvas.resize(pixposition[column], VISLINES * lineheight);
headingCanvas = new MultiHeadingCanvas(this);
setLayout(layout = new BorderLayout());
// HeadingCanvas.resize(pixposition[column], lineheight);
add("North", headingCanvas);
add("Center", listCanvas);
add("East", vScroll);
add("South", hScroll);
initted = true;
return initted;
}
// Sort items.
private boolean insertion () {
boolean changed = false;
// System.out.println("Insertion: "+this.sortMethod);
for (int i = 1; i < lineDatap.size(); ++i) {
LineData v = lineDataAt(i);
int j = i;
while (j > 0 && mcb.compare(this.sortMethod,
lineDataAt(j - 1).theUseful,
v.theUseful) > 0) {
changed = true;
lineDatap.setElementAt(lineDataAt(j - 1), j);
j--;
}
lineDatap.setElementAt(v, j);
}
if (changed)
listCanvas.updateInternal();
return changed;
}
public void reSort(int sortMethod1) {
sortMethod = sortMethod1;
// insertion();
// listCanvas.updateInternal();
}
public void insertEntry(Object theUseful, String[] fields, boolean quietness) {
LineData newLD = new LineData(theUseful, fields);
lineDatap.addElement(newLD);
reverseLook.put(theUseful, newLD);
if (!quietness) {
if (!insertion())
listCanvas.updateInternal();
}
listCanvas.reVScroll();
}
public void removeEntry(Object theUseful, boolean quietness) {
LineData oldLD = reverseLook(theUseful);
// if (oldLD==null) {
// System.out.println("Null reverse - from "+((ServerPlayer)theUseful).name);
// }
lineDatap.removeElement(oldLD);
reverseLook.remove(theUseful);
if (!quietness) {
listCanvas.updateInternal();
listCanvas.reVScroll();
}
}
public void updateEntry(Object theUseful, String[] fields) { // assume these
// come singly, else messy
LineData oldLd = reverseLook(theUseful);
for (int i = 0; i < fields.length; ++i) {
oldLd.fields[i] = fields[i];
}
if (!insertion()) {
int i;
for (i = 0; i < lines(); ++i) {
if (lineDataAt(i) == oldLd)
break;
}
listCanvas.updateLine(i);
} // end if list reordered
}
public void refresh () {
insertion();
listCanvas.updateInternal();
listCanvas.reVScroll();
}
private boolean layedout;
public boolean handleEvent (Event e) {
// if (!layedout)
// layout();
if (e.target == hScroll) {
switch(e.id) {
case Event.SCROLL_LINE_UP:
case Event.SCROLL_LINE_DOWN:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_ABSOLUTE:
int offset_x = ((Integer)e.arg).intValue();
listCanvas.scroll(offset_x, 0);
headingCanvas.scroll(offset_x);
break;
}
return true;
}
else if (e.target == vScroll) {
switch(e.id) {
case Event.SCROLL_LINE_UP:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_LINE_DOWN:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_ABSOLUTE:
int offset_y = ((Integer)e.arg).intValue();
listCanvas.scroll(0, offset_y);
break;
}
return true;
} // end if vscroll
return super.handleEvent(e);
} // end handleEvent
class mouseListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
Rectangle listBounds=listCanvas.getBounds();
int yline = (e.getY()/* - listBounds.y*/ + listCanvas.yoffset()) / lineheight;
int xpix = (e.getX() + listCanvas.xoffset());
int i;
for (i = 0; i < columns; ++i) {
if (xpix < pixposition[i]) {
--i;
break;
}
}
if (true /*!e.metaDown()*/) {
if (yline >= lines())
{ yline = -1; }
if (yline != selectedIndex) {
// System.out.println("Old selected "+selectedIndex+", new "+yline);
int oldIndex = selectedIndex;
selectedIndex = yline;
listCanvas.updateLine(oldIndex);
listCanvas.updateLine(selectedIndex);
}
} // end if selection changed...
if (yline < lines() && yline >= 0)
mcb.eventOn(lineDataAt(yline).theUseful, e, i);
}
}
public boolean action (Event e, Object arg) {
return mcb.actionOn(e, arg);
}
// Moved these out of MultiHeadingCanvas to satisfy the compiler.
private static final int EXTRA_HEIGHT = 4; // layout parameters for black bar, in pixels
private static final int BAR_HEIGHT = 2;
private static final int LIP = 3;
private static final int END = 40; // disused
/** MultiHeadingCanvas draws the column headings for a MultiBox.
* It has no particularly interesting features.
**/
class MultiHeadingCanvas extends Canvas {
private MultiBox parent;
private Graphics offg;
private Image offi;
private int xoffset;
private Dimension preferredSize = new Dimension();
private int width, height;
public void scroll(int xposition) {
xoffset = xposition * parent.scroll_increment();
repaint(0, 0, width, height);
}
MultiHeadingCanvas(MultiBox parent1) {
parent = parent1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -