📄 tableui.java
字号:
* This class should be treated as a "protected" inner class.
* Instantiate it only within subclasses of BasicTableUI.
* <p>As of Java 2 platform v1.3 this class is no longer used.
* Instead <code>JTable</code>
* overrides <code>processKeyBinding</code> to dispatch the event to
* the current <code>TableCellEditor</code>.
*/
public class KeyHandler implements KeyListener
{
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e)
{
KeyStroke keyStroke=KeyStroke.getKeyStroke(e.getKeyChar(),
e.getModifiers());
// We register all actions using ANCESTOR_OF_FOCUSED_COMPONENT
// which means that we might perform the appropriate action
// in the table and then forward it to the editor if the editor
// had focus. Make sure this doesn't happen by checking our
// InputMaps.
InputMap map=table.getInputMap(JComponent.WHEN_FOCUSED);
if(map!=null && map.get(keyStroke)!=null)
{
return;
}
map=table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
if(map!=null && map.get(keyStroke)!=null)
{
return;
}
keyStroke=KeyStroke.getKeyStrokeForEvent(e);
// The AWT seems to generate an unconsumed \r event when
// ENTER (\n) is pressed.
if(e.getKeyChar()=='\r')
{
return;
}
int anchorRow=table.getSelectionModel().getAnchorSelectionIndex();
int anchorColumn=table.getColumnModel().getSelectionModel()
.getAnchorSelectionIndex();
if(anchorRow!=-1 && anchorColumn!=-1 && !table.isEditing())
{
if(!table.editCellAt(anchorRow, anchorColumn))
{
return;
}
}
// Forwarding events this way seems to put the component
// in a state where it believes it has focus. In reality
// the table retains focus - though it is difficult for
// a user to tell, since the caret is visible and flashing.
// Calling table.requestFocus() here, to get the focus back to
// the table, seems to have no effect.
Component editorComp=table.getEditorComponent();
if(table.isEditing() && editorComp!=null)
{
if(editorComp instanceof JComponent)
{
JComponent component=(JComponent)editorComp;
map=component.getInputMap(JComponent.WHEN_FOCUSED);
Object binding=(map!=null) ? map.get(keyStroke) : null;
if(binding==null)
{
map=component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
binding=(map!=null) ? map.get(keyStroke) : null;
}
if(binding!=null)
{
ActionMap am=component.getActionMap();
Action action=(am!=null) ? am.get(binding) : null;
if(action!=null
&& SwingUtilities.notifyAction(action, keyStroke, e,
component,
e.getModifiers()))
{
e.consume();
}
}
}
}
}
}
//
// The Table's focus listener
//
/**
* This inner class is marked "public" due to a compiler bug.
* This class should be treated as a "protected" inner class.
* Instantiate it only within subclasses of BasicTableUI.
*/
public class FocusHandler implements FocusListener
{
private void repaintAnchorCell()
{
int rc=table.getRowCount();
int cc=table.getColumnCount();
int ar=table.getSelectionModel().getAnchorSelectionIndex();
int ac=table.getColumnModel().getSelectionModel()
.getAnchorSelectionIndex();
if(ar<0 || ar>=rc || ac<0 || ac>=cc)
{
return;
}
Rectangle dirtyRect=table.getCellRect(ar, ac, false);
table.repaint(dirtyRect);
}
public void focusGained(FocusEvent e)
{
repaintAnchorCell();
}
public void focusLost(FocusEvent e)
{
repaintAnchorCell();
}
}
//
// The Table's mouse and mouse motion listeners
//
/**
* This inner class is marked "public" due to a compiler bug.
* This class should be treated as a "protected" inner class.
* Instantiate it only within subclasses of BasicTableUI.
*/
public class MouseInputHandler implements MouseInputListener
{
// Component receiving mouse events during editing.
// May not be editorComponent.
private Component dispatchComponent;
private boolean selectedOnPress;
// The Table's mouse listener methods.
public void mouseClicked(MouseEvent e) {}
private void setDispatchComponent(MouseEvent e)
{
Component editorComponent=table.getEditorComponent();
Point p=e.getPoint();
Point p2=SwingUtilities.convertPoint(table, p, editorComponent);
dispatchComponent=SwingUtilities.getDeepestComponentAt(editorComponent,
p2.x, p2.y);
}
private boolean repostEvent(MouseEvent e)
{
// Check for isEditing() in case another event has
// caused the editor to be removed. See bug #4306499.
if(dispatchComponent==null || !table.isEditing())
{
return false;
}
MouseEvent e2=SwingUtilities.convertMouseEvent(table, e,
dispatchComponent);
dispatchComponent.dispatchEvent(e2);
return true;
}
private void setValueIsAdjusting(boolean flag)
{
table.getSelectionModel().setValueIsAdjusting(flag);
table.getColumnModel().getSelectionModel().setValueIsAdjusting(flag);
}
private boolean shouldIgnore(MouseEvent e)
{
return e.isConsumed()
|| (!(SwingUtilities.isLeftMouseButton(e) && table.isEnabled()));
}
public void mousePressed(MouseEvent e)
{
if(e.isConsumed())
{
selectedOnPress=false;
return;
}
selectedOnPress=true;
adjustFocusAndSelection(e);
}
void adjustFocusAndSelection(MouseEvent e)
{
if(shouldIgnore(e))
{
return;
}
Point p=e.getPoint();
int row=table.rowAtPoint(p);
int column=table.columnAtPoint(p);
// The autoscroller can generate drag events outside the Table's range.
if((column==-1) || (row==-1))
{
return;
}
if(table.editCellAt(row, column, e))
{
setDispatchComponent(e);
repostEvent(e);
}
else if(table.isRequestFocusEnabled())
{
table.requestFocus();
}
CellEditor editor=table.getCellEditor();
if(editor==null || editor.shouldSelectCell(e))
{
boolean adjusting=(e.getID()==MouseEvent.MOUSE_PRESSED) ? true : false;
setValueIsAdjusting(adjusting);
table.changeSelection(row, column, e.isControlDown(),
e.isShiftDown());
}
}
public void mouseReleased(MouseEvent e)
{
if(selectedOnPress)
{
if(shouldIgnore(e))
{
return;
}
repostEvent(e);
dispatchComponent=null;
setValueIsAdjusting(false);
}
else
{
adjustFocusAndSelection(e);
}
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
// The Table's mouse motion listener methods.
public void mouseMoved(MouseEvent e) {}
public void mouseDragged(MouseEvent e)
{
if(shouldIgnore(e))
{
return;
}
repostEvent(e);
CellEditor editor=table.getCellEditor();
if(editor==null || editor.shouldSelectCell(e))
{
Point p=e.getPoint();
int row=table.rowAtPoint(p);
int column=table.columnAtPoint(p);
// The autoscroller can generate drag events outside the Table's range.
if((column==-1) || (row==-1))
{
return;
}
table.changeSelection(row, column, false, true);
}
}
}
/**
* Drag gesture recognizer for JTable components
*/
static class TableDragGestureRecognizer extends TonicDragGestureRecognizer
{
/**
* Determines if the following are true:
* <ul>
* <li>the press event is located over a selection
* <li>the dragEnabled property is true
* <li>A TranferHandler is installed
* </ul>
* <p>
* This is implemented to perform the superclass behavior
* followed by a check if the dragEnabled
* property is set and if the location picked is selected.
*/
protected boolean isDragPossible(MouseEvent e)
{
if(super.isDragPossible(e))
{
JTable table=(JTable)this.getComponent(e);
if(table.getDragEnabled())
{
Point p=e.getPoint();
int row=table.rowAtPoint(p);
int column=table.columnAtPoint(p);
if((column!=-1) && (row!=-1)
&& table.isCellSelected(row, column))
{
return true;
}
}
}
return false;
}
}
/**
* A DropTargetListener to extend the default Swing handling of drop operations
* by moving the tree selection to the nearest location to the mouse pointer.
* Also adds autoscroll capability.
*/
static class TableDropTargetListener extends TonicDropTargetListener
{
private int rows[];
private int cols[];
/**
* called to save the state of a component in case it needs to
* be restored because a drop is not performed.
*/
protected void saveComponentState(JComponent comp)
{
JTable table=(JTable)comp;
rows=table.getSelectedRows();
cols=table.getSelectedColumns();
}
/**
* called to restore the state of a component
* because a drop was not performed.
*/
protected void restoreComponentState(JComponent comp)
{
JTable table=(JTable)comp;
table.clearSelection();
for(int i=0; i<rows.length; i++)
{
table.addRowSelectionInterval(rows[i], rows[i]);
}
for(int i=0; i<cols.length; i++)
{
table.addColumnSelectionInterval(cols[i], cols[i]);
}
}
/**
* called to set the insertion location to match the current
* mouse pointer coordinates.
*/
protected void updateInsertionLocation(JComponent comp, Point p)
{
JTable table=(JTable)comp;
int row=table.rowAtPoint(p);
int col=table.columnAtPoint(p);
if(row!=-1)
{
table.setRowSelectionInterval(row, row);
}
if(col!=-1)
{
table.setColumnSelectionInterval(col, col);
}
}
}
static class TableTransferHandler extends TransferHandler
implements UIResource
{
/**
* Create a Transferable to use as the source for a data transfer.
*
* @param c The component holding the data to be transfered. This
* argument is provided to enable sharing of TransferHandlers by
* multiple components.
* @return The representation of the data to be transfered.
*
*/
protected Transferable createTransferable(JComponent c)
{
if(c instanceof JTable)
{
JTable table=(JTable)c;
int rows[];
int cols[];
if(!table.getRowSelectionAllowed()
&& !table.getColumnSelectionAllowed())
{
return null;
}
if(!table.getRowSelectionAllowed())
{
int rowCount=table.getRowCount();
rows=new int[rowCount];
for(int counter=0; counter<rowCount; counter++)
{
rows[counter]=counter;
}
}
else
{
rows=table.getSelectedRows();
}
if(!table.getColumnSelectionAllowed())
{
int colCount=table.getColumnCount();
cols=new int[colCount];
for(int counter=0; counter<colCount; counter++)
{
cols[counter]=counter;
}
}
else
{
cols=table.getSelectedColumns();
}
if(rows==null || cols==null || rows.length==0 || cols.length==0)
{
return null;
}
StringBuffer plainBuf=new StringBuffer();
StringBuffer htmlBuf=new StringBuffer();
htmlBuf.append("<html>\n<body>\n<table>\n");
for(int row=0; row<rows.length; row++)
{
htmlBuf.append("<tr>\n");
for(int col=0; col<cols.length; col++)
{
Object obj=table.getValueAt(rows[row], cols[col]);
String val=((obj==null) ? "" : obj.toString());
plainBuf.append(val+"\t");
htmlBuf.append(" <td>"+val+"</td>\n");
}
// we want a newline at the end of each line and not a tab
plainBuf.deleteCharAt(plainBuf.length()-1).append("\n");
htmlBuf.append("</tr>\n");
}
// remove the last newline
plainBuf.deleteCharAt(plainBuf.length()-1);
htmlBuf.append("</table>\n</body>\n</html>");
return new TonicTransferable(plainBuf.toString(), htmlBuf.toString());
}
return null;
}
public int getSourceActions(JComponent c)
{
return COPY;
}
}
/**
* PropertyChangeListener for the table. Updates the appropriate
* varaible, or TreeState, based on what changes.
*/
private class PropertyChangeHandler implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent event)
{
String changeName=event.getPropertyName();
if(changeName.equals("componentOrientation"))
{
InputMap inputMap=getMyInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
SwingUtilities.replaceUIInputMap(table,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
inputMap);
UIManager.getLookAndFeelDefaults().put("Table.actionMap", null);
ActionMap actionMap=getMyActionMap();
SwingUtilities.replaceUIActionMap(table, actionMap);
JTableHeader header=table.getTableHeader();
if(header!=null)
{
header.setComponentOrientation((ComponentOrientation)event
.getNewValue());
}
}
else if("transferHandler".equals(changeName))
{
DropTarget dropTarget=table.getDropTarget();
if(dropTarget instanceof UIResource)
{
if(defaultDropTargetListener==null)
{
defaultDropTargetListener=new TableDropTargetListener();
}
try
{
dropTarget.addDropTargetListener(defaultDropTargetListener);
}
catch(TooManyListenersException tmle)
{
// should not happen... swing drop target is multicast
}
}
}
}
}
// End of BasicTableUI.PropertyChangeHandler
}
// End of Class BasicTableUI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -