mirror of
https://github.com/webmin/webmin.git
synced 2025-07-29 11:50:54 +00:00
Test checkin of some modules
This commit is contained in:
578
file/MultiColumn.java.bak
Normal file
578
file/MultiColumn.java.bak
Normal file
@ -0,0 +1,578 @@
|
||||
// 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;
|
||||
boolean multiselect = false;
|
||||
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
|
||||
Font font = new Font("timesRoman", Font.PLAIN, 12);
|
||||
FontMetrics fnm; // drawing font size
|
||||
int coldrag = -1; // column being resized
|
||||
int sel = -1; // selected row
|
||||
int sels[] = new int[0]; // all selected rows
|
||||
int top = 0; // first row displayed
|
||||
long last; // last mouse click time
|
||||
int rowh = 16; // row height
|
||||
Event last_event; // last event that triggered callback
|
||||
int sortcol; // Column currently being sorted
|
||||
int sortdir; // Sort direction (0=none, 1=up, 2=down)
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// modifyItem
|
||||
// Changes one row of the table
|
||||
void modifyItem(Object item[], int row)
|
||||
{
|
||||
for(int i=0; i<title.length; i++)
|
||||
list[i].setElementAt(item[i], row);
|
||||
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 most recently selected row
|
||||
int selected()
|
||||
{
|
||||
return sel;
|
||||
}
|
||||
|
||||
// select
|
||||
// Select some row
|
||||
void select(int s)
|
||||
{
|
||||
sel = s;
|
||||
sels = new int[1];
|
||||
sels[0] = s;
|
||||
repaint();
|
||||
}
|
||||
|
||||
// select
|
||||
// Select multiple rows
|
||||
void select(int s[])
|
||||
{
|
||||
if (s.length == 0) {
|
||||
sel = -1;
|
||||
sels = new int[0];
|
||||
}
|
||||
else {
|
||||
sel = s[0];
|
||||
sels = s;
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
// allSelected
|
||||
// Returns all the selected rows
|
||||
int[] allSelected()
|
||||
{
|
||||
return sels;
|
||||
}
|
||||
|
||||
// scrollto
|
||||
// Scroll to make some row visible
|
||||
void scrollto(int s)
|
||||
{
|
||||
int r = rows();
|
||||
if (s < top || s >= top+r) {
|
||||
top = s-1;
|
||||
if (top > list[0].size() - r)
|
||||
top = list[0].size() - r;
|
||||
sb.setValue(top);
|
||||
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) {
|
||||
// De-select deleted file
|
||||
sel = -1;
|
||||
}
|
||||
for(int i=0; i<sels.length; i++) {
|
||||
if (sels[i] == n) {
|
||||
// Remove from selection list
|
||||
int nsels[] = new int[sels.length-1];
|
||||
if (nsels.length > 0) {
|
||||
System.arraycopy(sels, 0, nsels, 0, i);
|
||||
System.arraycopy(sels, i+1, nsels, i,
|
||||
nsels.length-i);
|
||||
sel = nsels[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
compscroll();
|
||||
}
|
||||
|
||||
// clear
|
||||
// Remove everything from the list
|
||||
void clear()
|
||||
{
|
||||
for(int i=0; i<title.length; i++)
|
||||
list[i].removeAllElements();
|
||||
sel = -1;
|
||||
sels = new int[0];
|
||||
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();
|
||||
}
|
||||
|
||||
// Turns on or off multi-row selection with ctrl and shift
|
||||
void setMultiSelect(boolean m)
|
||||
{
|
||||
multiselect = m;
|
||||
}
|
||||
|
||||
// Enables the entire list
|
||||
public void enable()
|
||||
{
|
||||
enabled = true;
|
||||
sb.enable();
|
||||
repaint();
|
||||
}
|
||||
|
||||
// Disables the entire list
|
||||
public void disable()
|
||||
{
|
||||
enabled = false;
|
||||
sb.disable();
|
||||
repaint();
|
||||
}
|
||||
|
||||
// Sets or turns off the sort indication arrow for a column
|
||||
// Direction 0 = None, 1 = Up arrow, 2 = Down arrow
|
||||
public void sortingArrow(int col, int dir)
|
||||
{
|
||||
sortcol = col;
|
||||
sortdir = dir;
|
||||
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(font);
|
||||
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);
|
||||
Color lighterGray = new Color(Color.lightGray.getRed() + 20,
|
||||
Color.lightGray.getGreen() + 20,
|
||||
Color.lightGray.getBlue() + 20);
|
||||
|
||||
if (enabled) {
|
||||
// Mark the selected rows
|
||||
for(int i=0; i<sels.length; i++) {
|
||||
if (sels[i] >= top && sels[i] <= bot) {
|
||||
bg.setColor(sels[i] == sel ? Color.lightGray
|
||||
: lighterGray);
|
||||
bg.fillRect(0, th+(sels[i]-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);
|
||||
|
||||
// Sorting arrow
|
||||
int as = th-8;
|
||||
if (sortcol == i && sortdir == 1) {
|
||||
bg.setColor(Color.white);
|
||||
bg.drawLine(x+4, th-5, x+4+as, th-5);
|
||||
bg.drawLine(x+4+as, th-5, x+4+as/2, th-5-as);
|
||||
bg.setColor(Color.black);
|
||||
bg.drawLine(x+4+as/2, th-5-as, x+4, th-5);
|
||||
}
|
||||
else if (sortcol == i && sortdir == 2) {
|
||||
bg.setColor(Color.white);
|
||||
bg.drawLine(x+4+as/2, th-5, x+4+as, th-5-as);
|
||||
bg.setColor(Color.black);
|
||||
bg.drawLine(x+4, th-5-as, x+4+as, th-5-as);
|
||||
bg.drawLine(x+4, th-5-as, x+4+as/2, th-5);
|
||||
}
|
||||
|
||||
// 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=0; i<title.length; i++) {
|
||||
if (adjustable && i > 0 && Math.abs(cpos[i] - x) < 3) {
|
||||
// clicked on a column separator
|
||||
coldrag = i;
|
||||
}
|
||||
else if (x >= cpos[i] && x < cpos[i+1]) {
|
||||
// clicked in a title
|
||||
callback.headingClicked(this, 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;
|
||||
|
||||
if (e.shiftDown() && multiselect && sel != -1) {
|
||||
// Select all from last selection to this one
|
||||
int zero = sels[0];
|
||||
if (zero < row) {
|
||||
sels = new int[row-zero+1];
|
||||
for(int i=zero; i<=row; i++)
|
||||
sels[i-zero] = i;
|
||||
}
|
||||
else {
|
||||
sels = new int[zero-row+1];
|
||||
for(int i=zero; i>=row; i--)
|
||||
sels[zero-i] = i;
|
||||
}
|
||||
}
|
||||
else if (e.controlDown() && multiselect) {
|
||||
// Add this one to selection
|
||||
int nsels[] = new int[sels.length + 1];
|
||||
System.arraycopy(sels, 0, nsels, 0,sels.length);
|
||||
nsels[sels.length] = row;
|
||||
sels = nsels;
|
||||
}
|
||||
else {
|
||||
// Select one row only, and de-select others
|
||||
sels = new int[1];
|
||||
sels[0] = row;
|
||||
}
|
||||
sel = row;
|
||||
repaint();
|
||||
last_event = e;
|
||||
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);
|
||||
|
||||
// headingClicked
|
||||
// Called when a column heading is clicked on
|
||||
void headingClicked(MultiColumn list, int col);
|
||||
}
|
||||
|
Reference in New Issue
Block a user