📄 tableheaderui.java
字号:
package com.digitprop.tonic;
import java.awt.*;
import java.awt.event.*;
import java.util.Enumeration;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.table.*;
/** UI delegate for TableHeaders.
*
* @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 TableHeaderUI extends BasicTableHeaderUI
{
/** Cursor for resizing columns */
private static Cursor resizeCursor=Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
/** The JTableHeader that is delegating the painting to this UI. */
protected JTableHeader header;
/** Renderer pane for table headers */
protected CellRendererPane rendererPane;
/** Listeners that are attached to the JTable */
protected MouseInputListener mouseInputListener;
/** Creates the mouse listener for the JTable. */
protected MouseInputListener createMouseInputListener()
{
return new MouseInputHandler();
}
/** Creates and returns the UI delegate for the specified component */
public static ComponentUI createUI(JComponent component)
{
return new TableHeaderUI();
}
/** Installs the UI settings for the specified component */
public void installUI(JComponent c)
{
header=(JTableHeader)c;
rendererPane=new CellRendererPane();
header.add(rendererPane);
installDefaults();
installListeners();
installKeyboardActions();
}
/**
* Initialize JTableHeader 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(header, "TableHeader.background",
"TableHeader.foreground",
"TableHeader.font");
}
/**
* Attaches listeners to the JTableHeader.
*/
protected void installListeners()
{
mouseInputListener=createMouseInputListener();
header.addMouseListener(mouseInputListener);
header.addMouseMotionListener(mouseInputListener);
}
/**
* Register all keyboard actions on the JTableHeader.
*/
protected void installKeyboardActions() {}
/** Installs the UI settings for the specified component */
public void uninstallUI(JComponent c)
{
uninstallDefaults();
uninstallListeners();
uninstallKeyboardActions();
header.remove(rendererPane);
rendererPane=null;
header=null;
}
protected void uninstallDefaults() {}
protected void uninstallListeners()
{
header.removeMouseListener(mouseInputListener);
header.removeMouseMotionListener(mouseInputListener);
mouseInputListener=null;
}
protected void uninstallKeyboardActions() {}
/** Paints the specified component */
public void paint(Graphics g, JComponent c)
{
if(header.getColumnModel().getColumnCount()<=0)
{
return;
}
boolean ltr=header.getComponentOrientation().isLeftToRight();
Rectangle clip=g.getClipBounds();
Point left=clip.getLocation();
Point right=new Point(clip.x+clip.width-1, clip.y);
TableColumnModel cm=header.getColumnModel();
int cMin=header.columnAtPoint(ltr ? left : right);
int cMax=header.columnAtPoint(ltr ? right : left);
// 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=cm.getColumnCount()-1;
}
TableColumn draggedColumn=header.getDraggedColumn();
int columnWidth;
int columnMargin=cm.getColumnMargin();
Rectangle cellRect=header.getHeaderRect(cMin);
TableColumn aColumn;
if(ltr)
{
for(int column=cMin; column<=cMax; column++)
{
aColumn=cm.getColumn(column);
columnWidth=aColumn.getWidth();
cellRect.width=columnWidth-columnMargin;
if(aColumn!=draggedColumn)
{
paintCell(g, cellRect, column, column+1==header.getColumnModel().getColumnCount());
}
cellRect.x+=columnWidth;
}
}
else
{
aColumn=cm.getColumn(cMin);
if(aColumn!=draggedColumn)
{
columnWidth=aColumn.getWidth();
cellRect.width=columnWidth-columnMargin;
cellRect.x+=columnMargin;
paintCell(g, cellRect, cMin, false);
}
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, column, false);
}
}
}
// Paint the dragged column if we are dragging.
if(draggedColumn!=null)
{
int draggedColumnIndex=viewIndexForColumn(draggedColumn);
Rectangle draggedCellRect=header.getHeaderRect(draggedColumnIndex);
// Draw a gray well in place of the moving column.
g.setColor(header.getParent().getBackground());
g.fillRect(draggedCellRect.x, draggedCellRect.y,
draggedCellRect.width, draggedCellRect.height);
draggedCellRect.x+=header.getDraggedDistance();
// Fill the background.
g.setColor(header.getBackground());
g.fillRect(draggedCellRect.x, draggedCellRect.y,
draggedCellRect.width, draggedCellRect.height);
paintCell(g, draggedCellRect, draggedColumnIndex, false);
}
// Remove all components in the rendererPane.
rendererPane.removeAll();
}
private Component getHeaderRenderer(int columnIndex)
{
TableColumn aColumn=header.getColumnModel().getColumn(columnIndex);
TableCellRenderer renderer=aColumn.getHeaderRenderer();
if(renderer==null)
{
renderer=header.getDefaultRenderer();
}
return renderer.getTableCellRendererComponent(header.getTable(),
aColumn.getHeaderValue(),
false, false, -1,
columnIndex);
}
private void paintCell(Graphics g, Rectangle cellRect, int columnIndex, boolean isLastCell)
{
Component component=getHeaderRenderer(columnIndex);
rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
cellRect.width+(isLastCell ? 1 : 0), cellRect.height, true);
}
private int viewIndexForColumn(TableColumn aColumn)
{
TableColumnModel cm=header.getColumnModel();
for(int column=0; column<cm.getColumnCount(); column++)
{
if(cm.getColumn(column)==aColumn)
{
return column;
}
}
return -1;
}
//
// Size Methods
//
private int getHeaderHeight()
{
int height=0;
boolean accomodatedDefault=false;
TableColumnModel columnModel=header.getColumnModel();
for(int column=0; column<columnModel.getColumnCount(); column++)
{
TableColumn aColumn=columnModel.getColumn(column);
// Configuring the header renderer to calculate its preferred size is expensive.
// Optimise this by assuming the default renderer always has the same height.
if(aColumn.getHeaderRenderer()!=null || !accomodatedDefault)
{
Component comp=getHeaderRenderer(column);
int rendererHeight=comp.getPreferredSize().height;
height=Math.max(height, rendererHeight);
// If the header value is empty (== "") in the
// first column (and this column is set up
// to use the default renderer) we will
// return zero from this routine and the header
// will disappear altogether. Avoiding the calculation
// of the preferred size is such a performance win for
// most applications that we will continue to
// use this cheaper calculation, handling these
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -