package tmcsim.simulationmanager.model; import java.awt.Color; import java.awt.Component; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /** * TableCellRender to display a multi-line cell. * * http://www.roseindia.net/javatutorials/JTable_in_JDK.shtml * * @author Dr. Heinz M. Kabutz */ @SuppressWarnings("serial") public class LogEntryCellRenderer extends JTextArea implements TableCellRenderer { /** * DefaultTableCellRenderer for displaying multi line cells */ private final DefaultTableCellRenderer adaptee; /** * map from table to map of rows to map of column heights */ private final Map>> cellSizes; public LogEntryCellRenderer() { adaptee = new DefaultTableCellRenderer(); cellSizes = new HashMap>>(); 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); // FIXES defect where cell text disappears when selected // TODO: Better would be to make table not selectable // http://stackoverflow.com/questions/8291329/set-all-jtable-cells-unselectable if (isSelected) { setForeground(Color.WHITE); setBackground(Color.GRAY); } else { setForeground(adaptee.getForeground()); setBackground(adaptee.getBackground()); } setBorder(adaptee.getBorder()); setFont(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 != table.getRowHeight(row)) { table.setRowHeight(row, height_wanted); } return this; } private void addSize(JTable table, int row, int column, int height) { Map> rows = cellSizes.get(table); if (rows == null) { cellSizes.put(table, rows = new HashMap>()); } Map rowheights = rows.get(new Integer(row)); if (rowheights == null) { rows.put(new Integer(row), rowheights = new HashMap()); } rowheights.put(new Integer(column), new Integer(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 LogEntryCellRenderer) { LogEntryCellRenderer tar = (LogEntryCellRenderer) cellRenderer; maximum_height = Math.max(maximum_height, tar .findMaximumRowSize(table, row)); } } return maximum_height; } private int findMaximumRowSize(JTable table, int row) { Map> rows = cellSizes.get(table); if (rows == null) { return 0; } Map rowheights = rows.get(new Integer(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; } }