📄 tableui.java
字号:
package com.digitprop.tonic;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.table.*;
/** UI delegate for JTables.
*
* @author Markus Fischer
*
* <p>This software is under the <a href="http://www.gnu.org/copyleft/lesser.html" target="_blank">GNU Lesser General Public License</a>
*/
/*
* ------------------------------------------------------------------------
* Copyright (C) 2004 Markus Fischer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* You can contact the author at:
* Markus Fischer
* www.digitprop.com
* info@digitprop.com
* ------------------------------------------------------------------------
*/
public class TableUI extends BasicTableUI
{
private static final TableDragGestureRecognizer defaultDragRecognizer=new TableDragGestureRecognizer();
private static DropTargetListener defaultDropTargetListener=null;
private static final TransferHandler defaultTransferHandler=new TableTransferHandler();
/** Cell renderer for the associated JTable */
protected CellRendererPane rendererPane;
/** Key listener for the associated JTable */
protected KeyListener keyListener;
/** Foscus listener for the associated JTable */
protected FocusListener focusListener;
/** Mouse listener for the associated JTable */
protected MouseInputListener mouseInputListener;
/** Property change listener for the associated JTable */
private PropertyChangeListener propertyChangeListener;
/** Creates the key listener for handling keyboard navigation in
* the JTable.
*/
protected KeyListener createKeyListener()
{
return null;
}
/** Creates the focus listener for handling keyboard navigation
* in the JTable.
*/
protected FocusListener createFocusListener()
{
return new FocusHandler();
}
/** Creates the mouse listener for the JTable. */
protected MouseInputListener createMouseInputListener()
{
return new MouseInputHandler();
}
/** Creates the property change listener for the JTable. */
private PropertyChangeListener createPropertyChangeListener()
{
return new PropertyChangeHandler();
}
/** Creates and returns the UI delegate for the specified component */
public static ComponentUI createUI(JComponent component)
{
return new TableUI();
}
/** Installs the UI settings for the specified component */
public void installUI(JComponent c)
{
table=(JTable)c;
rendererPane=new CellRendererPane();
table.add(rendererPane);
installDefaults();
installListeners();
installKeyboardActions();
LookAndFeel.installBorder(table, "Table.border");
}
/** Initialize JTable properties, e.g. font, foreground, and background.
* The font, foreground, and background properties are only set if their
* current value is either null or a UIResource, other properties are set
* if the current value is null.
*
* @see #installUI
*/
protected void installDefaults()
{
LookAndFeel.installColorsAndFont(table, "Table.background",
"Table.foreground", "Table.font");
table.setIntercellSpacing(new Dimension(0,0));
Color sbg=table.getSelectionBackground();
if(sbg==null || sbg instanceof UIResource)
{
table.setSelectionBackground(UIManager.getColor("Table.selectionBackground"));
}
Color sfg=table.getSelectionForeground();
if(sfg==null || sfg instanceof UIResource)
{
table.setSelectionForeground(UIManager.getColor("Table.selectionForeground"));
}
Color gridColor=table.getGridColor();
if(gridColor==null || gridColor instanceof UIResource)
{
table.setGridColor(UIManager.getColor("Table.gridColor"));
}
// install the scrollpane border
Container parent=table.getParent(); // should be viewport
if(parent!=null)
{
parent=parent.getParent(); // should be the scrollpane
if(parent!=null && parent instanceof JScrollPane)
{
LookAndFeel.installBorder((JScrollPane)parent,
"Table.scrollPaneBorder");
}
}
TransferHandler th=table.getTransferHandler();
if(th==null || th instanceof UIResource)
{
table.setTransferHandler(defaultTransferHandler);
}
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
}
}
}
/**
* Attaches listeners to the JTable.
*/
protected void installListeners()
{
focusListener=createFocusListener();
keyListener=createKeyListener();
mouseInputListener=createMouseInputListener();
propertyChangeListener=createPropertyChangeListener();
table.addFocusListener(focusListener);
table.addKeyListener(keyListener);
table.addMouseListener(defaultDragRecognizer);
table.addMouseMotionListener(defaultDragRecognizer);
table.addMouseListener(mouseInputListener);
table.addMouseMotionListener(mouseInputListener);
table.addPropertyChangeListener(propertyChangeListener);
}
/**
* Register all keyboard actions on the JTable.
*/
protected void installKeyboardActions()
{
ActionMap map=getMyActionMap();
SwingUtilities.replaceUIActionMap(table, map);
InputMap inputMap=getMyInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
SwingUtilities.replaceUIInputMap(table,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
inputMap);
}
InputMap getMyInputMap(int condition)
{
if(condition==JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
{
InputMap keyMap=(InputMap)UIManager.get("Table.ancestorInputMap");
InputMap rtlKeyMap;
if(table.getComponentOrientation().isLeftToRight()
|| ((rtlKeyMap=(InputMap)UIManager.get("Table.ancestorInputMap.RightToLeft"))==null))
{
return keyMap;
}
else
{
rtlKeyMap.setParent(keyMap);
return rtlKeyMap;
}
}
return null;
}
ActionMap getMyActionMap()
{
ActionMap map=(ActionMap)UIManager.get("Table.actionMap");
if(map==null)
{
map=createMyActionMap();
if(map!=null)
{
UIManager.getLookAndFeelDefaults().put("Table.actionMap", map);
}
}
return map;
}
ActionMap createMyActionMap()
{
ActionMap map=new ActionMapUIResource();
map.put("selectNextColumn",
new NavigationalAction(1, 0, false, false, false));
map.put("selectPreviousColumn",
new NavigationalAction(-1, 0, false, false, false));
map.put("selectNextRow", new NavigationalAction(0, 1, false, false, false));
map.put("selectPreviousRow",
new NavigationalAction(0, -1, false, false, false));
map.put("selectNextColumnExtendSelection",
new NavigationalAction(1, 0, false, true, false));
map.put("selectPreviousColumnExtendSelection",
new NavigationalAction(-1, 0, false, true, false));
map.put("selectNextRowExtendSelection",
new NavigationalAction(0, 1, false, true, false));
map.put("selectPreviousRowExtendSelection",
new NavigationalAction(0, -1, false, true, false));
map.put("scrollUpChangeSelection",
new PagingAction(false, false, true, false));
map.put("scrollDownChangeSelection",
new PagingAction(false, true, true, false));
map.put("selectFirstColumn", new PagingAction(false, false, false, true));
map.put("selectLastColumn", new PagingAction(false, true, false, true));
map.put("scrollUpExtendSelection",
new PagingAction(true, false, true, false));
map.put("scrollDownExtendSelection",
new PagingAction(true, true, true, false));
map.put("selectFirstColumnExtendSelection",
new PagingAction(true, false, false, true));
map.put("selectLastColumnExtendSelection",
new PagingAction(true, true, false, true));
map.put("selectFirstRow", new PagingAction(false, false, true, true));
map.put("selectLastRow", new PagingAction(false, true, true, true));
map.put("selectFirstRowExtendSelection",
new PagingAction(true, false, true, true));
map.put("selectLastRowExtendSelection",
new PagingAction(true, true, true, true));
map.put("selectNextColumnCell",
new NavigationalAction(1, 0, true, false, true));
map.put("selectPreviousColumnCell",
new NavigationalAction(-1, 0, true, false, true));
map.put("selectNextRowCell",
new NavigationalAction(0, 1, true, false, true));
map.put("selectPreviousRowCell",
new NavigationalAction(0, -1, true, false, true));
map.put("selectAll", new SelectAllAction());
map.put("cancel", new CancelEditingAction());
map.put("startEditing", new StartEditingAction());
map.put(TransferHandler.getCutAction().getValue(Action.NAME),
TransferHandler.getCutAction());
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
map.put(TransferHandler.getPasteAction().getValue(Action.NAME),
TransferHandler.getPasteAction());
if(table.getComponentOrientation().isLeftToRight())
{
map.put("scrollLeftChangeSelection",
new PagingAction(false, false, false, false));
map.put("scrollRightChangeSelection",
new PagingAction(false, true, false, false));
map.put("scrollLeftExtendSelection",
new PagingAction(true, false, false, false));
map.put("scrollRightExtendSelection",
new PagingAction(true, true, false, false));
}
else
{
map.put("scrollLeftChangeSelection",
new PagingAction(false, true, false, false));
map.put("scrollRightChangeSelection",
new PagingAction(false, false, false, false));
map.put("scrollLeftExtendSelection",
new PagingAction(true, true, false, false));
map.put("scrollRightExtendSelection",
new PagingAction(true, false, false, false));
}
return map;
}
/** Uninstalls the UI settings for the specified component */
public void uninstallUI(JComponent c)
{
uninstallDefaults();
uninstallListeners();
uninstallKeyboardActions();
table.remove(rendererPane);
rendererPane=null;
table=null;
}
protected void uninstallDefaults()
{
if(table.getTransferHandler() instanceof UIResource)
{
table.setTransferHandler(null);
}
}
protected void uninstallListeners()
{
table.removeFocusListener(focusListener);
table.removeKeyListener(keyListener);
table.removeMouseListener(defaultDragRecognizer);
table.removeMouseMotionListener(defaultDragRecognizer);
table.removeMouseListener(mouseInputListener);
table.removeMouseMotionListener(mouseInputListener);
table.removePropertyChangeListener(propertyChangeListener);
focusListener=null;
keyListener=null;
mouseInputListener=null;
propertyChangeListener=null;
}
protected void uninstallKeyboardActions()
{
SwingUtilities.replaceUIInputMap(table,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
null);
SwingUtilities.replaceUIActionMap(table, null);
}
//
// Size Methods
//
private Dimension createTableSize(long width)
{
int height=0;
int rowCount=table.getRowCount();
if(rowCount>0 && table.getColumnCount()>0)
{
Rectangle r=table.getCellRect(rowCount-1, 0, true);
height=r.y+r.height;
}
// Width is always positive. The call to abs() is a workaround for
// a bug in the 1.1.6 JIT on Windows.
long tmp=Math.abs(width);
if(tmp>Integer.MAX_VALUE)
{
tmp=Integer.MAX_VALUE;
}
return new Dimension((int)tmp, height);
}
/**
* Return the minimum size of the table. The minimum height is the
* row height times the number of rows.
* The minimum width is the sum of the minimum widths of each column.
*/
public Dimension getMinimumSize(JComponent c)
{
long width=0;
Enumeration enumeration=table.getColumnModel().getColumns();
while(enumeration.hasMoreElements())
{
TableColumn aColumn=(TableColumn)enumeration.nextElement();
width=width+aColumn.getMinWidth();
}
Dimension result=createTableSize(width);
result.width+=c.getInsets().left+c.getInsets().right;
result.height+=c.getInsets().top+c.getInsets().bottom;
return result;
}
/**
* Return the preferred size of the table. The preferred height is the
* row height times the number of rows.
* The preferred width is the sum of the preferred widths of each column.
*/
public Dimension getPreferredSize(JComponent c)
{
long width=0;
Enumeration enumeration=table.getColumnModel().getColumns();
while(enumeration.hasMoreElements())
{
TableColumn aColumn=(TableColumn)enumeration.nextElement();
width=width+aColumn.getPreferredWidth();
}
Dimension result=createTableSize(width);
result.width+=c.getInsets().left+c.getInsets().right;
result.height+=c.getInsets().top+c.getInsets().bottom;
return result;
}
/**
* Return the maximum size of the table. The maximum height is the
* row heighttimes the number of rows.
* The maximum width is the sum of the maximum widths of each column.
*/
public Dimension getMaximumSize(JComponent c)
{
long width=0;
Enumeration enumeration=table.getColumnModel().getColumns();
while(enumeration.hasMoreElements())
{
TableColumn aColumn=(TableColumn)enumeration.nextElement();
width=width+aColumn.getMaxWidth();
}
Dimension result=createTableSize(width);
result.width+=c.getInsets().left+c.getInsets().right;
result.height+=c.getInsets().top+c.getInsets().bottom;
return result;
}
//
// Paint methods and support
//
/** Paints a representation of the <code>table</code> instance
* that was set in installUI().
*/
public void paint(Graphics g, JComponent c)
{
if(table.getRowCount()<=0 || table.getColumnCount()<=0)
{
return;
}
Rectangle clip=g.getClipBounds();
Point upperLeft=clip.getLocation();
upperLeft.x+=c.getInsets().left;
upperLeft.y+=c.getInsets().top;
Point lowerRight=new Point(clip.x+clip.width-1, clip.y+clip.height-1);
lowerRight.x+=c.getInsets().left;
lowerRight.y+=c.getInsets().top;
int rMin=table.rowAtPoint(upperLeft);
int rMax=table.rowAtPoint(lowerRight);
// This should never happen.
if(rMin==-1)
{
rMin=0;
}
// If the table does not have enough rows to fill the view we'll get -1.
// Replace this with the index of the last row.
if(rMax==-1)
{
rMax=table.getRowCount()-1;
}
boolean ltr=table.getComponentOrientation().isLeftToRight();
int cMin=table.columnAtPoint(ltr ? upperLeft : lowerRight);
int cMax=table.columnAtPoint(ltr ? lowerRight : upperLeft);
// This should never happen.
if(cMin==-1)
{
cMin=0;
}
// If the table does not have enough columns to fill the view we'll get -1.
// Replace this with the index of the last column.
if(cMax==-1)
{
cMax=table.getColumnCount()-1;
}
// Paint the grid.
boolean drawLastLine=false;
if(c.getParent()!=null && c.getParent() instanceof JViewport)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -