Browse Source
Added a multi-headered table in the simulator. Added this in a general way in userinterface.util.GUIGroupedTable
Added a multi-headered table in the simulator. Added this in a general way in userinterface.util.GUIGroupedTable
git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@164 bbc10eb1-c90d-0410-af57-cb519fbb1720master
6 changed files with 631 additions and 10 deletions
-
122prism/src/userinterface/simulator/GUISimulator.java
-
15prism/src/userinterface/simulator/GUISimulatorPathTable.java
-
118prism/src/userinterface/util/GUIGroupedTable.java
-
145prism/src/userinterface/util/GUIGroupedTableColumnModel.java
-
188prism/src/userinterface/util/GUIGroupedTableHeader.java
-
53prism/src/userinterface/util/GUIGroupedTableModel.java
@ -0,0 +1,118 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2002-2006, Mark Kattenbelt |
||||
|
// |
||||
|
// 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 javax.swing.*; |
||||
|
import javax.swing.table.*; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @author mxk |
||||
|
* A table object that is capable of grouping headers, effectively by means of two JTableHeader |
||||
|
* Objects on top of each other. |
||||
|
*/ |
||||
|
public class GUIGroupedTable extends JTable |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* Creates a new GUIGroupedTable. |
||||
|
* @param tableModel The (grouped) table data model on which to base this table. |
||||
|
*/ |
||||
|
public GUIGroupedTable(GUIGroupedTableModel tableModel) |
||||
|
{ |
||||
|
super(tableModel); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* The default TableColumnModel Object (and the only valid one) is a GUIGroupedColumnModel Object. |
||||
|
* @see javax.swing.JTable#createDefaultColumnModel() |
||||
|
*/ |
||||
|
@Override |
||||
|
protected TableColumnModel createDefaultColumnModel() |
||||
|
{ |
||||
|
return new GUIGroupedTableColumnModel(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Given a GUIGroupedTableModel, this function creates a GUIGroupedColumnModel. |
||||
|
* This function is called by JTable when the structure of the table changes, such that |
||||
|
* it is not necessary to worry about the header. |
||||
|
* @see javax.swing.JTable#createDefaultColumnsFromModel() |
||||
|
*/ |
||||
|
@Override |
||||
|
public void createDefaultColumnsFromModel() |
||||
|
{ |
||||
|
GUIGroupedTableColumnModel groupedColumnModel = (GUIGroupedTableColumnModel)columnModel; |
||||
|
|
||||
|
groupedColumnModel.clear(); |
||||
|
|
||||
|
if (dataModel != null && dataModel instanceof GUIGroupedTableModel && columnModel instanceof GUIGroupedTableColumnModel) |
||||
|
{ |
||||
|
GUIGroupedTableModel groupedDataModel = (GUIGroupedTableModel)dataModel; |
||||
|
|
||||
|
int group = 0; |
||||
|
int element = 0; |
||||
|
|
||||
|
// Add a group every iteration |
||||
|
while (group < groupedDataModel.getGroupCount() && element < groupedDataModel.getColumnCount()) |
||||
|
{ |
||||
|
ArrayList groupElements = new ArrayList(); |
||||
|
|
||||
|
// Add an element every iteration |
||||
|
while (groupedDataModel.getLastColumnOfGroup(group) >= element) |
||||
|
{ |
||||
|
TableColumn elementColumn = new TableColumn(element); |
||||
|
elementColumn.setHeaderValue(groupedDataModel.getColumnName(element)); |
||||
|
groupElements.add(elementColumn); |
||||
|
element++; |
||||
|
} |
||||
|
|
||||
|
TableColumn groupColumn = new TableColumn(group); |
||||
|
groupColumn.setHeaderValue(groupedDataModel.getGroupName(group)); |
||||
|
group++; |
||||
|
|
||||
|
groupedColumnModel.addColumnGroup(groupColumn, groupElements); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Creates a default table header from the current column model. |
||||
|
* Also called by JTable such that there is no need to worry about headers once you implemented |
||||
|
* GUIGroupedTableModel. |
||||
|
* @see javax.swing.JTable#createDefaultTableHeader() |
||||
|
*/ |
||||
|
@Override |
||||
|
protected JTableHeader createDefaultTableHeader() { |
||||
|
|
||||
|
if (columnModel != null && columnModel instanceof GUIGroupedTableColumnModel) |
||||
|
{ |
||||
|
return new GUIGroupedTableHeader((GUIGroupedTableColumnModel)columnModel); |
||||
|
} |
||||
|
return new GUIGroupedTableHeader(new GUIGroupedTableColumnModel()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,145 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2002-2006, Mark Kattenbelt |
||||
|
// |
||||
|
// 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.util.*; |
||||
|
import javax.swing.event.*; |
||||
|
import javax.swing.table.*; |
||||
|
|
||||
|
/** |
||||
|
* @author mxk |
||||
|
* The TableColumnModel with the addition of Groups. A group is a set of columns. The set of columns |
||||
|
* belonging to each group are disjoint and non-empty (!). |
||||
|
*/ |
||||
|
/** |
||||
|
* @author mxk |
||||
|
* |
||||
|
*/ |
||||
|
public class GUIGroupedTableColumnModel extends DefaultTableColumnModel implements TableColumnModelListener |
||||
|
{ |
||||
|
//private DefaultTableColumnModel elementTableColumnModel; |
||||
|
private DefaultTableColumnModel groupTableColumnModel; |
||||
|
|
||||
|
// The nth element is the index of the last element in the nth group. |
||||
|
private ArrayList lastColumn; |
||||
|
|
||||
|
/** |
||||
|
* Creates a new GUIGroupedTableModel with no groups. |
||||
|
*/ |
||||
|
public GUIGroupedTableColumnModel() |
||||
|
{ |
||||
|
lastColumn = new ArrayList(); |
||||
|
|
||||
|
//this.elementTableColumnModel = new DefaultTableColumnModel(); |
||||
|
this.groupTableColumnModel = new DefaultTableColumnModel(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Returns The columns of all groups in terms of a DefaultTableColumnModel. |
||||
|
* @return The columns of all groups in terms of a DefaultTableColumnModel. |
||||
|
*/ |
||||
|
public DefaultTableColumnModel getGroupTableColumnModel() |
||||
|
{ |
||||
|
return groupTableColumnModel; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Adds a group to this grouped column model. |
||||
|
* @param groupColumn A TableColumn representing all of the group. |
||||
|
* @param elementColumns An ArrayList of TableColumns representing the columns of this group in the model. |
||||
|
*/ |
||||
|
public void addColumnGroup(TableColumn groupColumn, ArrayList elementColumns) |
||||
|
{ |
||||
|
groupTableColumnModel.addColumn(groupColumn); |
||||
|
|
||||
|
for (int i = 0; i < elementColumns.size(); i++) |
||||
|
{ |
||||
|
this.addColumn(((TableColumn)elementColumns.get(i))); |
||||
|
} |
||||
|
|
||||
|
lastColumn.add(new Integer(this.getColumnCount()-1)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* A function that updates the widths of the group columns. |
||||
|
*/ |
||||
|
public void updateGroups() |
||||
|
{ |
||||
|
int group = 0; |
||||
|
int groupWidth = 0; |
||||
|
|
||||
|
for (int i = 0; i < this.getColumnCount(); i++) |
||||
|
{ |
||||
|
groupWidth += this.getColumn(i).getWidth(); |
||||
|
|
||||
|
// If this is the last column of a group. |
||||
|
if (i == ((Integer)lastColumn.get(group)).intValue()) |
||||
|
{ |
||||
|
while (group < groupTableColumnModel.getColumnCount() && i == ((Integer)lastColumn.get(group)).intValue()) |
||||
|
{ |
||||
|
groupTableColumnModel.getColumn(group).setWidth(groupWidth); |
||||
|
|
||||
|
groupWidth = 0; |
||||
|
group++; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void columnAdded(TableColumnModelEvent e) {} |
||||
|
public void columnMarginChanged(ChangeEvent e) {} |
||||
|
public void columnMoved(TableColumnModelEvent e) {} |
||||
|
public void columnRemoved(TableColumnModelEvent e) {} |
||||
|
public void columnSelectionChanged(ListSelectionEvent e) {} |
||||
|
|
||||
|
/** |
||||
|
* If something changed in the columns of the table, then adjust the group widths. |
||||
|
*/ |
||||
|
@Override |
||||
|
protected void fireColumnMarginChanged() { |
||||
|
// Size must have changed then. |
||||
|
updateGroups(); |
||||
|
super.fireColumnMarginChanged(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Empties this GUIGroupedTableColumnModel. |
||||
|
*/ |
||||
|
public void clear() |
||||
|
{ |
||||
|
while (this.getColumnCount() > 0) |
||||
|
{ |
||||
|
this.removeColumn(this.getColumn(0)); |
||||
|
} |
||||
|
|
||||
|
while (groupTableColumnModel.getColumnCount() > 0) |
||||
|
{ |
||||
|
groupTableColumnModel.removeColumn(groupTableColumnModel.getColumn(0)); |
||||
|
} |
||||
|
|
||||
|
this.lastColumn.clear(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,188 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2002-2006, Mark Kattenbelt |
||||
|
// |
||||
|
// 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.*; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @author mxk |
||||
|
* 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. |
||||
|
*/ |
||||
|
public class GUIGroupedTableHeader extends JTableHeader implements TableColumnModelListener, MouseListener |
||||
|
{ |
||||
|
private JTableHeader bottomHeader; |
||||
|
private JTableHeader topHeader; |
||||
|
|
||||
|
/** |
||||
|
* Creates a new GUIGroupedTableHeader. |
||||
|
* @param model The column model that is the basis of this table header (must be grouped). |
||||
|
*/ |
||||
|
public GUIGroupedTableHeader(GUIGroupedTableColumnModel model) |
||||
|
{ |
||||
|
super(); |
||||
|
removeAll(); |
||||
|
|
||||
|
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); |
||||
|
|
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 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())); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2002-2006, Mark Kattenbelt |
||||
|
// |
||||
|
// 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 javax.swing.table.TableModel; |
||||
|
|
||||
|
/** |
||||
|
* @author mxk |
||||
|
* An interface which extends {@link TableModel} such that also group information can |
||||
|
* be extracted automatically. Note that groups are always non-empty. |
||||
|
*/ |
||||
|
public interface GUIGroupedTableModel extends TableModel |
||||
|
{ |
||||
|
/** |
||||
|
* @return The number of groups in this model. |
||||
|
*/ |
||||
|
public int getGroupCount(); |
||||
|
|
||||
|
/** |
||||
|
* Retrieves the name of a group. |
||||
|
* @param groupIndex The index of a group. |
||||
|
* @return The name of the nth group, where n = groupIndex. |
||||
|
* @see TableModel.getColumnName(int columnIndex). |
||||
|
*/ |
||||
|
public String getGroupName(int groupIndex); |
||||
|
|
||||
|
/** |
||||
|
* Retrieves the index of the last `normal' column in a group. |
||||
|
* @param groupIndex The index of a group. |
||||
|
* @return The index of the last column in this group. |
||||
|
*/ |
||||
|
public int getLastColumnOfGroup(int groupIndex); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue