annotate java/src/uk/ac/qmul/eecs/ccmi/gui/DiagramPanel.java @ 1:e3935c01cde2 tip

moved license of PdPersistenceManager to the beginning of the file
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 08 Jul 2014 19:52:03 +0100
parents 78b7fc5391a2
children
rev   line source
f@0 1 /*
f@0 2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
f@0 3
f@0 4 Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
f@0 5 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
f@0 6
f@0 7 This program is free software: you can redistribute it and/or modify
f@0 8 it under the terms of the GNU General Public License as published by
f@0 9 the Free Software Foundation, either version 3 of the License, or
f@0 10 (at your option) any later version.
f@0 11
f@0 12 This program is distributed in the hope that it will be useful,
f@0 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
f@0 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f@0 15 GNU General Public License for more details.
f@0 16
f@0 17 You should have received a copy of the GNU General Public License
f@0 18 along with this program. If not, see <http://www.gnu.org/licenses/>.
f@0 19 */
f@0 20
f@0 21 package uk.ac.qmul.eecs.ccmi.gui;
f@0 22
f@0 23 import java.awt.BorderLayout;
f@0 24 import java.io.IOException;
f@0 25
f@0 26 import javax.swing.JPanel;
f@0 27 import javax.swing.JScrollPane;
f@0 28 import javax.swing.JSplitPane;
f@0 29 import javax.swing.event.ChangeEvent;
f@0 30 import javax.swing.event.ChangeListener;
f@0 31
f@0 32 import uk.ac.qmul.eecs.ccmi.gui.awareness.AwarenessPanel;
f@0 33 import uk.ac.qmul.eecs.ccmi.gui.awareness.DisplayFilter;
f@0 34 import uk.ac.qmul.eecs.ccmi.network.NetDiagram;
f@0 35
f@0 36 /**
f@0 37 * It's the panel which displays a diagram. It contains a {@link GraphPanel}, a {@link DiagramTree}
f@0 38 * a {@link GraphToolbar} and the {@code AwarenessPanel}.
f@0 39 * It's backed up by an instance of {@code Diagram}.
f@0 40 */
f@0 41 @SuppressWarnings("serial")
f@0 42 public class DiagramPanel extends JPanel{
f@0 43
f@0 44 /**
f@0 45 * Creates a new instance of {@code DiagramPanel} holding the diagram passed as argument.
f@0 46 *
f@0 47 * @param diagram the diagram this panel is backed up by
f@0 48 * @param tabbedPane the tabbed pane this DiagramPanel will be added to. This reference
f@0 49 * is used to updated the tab label when the diagram is modified or save (in the former
f@0 50 * case a star is added to the label, in the latter case the star is removed)
f@0 51 */
f@0 52 public DiagramPanel(Diagram diagram, EditorTabbedPane tabbedPane){
f@0 53 this.diagram = diagram;
f@0 54 this.tabbedPane = tabbedPane;
f@0 55
f@0 56 setName(diagram.getLabel());
f@0 57 setLayout(new BorderLayout());
f@0 58
f@0 59 modelChangeListener = new ChangeListener(){
f@0 60 @Override
f@0 61 public void stateChanged(ChangeEvent e) {
f@0 62 setModified(true);
f@0 63 }
f@0 64 };
f@0 65
f@0 66 toolbar = new GraphToolbar(diagram);
f@0 67 graphPanel = new GraphPanel(diagram, toolbar);
f@0 68 /* the focus must be hold by the tree and the tab panel only */
f@0 69 toolbar.setFocusable(false);
f@0 70 graphPanel.setFocusable(false);
f@0 71
f@0 72 tree = new DiagramTree(diagram);
f@0 73
f@0 74 /* the panel containing the graph and the toolbar and the awareness panel */
f@0 75 visualPanel = new JPanel(new BorderLayout());
f@0 76 visualPanel.add(toolbar, BorderLayout.NORTH);
f@0 77 visualPanel.add(new JScrollPane(graphPanel),BorderLayout.CENTER);
f@0 78 awarenessSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
f@0 79 awarenessSplitPane.setTopComponent(visualPanel);
f@0 80
f@0 81 /* divides the tree from the visual diagram */
f@0 82 JSplitPane treeSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
f@0 83 new JScrollPane(tree),
f@0 84 awarenessSplitPane);
f@0 85 treeSplitPane.setDividerLocation((int)tree.getPreferredSize().width*2);
f@0 86 add(treeSplitPane, BorderLayout.CENTER);
f@0 87 diagram.getCollectionModel().addChangeListener(modelChangeListener);
f@0 88 }
f@0 89
f@0 90 /**
f@0 91 * When a diagram is saved on the file system the its path is associated to the diagram panel
f@0 92 * and it's shown when the user hover on the its tab title.
f@0 93 *
f@0 94 * @return the path of the file where this diagram has been saved last time or {@code null}
f@0 95 */
f@0 96 public String getFilePath(){
f@0 97 return filePath;
f@0 98 }
f@0 99
f@0 100 /**
f@0 101 * Sets the file path to a new path. This method should be called after the backing diagram has
f@0 102 * been saved to a file.
f@0 103 *
f@0 104 * @param newValue the path of the file where the backing diagram has been saved last time
f@0 105 */
f@0 106 public void setFilePath(String newValue){
f@0 107 filePath = newValue;
f@0 108 }
f@0 109
f@0 110 /**
f@0 111 * Returns a reference to the backing diagram of this diagram panel.
f@0 112 *
f@0 113 * @return a reference to the backing diagram of this diagram panel
f@0 114 */
f@0 115 public Diagram getDiagram(){
f@0 116 return diagram;
f@0 117 }
f@0 118
f@0 119 /**
f@0 120 * Enables or disables the awareness panel of this diagram panel. As default the awareness panel
f@0 121 * is disabled but if the diagram is shared (either on a local or on a remote server) the awareness
f@0 122 * panel gets enabled. In fact, from now on, awareness messages will be received from the server and,
f@0 123 * even if the awareness panel is not visible, some messages (username messages)
f@0 124 * will still have to be taken into account.
f@0 125 *
f@0 126 * @param enabled {@code true} if the panel is to be enabled, {@code false} otherwise.
f@0 127 */
f@0 128 public void setAwarenessPanelEnabled(boolean enabled){
f@0 129 if(!(diagram instanceof NetDiagram))
f@0 130 return;
f@0 131 /* if the display filter has not been created yet, do create it */
f@0 132 DisplayFilter filter = DisplayFilter.getInstance();
f@0 133 if(filter == null)
f@0 134 try{
f@0 135 filter = DisplayFilter.createInstance();
f@0 136 }catch(IOException ioe){
f@0 137 SpeechOptionPane.showMessageDialog(this, ioe.getLocalizedMessage());
f@0 138 return;
f@0 139 }
f@0 140
f@0 141 NetDiagram netDiagram = (NetDiagram)diagram;
f@0 142 if(enabled){
f@0 143 awarenessPanel = new AwarenessPanel(diagram.getName());
f@0 144 awarenessPanelScrollPane = new JScrollPane(awarenessPanel);
f@0 145 netDiagram.enableAwareness(awarenessPanel);
f@0 146 if(awarenessPanelListener != null)
f@0 147 awarenessPanelListener.awarenessPanelEnabled(true);
f@0 148 }else{ //disabled
f@0 149 netDiagram.disableAwareness(awarenessPanel);
f@0 150 if(awarenessSplitPane.getRightComponent() != null){
f@0 151 // hide the panel
f@0 152 awarenessSplitPane.remove(awarenessPanelScrollPane);
f@0 153 }
f@0 154 awarenessPanelScrollPane = null;
f@0 155 awarenessPanel = null;
f@0 156 awarenessSplitPane.validate();
f@0 157 if(awarenessPanelListener != null)
f@0 158 awarenessPanelListener.awarenessPanelEnabled(false);
f@0 159 }
f@0 160 }
f@0 161
f@0 162 /**
f@0 163 * Makes the awareness panel visible or invisible, assuming that it has been enabled beforehand. If the
f@0 164 * awareness panel hasn't been enables this call has no effect.
f@0 165 *
f@0 166 * @param visible {@code true} if the panel is to be made visible, {@code false} otherwise.
f@0 167 */
f@0 168 public void setAwarenessPanelVisible(boolean visible){
f@0 169 if(awarenessPanelScrollPane == null)
f@0 170 return;
f@0 171 if(visible){
f@0 172 awarenessSplitPane.setRightComponent(awarenessPanelScrollPane);
f@0 173 awarenessSplitPane.setDividerLocation(0.8);
f@0 174 awarenessSplitPane.setResizeWeight(1.0);
f@0 175 awarenessSplitPane.validate();
f@0 176 if(awarenessPanelListener != null)
f@0 177 awarenessPanelListener.awarenessPanelVisible(true);
f@0 178 }else{
f@0 179 awarenessSplitPane.remove(awarenessPanelScrollPane);
f@0 180 awarenessSplitPane.validate();
f@0 181 if(awarenessPanelListener != null)
f@0 182 awarenessPanelListener.awarenessPanelVisible(false);
f@0 183 }
f@0 184 }
f@0 185
f@0 186 /**
f@0 187 * Queries the diagram panel on whether the awareness panel is currently visible.
f@0 188 *
f@0 189 * @return {@code true} if the awareness panel is currently visible, {@code false} otherwise.
f@0 190 */
f@0 191 public boolean isAwarenessPanelVisible(){
f@0 192 return (awarenessSplitPane.getRightComponent() != null);
f@0 193 }
f@0 194
f@0 195 /**
f@0 196 * Returns a reference to the inner awareness panel.
f@0 197 *
f@0 198 * @return the inner awareness panel if it has been enabled of {@code null} otherwise
f@0 199 */
f@0 200 public AwarenessPanel getAwarenessPanel(){
f@0 201 return awarenessPanel;
f@0 202 }
f@0 203
f@0 204 /**
f@0 205 * Sets the backing up delegate diagram for this panel. This method is used when a diagram is shared
f@0 206 * (or reverted). A shared diagram has a different way of updating the
f@0 207 * The modified status is changed according to
f@0 208 * the modified status of the {@code DiagramModel} internal to the new {@code Diagram}
f@0 209 *
f@0 210 * @param diagram the backing up delegate diagram
f@0 211 */
f@0 212 public void setDiagram(Diagram diagram){
f@0 213 /* remove the listener from the old model */
f@0 214 this.diagram.getCollectionModel().removeChangeListener(modelChangeListener);
f@0 215 diagram.getCollectionModel().addChangeListener(modelChangeListener);
f@0 216
f@0 217 this.diagram = diagram;
f@0 218 tree.setDiagram(diagram);
f@0 219 graphPanel.setModelUpdater(diagram.getModelUpdater());
f@0 220 setName(diagram.getLabel());
f@0 221 /* set the * according to the new diagram's model modification status */
f@0 222 setModified(isModified());
f@0 223 }
f@0 224
f@0 225 /**
f@0 226 * Returns a reference to the graph panel in this diagram panel. The tree's model is the
f@0 227 * model returned by a calling {@code getTreeModel()} on the backing diagram.
f@0 228 *
f@0 229 * @return the graph panel contained by this diagram panel
f@0 230 */
f@0 231 public GraphPanel getGraphPanel(){
f@0 232 return graphPanel;
f@0 233 }
f@0 234
f@0 235 /**
f@0 236 * Returns a reference to the tree in this diagram panel. The graph model is the
f@0 237 * model returned by a calling {@code getCollectionModel()} on the backing diagram.
f@0 238 *
f@0 239 * @return the tree contained by this diagram panel
f@0 240 */
f@0 241 public DiagramTree getTree(){
f@0 242 return tree;
f@0 243 }
f@0 244
f@0 245 /**
f@0 246 * Changes the {@code modified} status of the backing diagram of this panel. If set to {@code true}
f@0 247 * then a star will appear after the name of the diagram, returned by {@code getName()}.
f@0 248 *
f@0 249 * When called passing false as argument (which should be done after the diagram is saved on a file)
f@0 250 * listeners are notified that the diagram has been saved.
f@0 251 *
f@0 252 * @param modified {@code true} when the diagram has been modified, {@code false} when it has been saved
f@0 253 */
f@0 254 public void setModified(boolean modified){
f@0 255 if(!modified)
f@0 256 diagram.getCollectionModel().setUnmodified();
f@0 257 /* add an asterisk to notify that the diagram has changed */
f@0 258 if(modified)
f@0 259 setName(getName()+"*");
f@0 260 else
f@0 261 setName(diagram.getLabel());
f@0 262 tabbedPane.refreshComponentTabTitle(this);
f@0 263 }
f@0 264
f@0 265 /**
f@0 266 * Whether the backing diagram has been modified. The diagram is modified as a result of changes
f@0 267 * to the {@code TreeModel} or {@code CollectionModel} it contains. To change the {@code modified}
f@0 268 * status of the diagram (and of its models) {@code setModified()} must be used.
f@0 269 *
f@0 270 * @return {@code true} if the diagram is modified, {@code false} otherwise
f@0 271 */
f@0 272 public boolean isModified(){
f@0 273 return diagram.getCollectionModel().isModified();
f@0 274 }
f@0 275
f@0 276 void setAwarenessPanelListener(AwarenessPanelEnablingListener listener){
f@0 277 awarenessPanelListener = listener;
f@0 278 }
f@0 279
f@0 280 private Diagram diagram;
f@0 281 private GraphPanel graphPanel;
f@0 282 private JSplitPane awarenessSplitPane;
f@0 283 private DiagramTree tree;
f@0 284 private JPanel visualPanel;
f@0 285 private GraphToolbar toolbar;
f@0 286 private AwarenessPanel awarenessPanel;
f@0 287 private JScrollPane awarenessPanelScrollPane;
f@0 288 private String filePath;
f@0 289 private ChangeListener modelChangeListener;
f@0 290 private EditorTabbedPane tabbedPane;
f@0 291 private AwarenessPanelEnablingListener awarenessPanelListener;
f@0 292 }
f@0 293
f@0 294 interface AwarenessPanelEnablingListener {
f@0 295 public void awarenessPanelEnabled(boolean enabled);
f@0 296 public void awarenessPanelVisible(boolean visible);
f@0 297 }
f@0 298