📄 tableui.java
字号:
if(c.getHeight()<((JViewport)c.getParent()).getHeight())
drawLastLine=true;
paintGrid(g, rMin, rMax, cMin, cMax, c.getInsets().left, c.getInsets().top, drawLastLine);
// Paint the cells.
paintCells(g, rMin, rMax, cMin, cMax, c.getInsets().left, c.getInsets().top);
}
/*
* Paints the grid lines within <I>aRect</I>, using the grid
* color set with <I>setGridColor</I>. Paints vertical lines
* if <code>getShowVerticalLines()</code> returns true and paints
* horizontal lines if <code>getShowHorizontalLines()</code>
* returns true.
*/
private void paintGrid(Graphics g, int rMin, int rMax, int cMin, int cMax, int dx, int dy, boolean drawLastLine)
{
g.setColor(table.getGridColor());
Rectangle minCell=table.getCellRect(rMin, cMin, true);
Rectangle maxCell=table.getCellRect(rMax, cMax, true);
Rectangle damagedArea=minCell.union(maxCell);
if(table.getShowHorizontalLines())
{
int tableWidth=damagedArea.x+damagedArea.width;
int y=damagedArea.y;
for(int row=rMin; row<=rMax; row++)
{
y+=table.getRowHeight(row);
if(row+1<table.getRowCount())
g.drawLine(damagedArea.x+dx, y-1+dy, tableWidth-1+dx, y-1+dy);
}
if(drawLastLine)
{
g.drawLine(damagedArea.x+dx, y-1+dy, tableWidth-1+dx, y-1+dy);
}
}
if(table.getShowVerticalLines())
{
TableColumnModel cm=table.getColumnModel();
int tableHeight=damagedArea.y+damagedArea.height;
int x;
if(table.getComponentOrientation().isLeftToRight())
{
x=damagedArea.x;
for(int column=cMin; column<=cMax; column++)
{
int w=cm.getColumn(column).getWidth();
x+=w;
if(column+1<table.getColumnCount())
g.drawLine(x-1+dx, 0+dy, x-1+dx, tableHeight+dy);
}
}
else
{
x=damagedArea.x+damagedArea.width;
for(int column=cMin; column<cMax; column++)
{
int w=cm.getColumn(column).getWidth();
x-=w;
g.drawLine(x-1+dx, dy, x-1+dx, tableHeight+dy);
}
x-=cm.getColumn(cMax).getWidth();
g.drawLine(x+dx, dy, x+dx, tableHeight+dy);
}
}
}
private int viewIndexForColumn(TableColumn aColumn)
{
TableColumnModel cm=table.getColumnModel();
for(int column=0; column<cm.getColumnCount(); column++)
{
if(cm.getColumn(column)==aColumn)
{
return column;
}
}
return -1;
}
private void paintCells(Graphics g, int rMin, int rMax, int cMin, int cMax, int dx, int dy)
{
JTableHeader header=table.getTableHeader();
TableColumn draggedColumn=(header==null) ? null
: header.getDraggedColumn();
TableColumnModel cm=table.getColumnModel();
int columnMargin=cm.getColumnMargin();
Rectangle cellRect;
TableColumn aColumn;
int columnWidth;
if(table.getComponentOrientation().isLeftToRight())
{
for(int row=rMin; row<=rMax; row++)
{
cellRect=table.getCellRect(row, cMin, false);
for(int column=cMin; column<=cMax; column++)
{
aColumn=cm.getColumn(column);
columnWidth=aColumn.getWidth();
cellRect.width=columnWidth-columnMargin;
if(aColumn!=draggedColumn)
{
paintCell(g, cellRect, row, column, dx, dy);
}
cellRect.x+=columnWidth;
}
}
}
else
{
for(int row=rMin; row<=rMax; row++)
{
cellRect=table.getCellRect(row, cMin, false);
aColumn=cm.getColumn(cMin);
if(aColumn!=draggedColumn)
{
columnWidth=aColumn.getWidth();
cellRect.width=columnWidth-columnMargin;
paintCell(g, cellRect, row, cMin, dx, dy);
}
for(int column=cMin+1; column<=cMax; column++)
{
aColumn=cm.getColumn(column);
columnWidth=aColumn.getWidth();
cellRect.width=columnWidth-columnMargin;
cellRect.x-=columnWidth;
if(aColumn!=draggedColumn)
{
paintCell(g, cellRect, row, column, dx, dy);
}
}
}
}
// Paint the dragged column if we are dragging.
if(draggedColumn!=null)
{
paintDraggedArea(g, rMin, rMax, draggedColumn,
header.getDraggedDistance(), dx, dy);
}
// Remove any renderers that may be left in the rendererPane.
rendererPane.removeAll();
}
private void paintDraggedArea(Graphics g, int rMin, int rMax,
TableColumn draggedColumn, int distance, int dx, int dy)
{
int draggedColumnIndex=viewIndexForColumn(draggedColumn);
Rectangle minCell=table.getCellRect(rMin, draggedColumnIndex, true);
Rectangle maxCell=table.getCellRect(rMax, draggedColumnIndex, true);
Rectangle vacatedColumnRect=minCell.union(maxCell);
// Paint a gray well in place of the moving column.
g.setColor(table.getParent().getBackground());
g.fillRect(vacatedColumnRect.x+dx, vacatedColumnRect.y+dy,
vacatedColumnRect.width, vacatedColumnRect.height);
// Move to the where the cell has been dragged.
vacatedColumnRect.x+=distance;
// Fill the background.
g.setColor(table.getBackground());
g.fillRect(vacatedColumnRect.x+dx, vacatedColumnRect.y+dy,
vacatedColumnRect.width, vacatedColumnRect.height);
// Paint the vertical grid lines if necessary.
if(table.getShowVerticalLines())
{
g.setColor(table.getGridColor());
int x1=vacatedColumnRect.x;
int y1=vacatedColumnRect.y;
int x2=x1+vacatedColumnRect.width-1;
int y2=y1+vacatedColumnRect.height-1;
// Left
g.drawLine(x1-1+dx, y1+dy, x1-1+dx, y2+dy);
// Right
g.drawLine(x2+dx, y1+dy, x2+dx, y2+dy);
}
for(int row=rMin; row<=rMax; row++)
{
// Render the cell value
Rectangle r=table.getCellRect(row, draggedColumnIndex, false);
r.x+=distance;
paintCell(g, r, row, draggedColumnIndex, dx, dy);
// Paint the (lower) horizontal grid line if necessary.
if(table.getShowHorizontalLines())
{
g.setColor(table.getGridColor());
Rectangle rcr=table.getCellRect(row, draggedColumnIndex, true);
rcr.x+=distance;
int x1=rcr.x;
int y1=rcr.y;
int x2=x1+rcr.width-1;
int y2=y1+rcr.height-1;
g.drawLine(x1+dx, y2+dy, x2+dx, y2+dy);
}
}
}
private void paintCell(Graphics g, Rectangle cellRect, int row, int column, int dx, int dy)
{
if(table.isEditing() && table.getEditingRow()==row
&& table.getEditingColumn()==column)
{
Component component=table.getEditorComponent();
component.setBounds(cellRect);
component.validate();
}
else
{
TableCellRenderer renderer=table.getCellRenderer(row, column);
Component component=table.prepareRenderer(renderer, row, column);
rendererPane.paintComponent(g, component, table, cellRect.x+dx,
cellRect.y+dy, cellRect.width-1,
cellRect.height-1, true);
}
}
//
// Helper class for keyboard actions
//
private static class NavigationalAction extends AbstractAction
{
protected int dx;
protected int dy;
protected boolean toggle;
protected boolean extend;
protected boolean inSelection;
protected int anchorRow;
protected int anchorColumn;
protected int leadRow;
protected int leadColumn;
protected NavigationalAction(int dx, int dy, boolean toggle,
boolean extend, boolean inSelection)
{
this.dx=dx;
this.dy=dy;
this.toggle=toggle;
this.extend=extend;
this.inSelection=inSelection;
}
private int clipToRange(int i, int a, int b)
{
return Math.min(Math.max(i, a), b-1);
}
private void moveWithinTableRange(JTable table, int dx, int dy,
boolean changeLead)
{
if(changeLead)
{
leadRow=clipToRange(leadRow+dy, 0, table.getRowCount());
leadColumn=clipToRange(leadColumn+dx, 0, table.getColumnCount());
}
else
{
anchorRow=clipToRange(anchorRow+dy, 0, table.getRowCount());
anchorColumn=clipToRange(anchorColumn+dx, 0, table.getColumnCount());
}
}
private int selectionSpan(ListSelectionModel sm)
{
return sm.getMaxSelectionIndex()-sm.getMinSelectionIndex()+1;
}
private int compare(int i, ListSelectionModel sm)
{
return compare(i, sm.getMinSelectionIndex(),
sm.getMaxSelectionIndex()+1);
}
private int compare(int i, int a, int b)
{
return (i<a) ? -1 : (i>=b) ? 1 : 0;
}
private boolean moveWithinSelectedRange(JTable table, int dx, int dy,
boolean ignoreCarry)
{
ListSelectionModel rsm=table.getSelectionModel();
ListSelectionModel csm=table.getColumnModel().getSelectionModel();
int newAnchorRow=anchorRow+dy;
int newAnchorColumn=anchorColumn+dx;
int rowSgn;
int colSgn;
int rowCount=selectionSpan(rsm);
int columnCount=selectionSpan(csm);
boolean canStayInSelection=(rowCount*columnCount>1);
if(canStayInSelection)
{
rowSgn=compare(newAnchorRow, rsm);
colSgn=compare(newAnchorColumn, csm);
}
else
{
// If there is only one selected cell, there is no point
// in trying to stay within the selected area. Move outside
// the selection, wrapping at the table boundaries.
rowCount=table.getRowCount();
columnCount=table.getColumnCount();
rowSgn=compare(newAnchorRow, 0, rowCount);
colSgn=compare(newAnchorColumn, 0, columnCount);
}
anchorRow=newAnchorRow-rowCount*rowSgn;
anchorColumn=newAnchorColumn-columnCount*colSgn;
if(!ignoreCarry)
{
return moveWithinSelectedRange(table, rowSgn, colSgn, true);
}
return canStayInSelection;
}
public void actionPerformed(ActionEvent e)
{
JTable table=(JTable)e.getSource();
ListSelectionModel rsm=table.getSelectionModel();
anchorRow=rsm.getAnchorSelectionIndex();
leadRow=rsm.getLeadSelectionIndex();
ListSelectionModel csm=table.getColumnModel().getSelectionModel();
anchorColumn=csm.getAnchorSelectionIndex();
leadColumn=csm.getLeadSelectionIndex();
int oldAnchorRow=anchorRow;
int oldAnchorColumn=anchorColumn;
if(table.isEditing() && !table.getCellEditor().stopCellEditing())
{
return;
}
// Unfortunately, this strategy introduces bugs because
// of the asynchronous nature of requestFocus() call below.
// Introducing a delay with invokeLater() makes this work
// in the typical case though race conditions then allow
// focus to disappear altogether. The right solution appears
// to be to fix requestFocus() so that it queues a request
// for the focus regardless of who owns the focus at the
// time the call to requestFocus() is made. The optimisation
// to ignore the call to requestFocus() when the component
// already has focus may ligitimately be made as the
// request focus event is dequeued, not before.
// boolean wasEditingWithFocus = table.isEditing() && table.getEditorComponent().isFocusOwner();
if(!inSelection)
{
moveWithinTableRange(table, dx, dy, extend);
if(!extend)
{
table.changeSelection(anchorRow, anchorColumn, false, extend);
}
else
{
table.changeSelection(leadRow, leadColumn, false, extend);
}
}
else
{
if(moveWithinSelectedRange(table, dx, dy, false))
{
table.changeSelection(anchorRow, anchorColumn, true, true);
}
else
{
table.changeSelection(anchorRow, anchorColumn, false, false);
}
}
/*
if (wasEditingWithFocus) {
table.editCellAt(anchorRow, anchorColumn);
final Component editorComp = table.getEditorComponent();
if (editorComp != null) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
editorComp.requestFocus();
}
});
}
}
*/
}
}
private static class PagingAction extends NavigationalAction
{
private boolean forwards;
private boolean vertically;
private boolean toLimit;
private PagingAction(boolean extend, boolean forwards,
boolean vertically, boolean toLimit)
{
super(0, 0, false, extend, false);
this.forwards=forwards;
this.vertically=vertically;
this.toLimit=toLimit;
}
public void actionPerformed(ActionEvent e)
{
JTable table=(JTable)e.getSource();
if(toLimit)
{
if(vertically)
{
int rowCount=table.getRowCount();
this.dx=0;
this.dy=forwards ? rowCount : -rowCount;
}
else
{
int colCount=table.getColumnCount();
this.dx=forwards ? colCount : -colCount;
this.dy=0;
}
}
else
{
if(!(table.getParent().getParent() instanceof JScrollPane))
{
return;
}
Dimension delta=table.getParent().getSize();
ListSelectionModel sm=(vertically) ? table.getSelectionModel()
: table.getColumnModel()
.getSelectionModel();
int start=(extend) ? sm.getLeadSelectionIndex()
: sm.getAnchorSelectionIndex();
if(vertically)
{
Rectangle r=table.getCellRect(start, 0, true);
r.y+=forwards ? delta.height : -delta.height;
this.dx=0;
int newRow=table.rowAtPoint(r.getLocation());
if(newRow==-1 && forwards)
{
newRow=table.getRowCount();
}
this.dy=newRow-start;
}
else
{
Rectangle r=table.getCellRect(0, start, true);
r.x+=forwards ? delta.width : -delta.width;
int newColumn=table.columnAtPoint(r.getLocation());
if(newColumn==-1 && forwards)
{
newColumn=table.getColumnCount();
}
this.dx=newColumn-start;
this.dy=0;
}
}
super.actionPerformed(e);
}
}
/**
* Action to invoke <code>selectAll</code> on the table.
*/
private static class SelectAllAction extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
JTable table=(JTable)e.getSource();
table.selectAll();
}
}
/**
* Action to invoke <code>removeEditor</code> on the table.
*/
private static class CancelEditingAction extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
JTable table=(JTable)e.getSource();
table.removeEditor();
}
}
/**
* Action to start editing, and pass focus to the editor.
*/
private static class StartEditingAction extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
JTable table=(JTable)e.getSource();
if(!table.hasFocus())
{
CellEditor cellEditor=table.getCellEditor();
if(cellEditor!=null && !cellEditor.stopCellEditing())
{
return;
}
table.requestFocus();
return;
}
ListSelectionModel rsm=table.getSelectionModel();
int anchorRow=rsm.getAnchorSelectionIndex();
ListSelectionModel csm=table.getColumnModel().getSelectionModel();
int anchorColumn=csm.getAnchorSelectionIndex();
table.editCellAt(anchorRow, anchorColumn);
Component editorComp=table.getEditorComponent();
if(editorComp!=null)
{
editorComp.requestFocus();
}
}
}
//
// The Table's Key listener
//
/**
* This inner class is marked "public" due to a compiler bug.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -