/*
TextAreaRenderer.java
This Module encapsulates some more user interactions with a Jtable,
including right click menus to sort and remove columns
Created: 26 January 2006
Module By: James Ratcliff, falazar@arlut.utexas.edu
-----------------------------------------------------------------------
Ganymede Directory Management System
Copyright (C) 1996-2013
The University of Texas at Austin
Ganymede is a registered trademark of The University of Texas at Austin
Contact information
Author Email: ganymede_author@arlut.utexas.edu
Email mailing list: ganymede@arlut.utexas.edu
US Mail:
Computer Science Division
Applied Research Laboratories
The University of Texas at Austin
PO Box 8029, Austin TX 78713-8029
Telephone: (512) 835-3200
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package arlut.csd.JTable;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.util.*;
/*------------------------------------------------------------------------------
class
TextAreaRenderer
------------------------------------------------------------------------------*/
public class TextAreaRenderer extends JTextArea implements TableCellRenderer
{
private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
/**
* map from table to map of rows to map of column heights
*/
private final HashMap<JTable, HashMap<Integer, HashMap<Integer, Integer>>> cellSizes =
new HashMap<JTable, HashMap<Integer, HashMap<Integer, Integer>>>();
/**
* Cached FontMetrics object, used to calculate the necessary width
* for a specific string in the SmartTable's optimizeColumns()
* method.
*/
private FontMetrics metrics = null;
/* -- */
public TextAreaRenderer()
{
setLineWrap(true);
setWrapStyleWord(true);
}
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected,
boolean hasFocus, int row, int column)
{
// set the colours, etc. using the standard for that platform
adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
setForeground(adaptee.getForeground());
setBackground(adaptee.getBackground());
setBorder(adaptee.getBorder());
setFont(adaptee.getFont());
metrics = this.getFontMetrics(adaptee.getFont());
setText(adaptee.getText());
// This line was very important to get it working with JDK1.4
TableColumnModel columnModel = table.getColumnModel();
setSize(columnModel.getColumn(column).getWidth(), 100000);
int height_wanted = (int) getPreferredSize().getHeight();
addSize(table, row, column, height_wanted);
height_wanted = findTotalMaximumRowSize(table, row);
if (height_wanted > 0 && height_wanted != table.getRowHeight(row))
{
table.setRowHeight(row, height_wanted);
}
return this;
}
/**
* Returns the necessary width required to render obj with this
* renderer, given the table's defined font.
*/
public int getUnwrappedWidth(JTable table, Object obj)
{
if (obj == null)
{
return 0;
}
if (metrics == null)
{
metrics = this.getFontMetrics(table.getFont());
}
return metrics.stringWidth(obj.toString());
}
private void addSize(JTable table, int row, int column, int height)
{
HashMap<Integer, HashMap<Integer, Integer>> rows = cellSizes.get(table);
if (rows == null)
{
rows = new HashMap<Integer, HashMap<Integer, Integer>>();
cellSizes.put(table, rows);
}
HashMap<Integer, Integer> rowheights = rows.get(Integer.valueOf(row));
if (rowheights == null)
{
rowheights = new HashMap<Integer, Integer>();
rows.put(Integer.valueOf(row), rowheights);
}
rowheights.put(Integer.valueOf(column), Integer.valueOf(height));
}
/**
* Look through all columns and get the renderer. If it is
* also a TextAreaRenderer, we look at the maximum height in
* its hash table for this row.
*/
private int findTotalMaximumRowSize(JTable table, int row)
{
int maximum_height = 0;
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements())
{
TableColumn tc = (TableColumn) columns.nextElement();
TableCellRenderer cellRenderer = tc.getCellRenderer();
if (cellRenderer instanceof TextAreaRenderer)
{
TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
maximum_height = Math.max(maximum_height, tar.findMaximumRowSize(table, row));
}
}
return maximum_height;
}
private int findMaximumRowSize(JTable table, int row)
{
Map rows = (Map) cellSizes.get(table);
if (rows == null)
{
return 0;
}
Map rowheights = (Map) rows.get(Integer.valueOf(row));
if (rowheights == null)
{
return 0;
}
int maximum_height = 0;
for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry) it.next();
int cellHeight = ((Integer) entry.getValue()).intValue();
maximum_height = Math.max(maximum_height, cellHeight);
}
return maximum_height;
}
}