package org.openswing.swing.table.client;
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.table.*;
import java.awt.event.MouseEvent;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Grid UI, redefined to allow cells span.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
*
* <p> This file is part of OpenSwing Framework.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the (LGPL) Lesser General Public
* License as published by the Free Software Foundation;
*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author may be contacted at:
* maurocarniel@tin.it</p>
*
* @author Mauro Carniel
* @version 1.0
*/
public class GridUI extends BasicTableUI {
/** Paint 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();
Point lowerRight = new Point(clip.x + clip.width - 1, clip.y + clip.height - 1);
if (((Grid)table).hasCellSpan()) {
// no cells span defined: it is needed to split visible area in more regions, according to cells span:
int rMin = table.rowAtPoint(upperLeft);
// This should never happen.
if (rMin == -1) {
rMin = 0;
}
int rMax = rMin;
int h = 0;
for(int i=rMin;i<table.getRowCount();i++)
if (h<lowerRight.y) {
h += table.getRowHeight(i);
rMax = i;
}
else
break;
// 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);
// This should never happen.
if (cMin == -1) {
cMin = 0;
}
int cMax = cMin;
int w = 0;
for(int i=cMin;i<table.getColumnCount();i++)
if (w<lowerRight.x) {
w += table.getColumnModel().getColumn(i).getWidth();
cMax = i;
}
else
break;
// 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.
paintGrid(g, rMin, rMax, cMin, cMax);
// Paint the cells.
paintCells(g, rMin, rMax, cMin, cMax);
}
else {
// no cells span defined: it is possible to identify a unique visible area for the whole grid:
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.
paintGrid(g, rMin, rMax, cMin, cMax);
// Paint the cells.
paintCells(g, rMin, rMax, cMin, cMax);
}
}
/*
* 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) {
g.setColor(table.getGridColor());
TableColumnModel cm = table.getColumnModel();
int tableWidth;
int tableHeight;
Rectangle cell = null;
for (int col = cMin; col <= cMax; col++) {
if (table.getShowHorizontalLines()) {
for (int row = rMin; row <= rMax; row++) {
tableWidth = cm.getColumn(col).getWidth();
cell = table.getCellRect(row, col, true);
for (int i=col+1;i<col+((Grid)table).getSpan(row,col).getN2();i++) {
tableWidth += cm.getColumn(i).getWidth();
}
g.drawLine(cell.x, cell.y - 1, cell.x+tableWidth - 1, cell.y - 1);
}
}
if (table.getShowVerticalLines()) {
for (int row = rMin; row <= rMax; row++) {
cell = table.getCellRect(row, col, true);
tableHeight = cell.y+cell.height;
for (int i=col+1;i<col+((Grid)table).getSpan(row,col).getN2();i++) {
cell.x += cm.getColumn(i).getWidth();
}
g.drawLine(cell.x - 1, cell.y, cell.x - 1, tableHeight - 1);
}
}
}
}
private void paintCells(Graphics g, int rMin, int rMax, int cMin, int cMax) {
JTableHeader header = table.getTableHeader();
TableColumn draggedColumn = (header == null) ? null : header.getDraggedColumn();
TableColumnModel cm = table.getColumnModel();
Rectangle cellRect;
TableColumn aColumn;
for(int row = rMin; row <= rMax; row++) {
for(int column = cMin; column <= cMax; column++) {
cellRect = table.getCellRect(row, column, false);
//
aColumn = cm.getColumn(column);
// columnWidth = aColumn.getWidth();
// cellRect.width = columnWidth - columnMargin;
if (aColumn != draggedColumn) {
paintCell(g, cellRect, row, column);
}
// cellRect.x += columnWidth;
}
}
// Paint the dragged column if we are dragging.
if (draggedColumn != null) {
paintDraggedArea(g, rMin, rMax, draggedColumn, header.getDraggedDistance());
}
// 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 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, vacatedColumnRect.y,
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, vacatedColumnRect.y,
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, y1, x1-1, y2);
// Right
g.drawLine(x2, y1, x2, y2);
}
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);
// 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;
if (((Grid)table).isVisible(row,draggedColumnIndex))
g.drawLine(x1, y2, x2, y2);
}
}
}
private void paintCell(Graphics g, Rectangle cellRect, int row, int column) {
if (!((Grid)table).isVisible(row,column)) {
return;
}
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, cellRect.y,
cellRect.width, cellRect.height, true);
}
}
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;
}
}