You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
8.5 KiB
249 lines
8.5 KiB
//==============================================================================
|
|
//
|
|
// Copyright (c) 2002-
|
|
// Authors:
|
|
// * Mark Kattenbelt <mark.kattenbelt@comlab.ox.ac.uk> (University of Oxford, formerly University of Birmingham)
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// This file is part of PRISM.
|
|
//
|
|
// PRISM 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.
|
|
//
|
|
// PRISM 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 PRISM; if not, write to the Free Software Foundation,
|
|
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
//==============================================================================
|
|
|
|
package userinterface.util;
|
|
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
|
|
import javax.swing.*;
|
|
import javax.swing.event.*;
|
|
import javax.swing.table.*;
|
|
|
|
/**
|
|
* An object to represent a grouped TableHeader. It extends JTableHeader, but actually consists of two separate
|
|
* JTableHeaders. Some of this could be tidied up, but it is build more or less to Swings concepts.
|
|
*/
|
|
@SuppressWarnings("serial")
|
|
public class GUIGroupedTableHeader extends JTableHeader implements TableColumnModelListener, MouseListener
|
|
{
|
|
private JTableHeader bottomHeader;
|
|
private JTableHeader topHeader;
|
|
private GUIGroupedTableModel tableModel;
|
|
|
|
/**
|
|
* Creates a new GUIGroupedTableHeader.
|
|
* @param model The column model that is the basis of this table header (must be grouped).
|
|
*/
|
|
public GUIGroupedTableHeader(GUIGroupedTableColumnModel model, GUIGroupedTableModel tableModel, GUIGroupedTable table)
|
|
{
|
|
super();
|
|
removeAll();
|
|
|
|
this.tableModel = tableModel;
|
|
|
|
topHeader = new JTableHeader(model.getGroupTableColumnModel());
|
|
topHeader.setResizingAllowed(false);
|
|
topHeader.setReorderingAllowed(false);
|
|
|
|
final TableCellRenderer renderer = topHeader.getDefaultRenderer();
|
|
topHeader.setDefaultRenderer(new TableCellRenderer() {
|
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
|
|
{
|
|
Component component = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
|
component.setFont(topHeader.getFont().deriveFont(Font.BOLD));
|
|
return component;
|
|
}
|
|
});
|
|
|
|
bottomHeader = new JTableHeader(model);
|
|
bottomHeader.setReorderingAllowed(false);
|
|
|
|
topHeader.setTable(table);
|
|
bottomHeader.setTable(table);
|
|
|
|
setLayout(new GridLayout(2,1));
|
|
|
|
add(topHeader);
|
|
add(bottomHeader);
|
|
|
|
model.updateGroups();
|
|
|
|
this.setPreferredSize(new Dimension(bottomHeader.getPreferredSize().width, bottomHeader.getPreferredSize().height * 2));
|
|
this.setMinimumSize(new Dimension(bottomHeader.getMinimumSize().width, bottomHeader.getMinimumSize().height * 2));
|
|
this.setMaximumSize(new Dimension(bottomHeader.getMaximumSize().width, bottomHeader.getMaximumSize().height * 2));
|
|
|
|
Component[] cs = this.getComponents();
|
|
for (int i = 0; i < cs.length; i++)
|
|
{
|
|
cs[i].addMouseListener(this);
|
|
}
|
|
|
|
topHeader.addMouseMotionListener(new MouseMotionAdapter()
|
|
{
|
|
private TableColumn lastColumn;
|
|
|
|
public void mouseMoved(MouseEvent e)
|
|
{
|
|
bottomHeader.setToolTipText(null);
|
|
|
|
TableColumn currentColumn;
|
|
|
|
int column = topHeader.getColumnModel().getColumnIndexAtX(e.getX());
|
|
|
|
if (column >= 0)
|
|
{
|
|
currentColumn = topHeader.getColumnModel().getColumn(column);
|
|
|
|
if (currentColumn != lastColumn)
|
|
{
|
|
topHeader.setToolTipText((GUIGroupedTableHeader.this).tableModel.getGroupToolTip(column));
|
|
lastColumn = currentColumn;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
bottomHeader.addMouseMotionListener(new MouseMotionAdapter()
|
|
{
|
|
private TableColumn lastColumn;
|
|
|
|
public void mouseMoved(MouseEvent e)
|
|
{
|
|
topHeader.setToolTipText(null);
|
|
|
|
TableColumn currentColumn;
|
|
|
|
int column = bottomHeader.getColumnModel().getColumnIndexAtX(e.getX());
|
|
|
|
if (column >= 0)
|
|
{
|
|
currentColumn = bottomHeader.getColumnModel().getColumn(column);
|
|
|
|
if (currentColumn != lastColumn)
|
|
{
|
|
bottomHeader.setToolTipText((GUIGroupedTableHeader.this).tableModel.getColumnToolTip(column));
|
|
lastColumn = currentColumn;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
//topHeader.setToolTipText(null);
|
|
//bottomHeader.setToolTipText(null);
|
|
}
|
|
|
|
|
|
/**
|
|
* A fairly ugly hack to prevent a CellRenderer to be added to this container. More elegant solutions are welcome.
|
|
* @see java.awt.Container#addImpl(java.awt.Component, java.lang.Object, int)
|
|
*/
|
|
@Override
|
|
protected void addImpl(Component comp, Object constraints, int index) {
|
|
// TODO Auto-generated method stub
|
|
if (this.getComponents().length < 2)
|
|
{
|
|
super.addImpl(comp, constraints, index);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Overwritten to never allow reordering.
|
|
* @see javax.swing.table.JTableHeader#setReorderingAllowed(boolean)
|
|
*/
|
|
@Override
|
|
public void setReorderingAllowed(boolean reorderingAllowed) {
|
|
super.setReorderingAllowed(false);
|
|
}
|
|
|
|
/**
|
|
* Overwritten to always return the resizing column of the bottom JTableHeader.
|
|
* @see javax.swing.table.JTableHeader#getResizingColumn()
|
|
*/
|
|
@Override
|
|
public TableColumn getResizingColumn()
|
|
{
|
|
return bottomHeader.getResizingColumn();
|
|
}
|
|
|
|
/**
|
|
* Overwritten to give the JTableHeaders a change to resize as well.
|
|
* @see javax.swing.table.JTableHeader#resizeAndRepaint()
|
|
*/
|
|
@Override
|
|
public void resizeAndRepaint()
|
|
{
|
|
if (topHeader != null && bottomHeader != null)
|
|
{
|
|
this.setPreferredSize(new Dimension(bottomHeader.getPreferredSize().width, bottomHeader.getPreferredSize().height * 2));
|
|
this.setMinimumSize(new Dimension(bottomHeader.getMinimumSize().width, bottomHeader.getMinimumSize().height * 2));
|
|
this.setMaximumSize(new Dimension(bottomHeader.getMaximumSize().width, bottomHeader.getMaximumSize().height * 2));
|
|
|
|
this.doLayout();
|
|
}
|
|
|
|
super.resizeAndRepaint();
|
|
}
|
|
|
|
/**
|
|
* Set the column model.
|
|
* @param columnModel The grouped column model to use.
|
|
*/
|
|
public void setColumnModel(GUIGroupedTableColumnModel columnModel) {
|
|
|
|
topHeader.setColumnModel(columnModel.getGroupTableColumnModel());
|
|
bottomHeader.setColumnModel(columnModel);
|
|
|
|
this.resizeAndRepaint();
|
|
|
|
columnModel.updateGroups();
|
|
super.setColumnModel(columnModel);
|
|
}
|
|
|
|
/**
|
|
* Overwritten to catch events of child components.
|
|
*/
|
|
public void mouseClicked(MouseEvent e) {
|
|
this.dispatchEvent(new MouseEvent(this, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY() + ((Component)e.getSource()).getBounds().y, e.getClickCount(), e.isPopupTrigger()));
|
|
}
|
|
|
|
/**
|
|
* Overwritten to catch events of child components.
|
|
*/
|
|
public void mouseEntered(MouseEvent e) {
|
|
this.dispatchEvent(new MouseEvent(this, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY() + ((Component)e.getSource()).getBounds().y, e.getClickCount(), e.isPopupTrigger()));
|
|
}
|
|
|
|
/**
|
|
* Overwritten to catch events of child components.
|
|
*/
|
|
public void mouseExited(MouseEvent e) {
|
|
this.dispatchEvent(new MouseEvent(this, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY() + ((Component)e.getSource()).getBounds().y, e.getClickCount(), e.isPopupTrigger()));
|
|
}
|
|
|
|
/**
|
|
* Overwritten to catch events of child components.
|
|
*/
|
|
public void mousePressed(MouseEvent e) {
|
|
this.dispatchEvent(new MouseEvent(this, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY() + ((Component)e.getSource()).getBounds().y, e.getClickCount(), e.isPopupTrigger()));
|
|
}
|
|
|
|
/**
|
|
* Overwritten to catch events of child components.
|
|
*/
|
|
public void mouseReleased(MouseEvent e) {
|
|
this.dispatchEvent(new MouseEvent(this, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY() + ((Component)e.getSource()).getBounds().y, e.getClickCount(), e.isPopupTrigger()));
|
|
}
|
|
}
|