📄 multicolumn.java
字号:
// MultiColumn// A List box that supports multiple columns.import java.awt.*;import java.util.Vector;public class MultiColumn extends BorderPanel implements CbScrollbarCallback{ MultiColumnCallback callback; // what to call back to String title[]; // column titles boolean adjustable = true; boolean drawlines = true; Color colors[][] = null; boolean enabled = true; int cpos[]; // column x positions float cwidth[]; // proportional column widths Vector list[]; // columns of the list CbScrollbar sb; // scrollbar at the right side int width, height; // size, minus the scrollbar Insets in; // used space around the border int sbwidth; // width of the scrollbar int th; // height of title bar Image bim; // backing image Graphics bg; // backing graphics FontMetrics fnm; // drawing font size int coldrag = -1; // column being resized int sel = -1; // selected row int top = 0; // first row displayed long last; // last mouse click time int rowh = 16; // row height // Create a new list with the given column titles MultiColumn(String t[]) { super(3, new Color(50,50,50), new Color(220,220,220)); title = new String[t.length]; for(int i=0; i<t.length; i++) title[i] = t[i]; list = new Vector[t.length]; for(int i=0; i<t.length; i++) list[i] = new Vector(); cwidth = new float[t.length]; for(int i=0; i<t.length; i++) cwidth[i] = 1.0f/t.length; cpos = new int[t.length+1]; setLayout(null); sb = new CbScrollbar(CbScrollbar.VERTICAL, this); add(sb); } // Create a new list that calls back to the given object on // single or double clicks. MultiColumn(String t[], MultiColumnCallback c) { this(t); callback = c; } // addItem // Add a row to the list void addItem(Object item[]) { for(int i=0; i<title.length; i++) list[i].addElement(item[i]); repaint(); compscroll(); } // addItems // Add several rows to the list void addItems(Object item[][]) { for(int i=0; i<item.length; i++) for(int j=0; j<title.length; j++) list[j].addElement(item[i][j]); repaint(); compscroll(); } // getItem // Returns the contents of a given row Object []getItem(int n) { Object r[] = new Object[title.length]; for(int i=0; i<title.length; i++) r[i] = list[i].elementAt(n); return r; } // selected // Return the selected row int selected() { return sel; } // select // Select some row void select(int s) { sel = s; repaint(); } // deleteItem // Remove one row from the list void deleteItem(int n) { for(int i=0; i<title.length; i++) list[i].removeElementAt(n); if (n == sel) sel = -1; repaint(); compscroll(); } // clear // Remove everything from the list void clear() { for(int i=0; i<title.length; i++) list[i].removeAllElements(); sel = -1; top = 0; repaint(); sb.setValues(0, 1, 0); } // setWidths // Set the proportional widths of each column void setWidths(float w[]) { for(int i=0; i<title.length; i++) cwidth[i] = w[i]; respace(); repaint(); } /**Turns on or off the user's ability to adjust column widths * @param a Can adjust or not? */ void setAdjustable(boolean a) { adjustable = a; } /**Turns on or off the drawing of column lines * @param d Draw lines or not? */ void setDrawLines(boolean d) { drawlines = d; } /**Sets the array of colors used to draw text items. * @param c The color array (in row/column order), or null to * use the default */ void setColors(Color c[][]) { colors = c; repaint(); } public void enable() { enabled = true; sb.enable(); repaint(); } public void disable() { enabled = false; sb.disable(); repaint(); } // reshape // Called when this component gets resized public void reshape(int nx, int ny, int nw, int nh) { if (nw != width+sbwidth || nh != height) { in = insets(); sbwidth = sb.minimumSize().width; width = nw-sbwidth - (in.left + in.right); height = nh - (in.top + in.bottom); sb.reshape(width+in.left, in.top, sbwidth, height); respace(); // Force creation of a new backing image and re-painting bim = null; repaint(); compscroll(); } super.reshape(nx, ny, nw, nh); } // respace // Compute pixel column widths from proportional widths void respace() { cpos[0] = 0; for(int i=0; i<title.length; i++) cpos[i+1] = cpos[i] + (int)(width*cwidth[i]); } // paint // Blit the backing image to the front public void paint(Graphics g) { super.paint(g); if (bim == null) { // This is the first rendering bim = createImage(width, height); bg = bim.getGraphics(); bg.setFont(new Font("timesRoman", Font.PLAIN, 12)); fnm = bg.getFontMetrics(); th = fnm.getHeight() + 4; render(); compscroll(); } g.drawImage(bim, in.left, in.top, this); } // update // Called sometime after repaint() public void update(Graphics g) { if (fnm != null) { render(); paint(g); } } // render // Re-draw the list into the backing image void render() { int fh = fnm.getHeight(), // useful font metrics fd = fnm.getDescent(), fa = fnm.getAscent(); int bot = Math.min(top+rows()-1, list[0].size()-1); // Clear title section and list bg.setColor(Color.lightGray); bg.fillRect(0, 0, width, th); bg.setColor(Color.white); bg.fillRect(0, th, width, height-th); if (enabled) { // Mark the selected row if (sel >= top && sel <= bot) { bg.setColor(Color.lightGray); bg.fillRect(0, th+(sel-top)*rowh, width, rowh); } } // Draw each column for(int i=0; i<title.length; i++) { int x = cpos[i], w = cpos[i+1]-x-1; // Column title bg.setColor(Color.white); bg.drawLine(x, 0, x+w, 0); bg.drawLine(x, 1, x+w-1, 1); bg.drawLine(x, 0, x, th-1); bg.drawLine(x+1, 0, x+1, th-2); bg.setColor(Color.black); bg.drawLine(x, th-1, x+w, th-1); bg.drawLine(x, th-2, x+w-1, th-2); bg.drawLine(x+w, th-1, x+w, 0); bg.drawLine(x+w-1, th-1, x+w-1, 1); int tw = fnm.stringWidth(title[i]); if (tw < w-6) bg.drawString(title[i], x+(w-tw)/2, th-fd-2); // Column items if (drawlines) { bg.setColor(Color.lightGray); bg.drawLine(x+w-1, th, x+w-1, height); bg.setColor(Color.black); bg.drawLine(x+w, th, x+w, height); } for(int j=top; j<=bot; j++) { Object o = list[i].elementAt(j); if (o instanceof String) { // Render string in column String s = (String)o; while(fnm.stringWidth(s) > w-3) s = s.substring(0, s.length()-1); if (!enabled) bg.setColor(Color.lightGray); else if (colors != null) bg.setColor(colors[j][i]); bg.drawString(s, x+1, th+(j+1-top)*rowh-fd); } else if (o instanceof Image) { // Render image in column Image im = (Image)o; bg.drawImage(im, x+1, th+(j-top)*rowh, this); } } } } // mouseDown // Select a list item or a column to drag public boolean mouseDown(Event e, int x, int y) { if (!enabled) { return true; } x -= in.left; y -= in.top; coldrag = -1; if (y < th) { // Click in title bar for(int i=1; i<title.length; i++) if (adjustable && Math.abs(cpos[i] - x) < 3) { // clicked on a column separator coldrag = i; } } else { // Item chosen from list int row = (y-th)/rowh + top; if (row < list[0].size()) { // Double-click? boolean dclick = false; if (e.when-last < 1000 && sel == row) dclick = true; else last = e.when; sel = row; repaint(); if (callback != null) { // Callback the right function if (dclick) callback.doubleClick(this, row); else callback.singleClick(this, row); } else { // Send an event getParent().postEvent( new Event(this, Event.ACTION_EVENT, dclick?"Double":"Single")); } } } return true; } // mouseDrag // If a column is selected, change it's width public boolean mouseDrag(Event e, int x, int y) { if (!enabled) { return true; } x -= in.left; y -= in.top; if (coldrag != -1) { if (x > cpos[coldrag-1]+3 && x < cpos[coldrag+1]-3) { cpos[coldrag] = x; cwidth[coldrag-1] = (cpos[coldrag]-cpos[coldrag-1]) / (float)width; cwidth[coldrag] = (cpos[coldrag+1]-cpos[coldrag]) / (float)width; repaint(); } } return true; } public void moved(CbScrollbar s, int v) { moving(s, v); } public void moving(CbScrollbar s, int v) { top = sb.getValue(); compscroll(); repaint(); } // compscroll // Re-compute the size of the scrollbar private void compscroll() { if (fnm == null) return; // not visible int r = rows(); int c = list[0].size() - r; sb.setValues(top, r==0?1:r, list[0].size()); } // rows // Returns the number of rows visible in the list private int rows() { return Math.min(height/rowh - 1, list[0].size()); } public Dimension minimumSize() { return new Dimension(400, 100); } public Dimension preferredSize() { return minimumSize(); }}// MultiColumnCallback// Objects implementing this interface can be passed to the MultiColumn// class, to have their singleClick() and doubleClick() functions called in// response to single or double click in the list.interface MultiColumnCallback{ // singleClick // Called on a single click on a list item void singleClick(MultiColumn list, int num); // doubleClick // Called upon double-clicking on a list item void doubleClick(MultiColumn list, int num);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -