📄 classextentview.java
字号:
/* * USE - UML based specification environment * Copyright (C) 1999-2004 Mark Richters, University of Bremen * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* $ProjectHeader: use 2-3-0-release.1 Mon, 12 Sep 2005 20:18:33 +0200 green $ */package org.tzi.use.gui.views;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.io.PrintWriter;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import javax.swing.Icon;import javax.swing.ImageIcon;import javax.swing.JCheckBoxMenuItem;import javax.swing.JMenu;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.JPopupMenu;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.ListSelectionModel;import javax.swing.table.AbstractTableModel;import org.tzi.use.config.Options;import org.tzi.use.gui.main.MainWindow;import org.tzi.use.gui.main.ModelBrowserSorting;import org.tzi.use.gui.main.ModelBrowserSorting.SortChangeEvent;import org.tzi.use.gui.main.ModelBrowserSorting.SortChangeListener;import org.tzi.use.gui.util.PopupListener;import org.tzi.use.uml.mm.MAttribute;import org.tzi.use.uml.mm.MClass;import org.tzi.use.uml.mm.MClassInvariant;import org.tzi.use.uml.ocl.expr.Evaluator;import org.tzi.use.uml.ocl.expr.Expression;import org.tzi.use.uml.ocl.value.ObjectValue;import org.tzi.use.uml.ocl.value.SetValue;import org.tzi.use.uml.ocl.value.Value;import org.tzi.use.uml.ocl.value.VarBindings;import org.tzi.use.uml.sys.MObject;import org.tzi.use.uml.sys.MObjectState;import org.tzi.use.uml.sys.MSystem;import org.tzi.use.uml.sys.StateChangeEvent;import org.tzi.use.util.NullWriter;/** * A view showing all objects of a class, their properties * (attributes), and results of invariants. * * @version $ProjectVersion: 2-3-0-release.1 $ * @author Mark Richters */public class ClassExtentView extends JPanel implements View, ActionListener {// private MainWindow fMainWindow; private MSystem fSystem; private MClass fClass; private boolean fShowInvResults; private JPopupMenu fPopupMenu; // context menu on right mouse click private JTable fTable; private JScrollPane fTablePane; private TableModel fTableModel; public ClassExtentView(MainWindow parent, MSystem system) { super(new BorderLayout());// fMainWindow = parent; fSystem = system; fSystem.addChangeListener(this); // get a class Collection classes = fSystem.model().classes(); if (! classes.isEmpty() ) { fClass = (MClass) classes.iterator().next(); } // create table of attribute/value pairs fTableModel = new TableModel(); fTable = new JTable(fTableModel); fTable.setPreferredScrollableViewportSize(new Dimension(250, 70)); fTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); fTablePane = new JScrollPane(fTable); // create the popup menu for options fPopupMenu = new JPopupMenu(); final JCheckBoxMenuItem cbShowInvResults = new JCheckBoxMenuItem("Show results of invariants"); cbShowInvResults.setState(fShowInvResults); cbShowInvResults.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent ev) { fShowInvResults = ev.getStateChange() == ItemEvent.SELECTED; fTableModel.initStructure(); fTableModel.initModel(); if (fShowInvResults ) fTableModel.updateInvariants(); fTableModel.fireTableStructureChanged(); fTableModel.fireTableDataChanged(); } }); fPopupMenu.add(cbShowInvResults); JMenu submenu = new JMenu("Select class"); // add all classes to submenu Object[] c = classes.toArray(); Arrays.sort(c); JMenu sub = submenu; for (int i = 0; i < c.length; i++) { if (i > 0 && i % 30 == 0 ) { // nested submenus for large model JMenu s = new JMenu("More..."); sub.add(s); sub = s; } JMenuItem mi = new JMenuItem(((MClass) c[i]).name()); mi.addActionListener(this); sub.add(mi); } fPopupMenu.add(submenu); fTable.addMouseListener(new PopupListener(fPopupMenu)); fTablePane.addMouseListener(new PopupListener(fPopupMenu)); // layout panel add(fTablePane, BorderLayout.CENTER); } /** * Called when a class was selected in the popup menu. */ public void actionPerformed(ActionEvent e) { // System.err.println("*** ActionEvent = " + e.getActionCommand()); String name = e.getActionCommand(); // see if there's really a change if (fClass.name().equals(name) ) return; fClass = fSystem.model().getClass(name); fTableModel.initStructure(); fTableModel.initModel(); if (fShowInvResults ) fTableModel.updateInvariants(); fTableModel.fireTableStructureChanged(); fTableModel.fireTableDataChanged(); // TableColumn column = null; // for (int i = fTableModel.getColumnCount() - 1; i >= 0; i--) { // column = fTable.getColumnModel().getColumn(i); // column.sizeWidthToFit(); // } } // icons used for invariant results private static final Icon fTrueIcon = new ImageIcon(Options.iconDir + "InvTrue.gif"); private static final Icon fFalseIcon = new ImageIcon(Options.iconDir + "InvFalse.gif"); private static final Icon fNotAvailIcon = new ImageIcon(Options.iconDir + "InvNotAvail.gif"); /** * The table model. */ class TableModel extends AbstractTableModel implements SortChangeListener { private ArrayList fColumnNames; private ArrayList fObjects; private List fAttributes; private List fClassInvariants; private Map fObjectValueStrMap; // (MObject -> String) private Map fInvBadObjects; // (MClassInvariant -> Set(MObject)) // need to cache all data because getValueAt is called often. TableModel() { fObjects = new ArrayList(); fColumnNames = new ArrayList(); fObjectValueStrMap = new HashMap(); fInvBadObjects = new HashMap(); fAttributes = new ArrayList(); fClassInvariants = new ArrayList(); ModelBrowserSorting.getInstance().addSortChangeListener( this ); initStructure(); initModel(); } void initStructure() { fColumnNames.clear(); fInvBadObjects.clear(); if (fClass == null ) return; // prepare table: get attributes of class fAttributes = (ArrayList) ModelBrowserSorting.getInstance().sortAttributes( fClass.allAttributes() ); // set columns fColumnNames.add(fClass.name()); for (int i = 0; i < fAttributes.size(); i++) fColumnNames.add( ((MAttribute) fAttributes.get(i)).name()); // get all invariants for selected class if (fShowInvResults ) { Set invSet = fSystem.model().allClassInvariants(fClass); fClassInvariants = (ArrayList) ModelBrowserSorting.getInstance() .sortInvariants( invSet ); for (int i = 0; i < fClassInvariants.size(); i++) fColumnNames.add( ((MClassInvariant) fClassInvariants.get(i)).name()); } } void initModel() { // initialize object list fObjects.clear(); fObjectValueStrMap.clear(); if (fClass == null ) return; // get attribute values for all objects Iterator objIter = fSystem.state().objectsOfClass(fClass).iterator(); while (objIter.hasNext() ) { MObject obj = (MObject) objIter.next(); addObject(obj); } sortRows(); } /** * After the occurence of an event the attribute list is updated. */ public void stateChanged( SortChangeEvent e ) { fAttributes = (ArrayList) ModelBrowserSorting.getInstance() .sortAttributes( fAttributes ); fClassInvariants = (ArrayList) ModelBrowserSorting.getInstance() .sortInvariants( fClassInvariants ); initStructure(); initModel(); updateInvariants(); fTableModel.fireTableStructureChanged(); fTableModel.fireTableDataChanged(); } void updateInvariants() { if (! fSystem.state().checkStructure(new PrintWriter(new NullWriter())) ) { // cannot evaluate on ill-formed state for (int i = 0; i < fClassInvariants.size(); i++) { fInvBadObjects.put(fClassInvariants.get(i), null); } } else { for (int i = 0; i < fClassInvariants.size(); i++) { Set badObjects = new HashSet(); Evaluator evaluator = new Evaluator(); Expression expr = ((MClassInvariant) fClassInvariants.get(i)) .getExpressionForViolatingInstances(); Value v = evaluator.eval(expr, fSystem.state(), new VarBindings()); Iterator valIter = ((SetValue) v).collection().iterator(); while (valIter.hasNext() ) { ObjectValue oVal = (ObjectValue) valIter.next(); badObjects.add(oVal.value()); } fInvBadObjects.put(fClassInvariants.get(i), badObjects); } } } public String getColumnName(int col) { return (String) fColumnNames.get(col); } public int getColumnCount() { return fColumnNames.size(); } public int getRowCount() { return fObjects.size(); } public Class getColumnClass(int col) { if (col <= fAttributes.size() ) return String.class; else return Icon.class; } public Object getValueAt(int row, int col) { // System.err.println("*** getValueAt (" + row + ", " + col + ")"); MObject obj = (MObject) fObjects.get(row); if (col == 0 ) return obj.name(); else if (col <= fAttributes.size() ) { String[] values = (String[]) fObjectValueStrMap.get(obj); return values[col - 1]; } else { MClassInvariant inv = (MClassInvariant) fClassInvariants.get( col - fAttributes.size() - 1 ); Set badObjects = (Set) fInvBadObjects.get(inv); if (badObjects == null ) return fNotAvailIcon; else if (badObjects.contains(obj) ) return fFalseIcon; else return fTrueIcon; } } /** * Adds a row for an object to the table. */ void addObject(MObject obj) { fObjects.add(obj); updateObject(obj); } /** * Updates the row for the given object. */ void updateObject(MObject obj) { MObjectState objState = obj.state(fSystem.state()); String[] values = new String[fAttributes.size()]; for (int i = 0; i < fAttributes.size(); i++) values[i] = ((Value) objState.attributeValue( (MAttribute) fAttributes.get(i) ) ).toString(); fObjectValueStrMap.put(obj, values); } /** * Removes a row for an object from the table. */ void removeObject(MObject obj) { fObjects.remove(obj); fObjectValueStrMap.remove(obj); } void sortRows() { Collections.sort(fObjects, new Comparator() { public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); }}); } } /** * Called due to an external change of state. */ public void stateChanged(StateChangeEvent e) { Iterator it; // incremental update of table model it = e.getNewObjects().iterator(); while (it.hasNext() ) { MObject obj = (MObject) it.next(); if (obj.cls().equals(fClass) ) fTableModel.addObject(obj); } it = e.getDeletedObjects().iterator(); while (it.hasNext() ) { MObject obj = (MObject) it.next(); if (obj.cls().equals(fClass) ) fTableModel.removeObject(obj); } it = e.getModifiedObjects().iterator(); while (it.hasNext() ) { MObject obj = (MObject) it.next(); if (obj.cls().equals(fClass) ) fTableModel.updateObject(obj); } // change in number of rows? if (e.structureHasChanged() ) fTableModel.sortRows(); if (fShowInvResults ) fTableModel.updateInvariants(); fTableModel.fireTableDataChanged(); } /** * Detaches the view from its model. */ public void detachModel() { fSystem.removeChangeListener(this); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -