|
1 /* |
|
2 * CDDL HEADER START |
|
3 * |
|
4 * The contents of this file are subject to the terms of the |
|
5 * Common Development and Distribution License (the "License"). |
|
6 * You may not use this file except in compliance with the License. |
|
7 * |
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 * or http://www.opensolaris.org/os/licensing. |
|
10 * See the License for the specific language governing permissions |
|
11 * and limitations under the License. |
|
12 * |
|
13 * When distributing Covered Code, include this CDDL HEADER in each |
|
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 * If applicable, add the following below this CDDL HEADER, with the |
|
16 * fields enclosed by brackets "[]" replaced with your own identifying |
|
17 * information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 * |
|
19 * CDDL HEADER END |
|
20 */ |
|
21 |
|
22 /* |
|
23 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
|
24 */ |
|
25 |
|
26 package com.oracle.solaris.vp.panels.usermgr.client.swing; |
|
27 |
|
28 import javax.swing.*; |
|
29 import javax.swing.event.*; |
|
30 import javax.swing.text.*; |
|
31 import javax.swing.border.*; |
|
32 import javax.swing.tree.*; |
|
33 |
|
34 import java.awt.*; |
|
35 import java.awt.event.*; |
|
36 import java.beans.*; |
|
37 import java.util.*; |
|
38 import java.io.*; |
|
39 |
|
40 import com.oracle.solaris.vp.util.misc.finder.Finder; |
|
41 |
|
42 /** |
|
43 * SMC code adapted for Visual Panels |
|
44 */ |
|
45 public class Arranger extends DoubleTrees { |
|
46 |
|
47 JButton moveUpItem, moveDownItem; |
|
48 |
|
49 public Arranger() { |
|
50 |
|
51 // Map DoubleTrees variables here for better descriptive names |
|
52 moveUpItem = addAllItem; |
|
53 moveDownItem = delAllItem; |
|
54 |
|
55 setListeners(); |
|
56 } |
|
57 |
|
58 public Arranger(String srcHeader, String dstHeader) { |
|
59 |
|
60 super(srcHeader, dstHeader); |
|
61 |
|
62 // Map DoubleTrees variables here for better descriptive names |
|
63 moveUpItem = addAllItem; |
|
64 moveDownItem = delAllItem; |
|
65 |
|
66 setListeners(); |
|
67 |
|
68 } |
|
69 |
|
70 /** |
|
71 * Create any dynamic images we need. |
|
72 */ |
|
73 public void addNotify() { |
|
74 |
|
75 ActionString actionString; |
|
76 |
|
77 super.addNotify(); |
|
78 |
|
79 delItem.setIcon(Finder.getIcon("images/remove.png")); |
|
80 delItem.setHorizontalTextPosition(JButton.RIGHT); |
|
81 |
|
82 moveDownItem.setIcon(Finder.getIcon("images/move_dn.png")); |
|
83 moveDownItem.setHorizontalTextPosition(JButton.LEFT); |
|
84 actionString = new ActionString("usermgr.advanced.move_down_btn"); |
|
85 moveDownItem.setText(actionString.getString()); |
|
86 moveDownItem.setMnemonic(actionString.getMnemonic()); |
|
87 |
|
88 addItem.setIcon(Finder.getIcon("images/add.png")); |
|
89 addItem.setHorizontalTextPosition(JButton.LEFT); |
|
90 |
|
91 moveUpItem.setIcon(Finder.getIcon("images/move_up.png")); |
|
92 moveUpItem.setHorizontalTextPosition(JButton.LEFT); |
|
93 actionString = new ActionString("usermgr.advanced.move_up_btn"); |
|
94 moveUpItem.setText(actionString.getString()); |
|
95 moveUpItem.setMnemonic(actionString.getMnemonic()); |
|
96 |
|
97 } // addNotify |
|
98 |
|
99 public void setListeners() { |
|
100 |
|
101 addItem.addActionListener(new ActionListener() { |
|
102 public void actionPerformed(ActionEvent e) { |
|
103 move(srcTree, dstTree); |
|
104 } |
|
105 }); |
|
106 |
|
107 delItem.addActionListener(new ActionListener() { |
|
108 public void actionPerformed(ActionEvent e) { |
|
109 move(dstTree, srcTree); |
|
110 } |
|
111 }); |
|
112 |
|
113 moveUpItem.addActionListener(new ActionListener() { |
|
114 public void actionPerformed(ActionEvent e) { |
|
115 reorder(dstTree, -1); |
|
116 } |
|
117 }); |
|
118 |
|
119 moveDownItem.addActionListener(new ActionListener() { |
|
120 public void actionPerformed(ActionEvent e) { |
|
121 reorder(dstTree, +1); |
|
122 } |
|
123 }); |
|
124 |
|
125 MouseListener ml = new MouseAdapter() { |
|
126 public void mouseClicked(MouseEvent e) { |
|
127 handleMouse(e); |
|
128 } |
|
129 |
|
130 public void mousePressed(MouseEvent e) { |
|
131 handleMouse(e); |
|
132 } |
|
133 }; |
|
134 |
|
135 srcTree.addMouseListener(ml); |
|
136 dstTree.addMouseListener(ml); |
|
137 |
|
138 } |
|
139 |
|
140 private void updateMoveButtons(DblTreeNode node, boolean flag) { |
|
141 |
|
142 if (flag) { |
|
143 DefaultTreeModel dstModel = (DefaultTreeModel)dstTree.getModel(); |
|
144 DblTreeNode root = (DblTreeNode)dstModel.getRoot(); |
|
145 |
|
146 int index = dstModel.getIndexOfChild(root, node); |
|
147 int limit = dstModel.getChildCount(root); |
|
148 |
|
149 if (index > 0) |
|
150 moveUpItem.setEnabled(true); |
|
151 else |
|
152 moveUpItem.setEnabled(false); |
|
153 if (index < (limit - 1)) |
|
154 moveDownItem.setEnabled(true); |
|
155 else |
|
156 moveDownItem.setEnabled(false); |
|
157 } else { |
|
158 moveUpItem.setEnabled(false); |
|
159 moveDownItem.setEnabled(false); |
|
160 } |
|
161 |
|
162 } |
|
163 |
|
164 private void handleMouse(MouseEvent e) { |
|
165 |
|
166 JTree tree1, tree2; |
|
167 |
|
168 if (e.getSource() == srcTree) { |
|
169 tree1 = srcTree; |
|
170 tree2 = dstTree; |
|
171 |
|
172 delItem.setEnabled(false); |
|
173 moveUpItem.setEnabled(false); |
|
174 moveDownItem.setEnabled(false); |
|
175 } else { |
|
176 tree1 = dstTree; |
|
177 tree2 = srcTree; |
|
178 addItem.setEnabled(false); |
|
179 } |
|
180 TreePath selPath = tree1.getPathForLocation(e.getX(), e.getY()); |
|
181 |
|
182 if (selPath != null) { |
|
183 tree2.clearSelection(); |
|
184 int selCount = selPath.getPathCount(); |
|
185 |
|
186 DblTreeNode node = (DblTreeNode)selPath.getLastPathComponent(); |
|
187 if (e.getClickCount() < 2) { |
|
188 boolean flag; |
|
189 if (selCount == 2) |
|
190 flag = true; |
|
191 else |
|
192 flag = false; |
|
193 |
|
194 if (e.getSource() == srcTree) { |
|
195 addItem.setEnabled(flag); |
|
196 } else { |
|
197 delItem.setEnabled(flag); |
|
198 updateMoveButtons(node, flag); |
|
199 } |
|
200 } else if (e.getClickCount() == 2) { |
|
201 if ((selCount == 2) && node.isLeaf()) |
|
202 move(tree1, tree2); |
|
203 } |
|
204 } |
|
205 |
|
206 } |
|
207 |
|
208 public void move(JTree src, JTree dst) { |
|
209 DblTreeNode node; |
|
210 |
|
211 TreePath selPath = src.getSelectionPath(); |
|
212 if (selPath == null) // nothing selected (should be disabled) |
|
213 return; |
|
214 else if (selPath.getPathCount() != 2) |
|
215 return; |
|
216 else { |
|
217 node = (DblTreeNode)selPath.getLastPathComponent(); |
|
218 moveLeaf(src, dst, node); |
|
219 |
|
220 if (src == dstTree) { |
|
221 addItem.setEnabled(true); |
|
222 delItem.setEnabled(false); |
|
223 updateMoveButtons(node, false); |
|
224 } else { |
|
225 addItem.setEnabled(false); |
|
226 delItem.setEnabled(true); |
|
227 updateMoveButtons(node, true); |
|
228 } |
|
229 } |
|
230 |
|
231 } |
|
232 |
|
233 |
|
234 private int matchChild(JTree src, |
|
235 JTree dst, |
|
236 DblTreeNode srcNode, |
|
237 DblTreeNode newparent, |
|
238 Enumeration dstKids, |
|
239 int index) { |
|
240 |
|
241 DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); |
|
242 DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); |
|
243 |
|
244 DblTreeNode dstNode = null; |
|
245 String srcString = srcNode.toString(); |
|
246 while (dstKids.hasMoreElements()) { |
|
247 String teststring; |
|
248 |
|
249 dstNode = (DblTreeNode)dstKids.nextElement(); |
|
250 // if(dstNode.isLeaf() == false) |
|
251 // break; // leaves come first |
|
252 teststring = dstNode.toString(); |
|
253 if (teststring.compareTo(srcString) < 0) { |
|
254 index++; |
|
255 continue; |
|
256 } else { |
|
257 break; |
|
258 } |
|
259 } |
|
260 |
|
261 srcModel.removeNodeFromParent(srcNode); |
|
262 dstModel.insertNodeInto(srcNode, newparent, index); |
|
263 index++; |
|
264 return index; |
|
265 |
|
266 } |
|
267 |
|
268 public void moveLeaf(JTree src, JTree dst, DblTreeNode node) { |
|
269 |
|
270 if (node.isEnabled()) { |
|
271 TreePath nodepath = new TreePath(node.getPath()); |
|
272 boolean expanded = src.isExpanded(nodepath); |
|
273 initLeaf(src, dst, node); |
|
274 nodepath = new TreePath(node.getPath()); |
|
275 dst.setSelectionPath(nodepath); |
|
276 |
|
277 if (expanded) |
|
278 dst.expandPath(nodepath); |
|
279 } |
|
280 |
|
281 } |
|
282 |
|
283 |
|
284 public void initLeaf(JTree src, JTree dst, DblTreeNode node) { |
|
285 |
|
286 DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); |
|
287 DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); |
|
288 DblTreeNode parent, newparent, clonedParent, root; |
|
289 int index = 0; |
|
290 root = (DblTreeNode)dstModel.getRoot(); |
|
291 int limit = dstModel.getChildCount(root); |
|
292 |
|
293 if (dst == dstTree) { |
|
294 srcModel.removeNodeFromParent(node); |
|
295 dstModel.insertNodeInto(node, root, limit); |
|
296 } else { |
|
297 Enumeration kids = root.children(); |
|
298 index = matchChild(src, dst, node, root, kids, index); |
|
299 } |
|
300 |
|
301 TreePath nodepath = new TreePath(node.getPath()); |
|
302 dst.scrollPathToVisible(nodepath); |
|
303 } |
|
304 |
|
305 |
|
306 public void reorder(JTree dst, int delta) { |
|
307 |
|
308 DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); |
|
309 DblTreeNode dstRoot = (DblTreeNode)dstModel.getRoot(); |
|
310 DblTreeNode node; |
|
311 |
|
312 TreePath selPath = dst.getSelectionPath(); |
|
313 if (selPath == null) // nothing selected (should be disabled) |
|
314 return; |
|
315 |
|
316 node = (DblTreeNode)selPath.getLastPathComponent(); |
|
317 int index = dstModel.getIndexOfChild(dstRoot, node); |
|
318 int limit = dstModel.getChildCount(dstRoot); |
|
319 index += delta; |
|
320 |
|
321 if ((index < 0) || (index >= limit)) |
|
322 return; |
|
323 |
|
324 boolean expanded = dst.isExpanded(selPath); |
|
325 dst.clearSelection(); |
|
326 |
|
327 dstModel.removeNodeFromParent(node); |
|
328 dstModel.insertNodeInto(node, dstRoot, index); |
|
329 |
|
330 TreePath nodepath = new TreePath(node.getPath()); |
|
331 if (expanded) |
|
332 dst.expandPath(nodepath); |
|
333 |
|
334 dst.setSelectionPath(nodepath); |
|
335 dst.scrollPathToVisible(nodepath); |
|
336 |
|
337 if (index > 0) |
|
338 moveUpItem.setEnabled(true); |
|
339 else |
|
340 moveUpItem.setEnabled(false); |
|
341 |
|
342 if (index < (limit - 1)) |
|
343 moveDownItem.setEnabled(true); |
|
344 else |
|
345 moveDownItem.setEnabled(false); |
|
346 |
|
347 } |
|
348 |
|
349 /** |
|
350 * Set the focus listeners for the components in the selector panel that |
|
351 * can have unique help that may be context-specific. Client apps |
|
352 * should call this method after the Arranger is created, but |
|
353 * before the dialog is shown. Any of the listener arguments can be |
|
354 * null, if the client app can accept the default help for the particular |
|
355 * component. |
|
356 * |
|
357 * @param upButtonListener listener for the move-up button |
|
358 * @param downButtonListener listener for the move-down button |
|
359 * @see ContextHelpListener |
|
360 */ |
|
361 public void setFocusListeners( |
|
362 FocusListener upButtonListener, |
|
363 FocusListener downButtonListener) { |
|
364 |
|
365 if (upButtonListener != null) |
|
366 moveUpItem.addFocusListener(upButtonListener); |
|
367 |
|
368 if (downButtonListener != null) |
|
369 moveDownItem.addFocusListener(downButtonListener); |
|
370 |
|
371 } // setFocusListeners |
|
372 |
|
373 public void resetModels() { |
|
374 srcTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items"))); |
|
375 dstTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items"))); |
|
376 } |
|
377 } |