/** * $RCSfile: ,v $ * $Revision: $ * $Date: $ * * Copyright (C) 2004-2011 Jive Software. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.spark.component; import org.jivesoftware.spark.util.GraphicUtils; import org.jdesktop.swingx.JXTable; import javax.swing.BorderFactory; import javax.swing.DefaultCellEditor; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.ListSelectionModel; import javax.swing.border.Border; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.List; import java.util.Map; /** * <code>Table</code> class can be used to maintain quality look and feel * throughout the product. This is mainly from the rendering capabilities. * * @version 1.0, 03/12/14 */ public abstract class Table extends JXTable { private static final long serialVersionUID = -6511813002260596088L; private Table.JiveTableModel tableModel; /** * Define the color of row and column selections. */ public static final Color SELECTION_COLOR = new Color(166, 202, 240); /** * Define the color used in the tooltips. */ public static final Color TOOLTIP_COLOR = new Color(166, 202, 240); private final Map<Integer,Object> objectMap = new HashMap<Integer,Object>(); /** * Empty Constructor. */ protected Table() { } public String getToolTipText(MouseEvent e) { int r = rowAtPoint(e.getPoint()); int c = columnAtPoint(e.getPoint()); Object value; try { value = getValueAt(r, c); } catch (Exception e1) { // If we encounter a row that should not actually exist and therefore // has a null value. Just return an empty string for the tooltip. return ""; } String tooltipValue = null; if (value instanceof JLabel) { tooltipValue = ((JLabel)value).getToolTipText(); } if (value instanceof JLabel && tooltipValue == null) { tooltipValue = ((JLabel)value).getText(); } else if (value != null && tooltipValue == null) { tooltipValue = value.toString(); } else if (tooltipValue == null) { tooltipValue = ""; } return GraphicUtils.createToolTip(tooltipValue); } // Handle image rendering correctly public TableCellRenderer getCellRenderer(int row, int column) { Object o = getValueAt(row, column); if (o != null) { if (o instanceof JLabel) { return new JLabelRenderer(false); } } return super.getCellRenderer(row, column); } /** * Creates a table using the specified table headers. * * @param headers the table headers to use. */ protected Table(String[] headers) { tableModel = new Table.JiveTableModel(headers, 0, false); setModel(tableModel); // Handle JDK 1.5 bug with preferred size on table headers. JTableHeader header = getTableHeader(); Dimension dim = header.getPreferredSize(); dim.height = 20; header.setPreferredSize(dim); getTableHeader().setReorderingAllowed(false); setGridColor(Color.white); setRowHeight(20); getColumnModel().setColumnMargin(0); setSelectionBackground(SELECTION_COLOR); setSelectionForeground(Color.black); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); this.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { if (e.getKeyChar() == KeyEvent.VK_ENTER) { e.consume(); enterPressed(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }); } public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) { Component c = super.prepareRenderer(renderer, rowIndex, vColIndex); if (rowIndex % 2 == 0 && !isCellSelected(rowIndex, vColIndex)) { c.setBackground(getBackground()); } else if (isCellSelected(rowIndex, vColIndex)) { c.setBackground(SELECTION_COLOR); } else { // If not shaded, match the table's background c.setBackground(getBackground()); //c.setBackground(new Color(217, 232, 250)); } return c; } /** * Adds a list to the table model. * * @param list the list to add to the model. */ public void add(List<Object> list) { for (Object aList : list) { Object[] newRow = (Object[]) aList; tableModel.addRow(newRow); } } /** * Get the object array of a row. * * @return the object array of a row. */ public Object[] getSelectedRowObject() { return getRowObject(getSelectedRow()); } /** * Returns the object[] of a row. * * @param selectedRow the row to retrieve. * @return the object[] of a row. */ public Object[] getRowObject(int selectedRow) { if (selectedRow < 0) { return null; } int columnCount = getColumnCount(); Object[] obj = new Object[columnCount]; for (int j = 0; j < columnCount; j++) { Object objs = tableModel.getValueAt(selectedRow, j); obj[j] = objs; } return obj; } /** * Removes all columns and rows from table. */ public void clearTable() { int rowCount = getRowCount(); for (int i = 0; i < rowCount; i++) { getTableModel().removeRow(0); } } /** * The internal Table Model. */ public static class JiveTableModel extends DefaultTableModel { private static final long serialVersionUID = 2256144012470569949L; private boolean isEditable; /** * Use the JiveTableModel in order to better handle the table. This allows * for consistency throughout the product. * * @param columnNames - String array of columnNames * @param numRows - initial number of rows * @param isEditable - true if the cells are editable, false otherwise. */ public JiveTableModel(Object[] columnNames, int numRows, boolean isEditable) { super(columnNames, numRows); this.isEditable = isEditable; } /** * Returns true if cell is editable. * * @param row the row to check. * @param column the column to check. * @return true if the cell is editable. */ public boolean isCellEditable(int row, int column) { return isEditable; } } /** * A swing renderer used to display labels within a table. */ public class JLabelRenderer extends JLabel implements TableCellRenderer { private static final long serialVersionUID = 4433780600297455731L; Border unselectedBorder; Border selectedBorder; boolean isBordered = true; /** * JLabelConstructor to build ui. * * @param isBordered true if the border should be shown. */ public JLabelRenderer(boolean isBordered) { setOpaque(true); this.isBordered = isBordered; } public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { final String text = ((JLabel)color).getText(); if (text != null) { setText(" " + text); } final Icon icon = ((JLabel)color).getIcon(); setIcon(icon); if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(Color.black); setBackground(Color.white); if (row % 2 == 0) { //setBackground( new Color( 156, 207, 255 ) ); } } if (isBordered) { if (isSelected) { if (selectedBorder == null) { selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getSelectionBackground()); } setBorder(selectedBorder); } else { if (unselectedBorder == null) { unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getBackground()); } setBorder(unselectedBorder); } } return this; } } /** * A swing renderer to dispaly Textareas within a table. */ public class TextAreaCellRenderer extends JTextArea implements TableCellRenderer { private static final long serialVersionUID = -8533968851464831361L; /** * Create new renderer with font. * * @param font the font to use in the renderer. */ public TextAreaCellRenderer(Font font) { setLineWrap(true); setWrapStyleWord(true); setFont(font); } public Component getTableCellRendererComponent(JTable jTable, Object obj, boolean isSelected, boolean hasFocus, int row, int column) { // set color & border here setText(obj == null ? "" : obj.toString()); setSize(jTable.getColumnModel().getColumn(column).getWidth(), getPreferredSize().height); if (jTable.getRowHeight(row) != getPreferredSize().height) { jTable.setRowHeight(row, getPreferredSize().height); } return this; } } /** * A swing renderer used to display Buttons within a table. */ public class JButtonRenderer extends JButton implements TableCellRenderer { private static final long serialVersionUID = 1268514163461994738L; Border unselectedBorder; Border selectedBorder; boolean isBordered = true; /** * Empty Constructor. */ public JButtonRenderer() { } public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { final String text = ((JButton)color).getText(); setText(text); final Icon icon = ((JButton)color).getIcon(); setIcon(icon); if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(Color.black); setBackground(Color.white); if (row % 2 == 0) { //setBackground( new Color( 156, 207, 255 ) ); } } if (isBordered) { if (isSelected) { if (selectedBorder == null) { selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getSelectionBackground()); } setBorder(selectedBorder); } else { if (unselectedBorder == null) { unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getBackground()); } setBorder(unselectedBorder); } } return this; } } public class ComboBoxRenderer extends JComboBox implements TableCellRenderer { private static final long serialVersionUID = -545496178928790522L; public ComboBoxRenderer() { } public ComboBoxRenderer(String[] items) { super(items); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); super.setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } // Select the current value setSelectedItem(value); return this; } } public class MyComboBoxEditor extends DefaultCellEditor { private static final long serialVersionUID = 6097118754932234992L; public MyComboBoxEditor(String[] items) { super(new JComboBox(items)); } } /** * Returns the table model. * * @return the table model. */ public Table.JiveTableModel getTableModel() { return tableModel; } /** * Clears all objects from map. */ public void clearObjectMap() { objectMap.clear(); } /** * Associate an object with a row. * * @param row - the current row * @param object - the object to associate with the row. */ public void addObject(int row, Object object) { objectMap.put(row, object); } /** * Returns the associated row object. * * @param row - the row associated with the object. * @return The object associated with the row. */ public Object getObject(int row) { return objectMap.get(row); } /** * Override to handle when enter is pressed. */ public void enterPressed() { } }