View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors
3    * All rights reserved.
4    *
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    *
8    * 
9    */
10  package edu.uci.ics.jung.visualization.annotations;
11  
12  import java.awt.Component;
13  import java.awt.Cursor;
14  import java.awt.Dimension;
15  import java.awt.ItemSelectable;
16  import java.awt.event.InputEvent;
17  import java.awt.event.ItemEvent;
18  import java.awt.event.ItemListener;
19  import java.awt.event.KeyAdapter;
20  import java.awt.event.KeyEvent;
21  
22  import javax.swing.ButtonGroup;
23  import javax.swing.Icon;
24  import javax.swing.JComboBox;
25  import javax.swing.JMenu;
26  import javax.swing.JRadioButtonMenuItem;
27  import javax.swing.plaf.basic.BasicIconFactory;
28  
29  import edu.uci.ics.jung.visualization.MultiLayerTransformer;
30  import edu.uci.ics.jung.visualization.RenderContext;
31  import edu.uci.ics.jung.visualization.control.AbstractModalGraphMouse;
32  import edu.uci.ics.jung.visualization.control.AnimatedPickingGraphMousePlugin;
33  import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
34  import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
35  import edu.uci.ics.jung.visualization.control.PickingGraphMousePlugin;
36  import edu.uci.ics.jung.visualization.control.RotatingGraphMousePlugin;
37  import edu.uci.ics.jung.visualization.control.ScalingGraphMousePlugin;
38  import edu.uci.ics.jung.visualization.control.ShearingGraphMousePlugin;
39  import edu.uci.ics.jung.visualization.control.TranslatingGraphMousePlugin;
40  
41  /**
42   * a graph mouse that supplies an annotations mode
43   * 
44   * @author Tom Nelson - tomnelson@dev.java.net
45   *
46   * @param <V> the vertex type
47   * @param <E> the edge type
48   */
49  public class AnnotatingModalGraphMouse<V,E> extends AbstractModalGraphMouse 
50  	implements ModalGraphMouse, ItemSelectable {
51  
52  	protected AnnotatingGraphMousePlugin<V,E> annotatingPlugin;
53  	protected MultiLayerTransformer basicTransformer;
54  	protected RenderContext<V,E> rc;
55  
56  	/**
57  	 * Create an instance with default values for scale in (1.1) and scale out (1/1.1).
58  	 * 
59  	 * @param rc the RenderContext for which this class will be used
60  	 * @param annotatingPlugin the plugin used by this class for annotating
61  	 */
62  	public AnnotatingModalGraphMouse(RenderContext<V,E> rc, 
63  			AnnotatingGraphMousePlugin<V,E> annotatingPlugin) {
64  		this(rc, annotatingPlugin, 1.1f, 1/1.1f);
65  	}
66  
67  	/**
68  	 * Create an instance with the specified scale in and scale out values.
69  	 * 
70  	 * @param rc the RenderContext for which this class will be used
71  	 * @param annotatingPlugin the plugin used by this class for annotating
72  	 * @param in override value for scale in
73  	 * @param out override value for scale out
74  	 */
75  	public AnnotatingModalGraphMouse(RenderContext<V,E> rc,
76  			AnnotatingGraphMousePlugin<V,E> annotatingPlugin,
77  			float in, float out) {
78  		super(in,out);
79  		this.rc = rc;
80  		this.basicTransformer = rc.getMultiLayerTransformer();
81  		this.annotatingPlugin = annotatingPlugin;
82  		loadPlugins();
83  		setModeKeyListener(new ModeKeyAdapter(this));
84  	}
85  
86  	/**
87  	 * create the plugins, and load the plugins for TRANSFORMING mode
88  	 *
89  	 */
90  	@Override
91      protected void loadPlugins() {
92  		this.pickingPlugin = new PickingGraphMousePlugin<V,E>();
93  		this.animatedPickingPlugin = new AnimatedPickingGraphMousePlugin<V,E>();
94  		this.translatingPlugin = new TranslatingGraphMousePlugin(InputEvent.BUTTON1_MASK);
95  		this.scalingPlugin = new ScalingGraphMousePlugin(new CrossoverScalingControl(), 0, in, out);
96  		this.rotatingPlugin = new RotatingGraphMousePlugin();
97  		this.shearingPlugin = new ShearingGraphMousePlugin();
98  		add(scalingPlugin);
99  		setMode(Mode.TRANSFORMING);
100 	}
101 
102 	/**
103 	 * setter for the Mode.
104 	 */
105 	@Override
106 	public void setMode(Mode mode) {
107 		if(this.mode != mode) {
108 			fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
109 					this.mode, ItemEvent.DESELECTED));
110 			this.mode = mode;
111 			if(mode == Mode.TRANSFORMING) {
112 				setTransformingMode();
113 			} else if(mode == Mode.PICKING) {
114 				setPickingMode();
115 			} else if(mode == Mode.ANNOTATING) {
116 				setAnnotatingMode();
117 			}
118 			if(modeBox != null) {
119 				modeBox.setSelectedItem(mode);
120 			}
121 			fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, mode, ItemEvent.SELECTED));
122 		}
123 	}
124 	
125 	@Override
126 	protected void setPickingMode() {
127 		remove(translatingPlugin);
128 		remove(rotatingPlugin);
129 		remove(shearingPlugin);
130 		remove(annotatingPlugin);
131 		add(pickingPlugin);
132 		add(animatedPickingPlugin);
133 	}
134 
135 	@Override
136 	protected void setTransformingMode() {
137 		remove(pickingPlugin);
138 		remove(animatedPickingPlugin);
139 		remove(annotatingPlugin);
140 		add(translatingPlugin);
141 		add(rotatingPlugin);
142 		add(shearingPlugin);
143 	}
144 
145 	protected void setEditingMode() {
146 		remove(pickingPlugin);
147 		remove(animatedPickingPlugin);
148 		remove(translatingPlugin);
149 		remove(rotatingPlugin);
150 		remove(shearingPlugin);
151 		remove(annotatingPlugin);
152 	}
153 
154 	protected void setAnnotatingMode() {
155 		remove(pickingPlugin);
156 		remove(animatedPickingPlugin);
157 		remove(translatingPlugin);
158 		remove(rotatingPlugin);
159 		remove(shearingPlugin);
160 		add(annotatingPlugin);
161 	}
162 
163 
164 	/**
165 	 * @return Returns the modeBox.
166 	 */
167 	@Override
168 	public JComboBox<Mode> getModeComboBox() {
169 		if(modeBox == null) {
170 			modeBox = new JComboBox<Mode>(
171 				new Mode[]{Mode.TRANSFORMING, Mode.PICKING, Mode.ANNOTATING});
172 			modeBox.addItemListener(getModeListener());
173 		}
174 		modeBox.setSelectedItem(mode);
175 		return modeBox;
176 	}
177 
178 	/**
179 	 * create (if necessary) and return a menu that will change
180 	 * the mode
181 	 * @return the menu
182 	 */
183 	@Override
184     public JMenu getModeMenu() {
185 		if(modeMenu == null) {
186 			modeMenu = new JMenu();// {
187 			Icon icon = BasicIconFactory.getMenuArrowIcon();
188 			modeMenu.setIcon(BasicIconFactory.getMenuArrowIcon());
189 			modeMenu.setPreferredSize(new Dimension(icon.getIconWidth()+10, 
190 					icon.getIconHeight()+10));
191 
192 			final JRadioButtonMenuItem transformingButton = 
193 				new JRadioButtonMenuItem(Mode.TRANSFORMING.toString());
194 			transformingButton.addItemListener(new ItemListener() {
195 				public void itemStateChanged(ItemEvent e) {
196 					if(e.getStateChange() == ItemEvent.SELECTED) {
197 						setMode(Mode.TRANSFORMING);
198 					}
199 				}});
200 
201 			final JRadioButtonMenuItem pickingButton =
202 				new JRadioButtonMenuItem(Mode.PICKING.toString());
203 			pickingButton.addItemListener(new ItemListener() {
204 				public void itemStateChanged(ItemEvent e) {
205 					if(e.getStateChange() == ItemEvent.SELECTED) {
206 						setMode(Mode.PICKING);
207 					}
208 				}});
209 
210 			ButtonGroup radio = new ButtonGroup();
211 			radio.add(transformingButton);
212 			radio.add(pickingButton);
213 			transformingButton.setSelected(true);
214 			modeMenu.add(transformingButton);
215 			modeMenu.add(pickingButton);
216 			modeMenu.setToolTipText("Menu for setting Mouse Mode");
217 			addItemListener(new ItemListener() {
218 				public void itemStateChanged(ItemEvent e) {
219 					if(e.getStateChange() == ItemEvent.SELECTED) {
220 						if(e.getItem() == Mode.TRANSFORMING) {
221 							transformingButton.setSelected(true);
222 						} else if(e.getItem() == Mode.PICKING) {
223 							pickingButton.setSelected(true);
224 						}
225 					}
226 				}});
227 		}
228 		return modeMenu;
229 	}
230 	
231     public static class ModeKeyAdapter extends KeyAdapter {
232     	private char t = 't';
233     	private char p = 'p';
234     	private char a = 'a';
235     	protected ModalGraphMouse graphMouse;
236 
237     	public ModeKeyAdapter(ModalGraphMouse graphMouse) {
238 			this.graphMouse = graphMouse;
239 		}
240 
241 		public ModeKeyAdapter(char t, char p, char a, ModalGraphMouse graphMouse) {
242 			this.t = t;
243 			this.p = p;
244 			this.a = a;
245 			this.graphMouse = graphMouse;
246 		}
247 		
248 		@Override
249     public void keyTyped(KeyEvent event) {
250 			char keyChar = event.getKeyChar();
251 			if(keyChar == t) {
252 				((Component)event.getSource()).setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
253 				graphMouse.setMode(Mode.TRANSFORMING);
254 			} else if(keyChar == p) {
255 				((Component)event.getSource()).setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
256 				graphMouse.setMode(Mode.PICKING);
257 			} else if(keyChar == a) {
258 				((Component)event.getSource()).setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
259 				graphMouse.setMode(Mode.ANNOTATING);
260 			}
261 		}
262     }
263 }
264