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) 2010, 2012, Oracle and/or its affiliates. All rights reserved. |
|
24 */ |
|
25 |
|
26 package com.oracle.solaris.vp.panel.swing.smf; |
|
27 |
|
28 import java.awt.*; |
|
29 import java.awt.event.*; |
|
30 import javax.swing.*; |
|
31 import javax.swing.event.*; |
|
32 import com.oracle.solaris.vp.util.misc.finder.Finder; |
|
33 import com.oracle.solaris.vp.util.swing.*; |
|
34 import com.oracle.solaris.vp.util.swing.event.ChangeListeners; |
|
35 import com.oracle.solaris.vp.util.swing.layout.*; |
|
36 |
|
37 @SuppressWarnings({"serial"}) |
|
38 public abstract class ComponentList<C extends Component> extends JPanel { |
|
39 // |
|
40 // Inner classes |
|
41 // |
|
42 |
|
43 private class ComponentListItem extends CollapsiblePane { |
|
44 // |
|
45 // Instance data |
|
46 // |
|
47 |
|
48 private boolean remove; |
|
49 private JMenuItem removeItem; |
|
50 |
|
51 // |
|
52 // Constructors |
|
53 // |
|
54 |
|
55 public ComponentListItem(Component comp) { |
|
56 super(comp); |
|
57 setOpaque(false); |
|
58 |
|
59 JMenuItem addItem = new JMenuItem(Finder.getString( |
|
60 "service.settings.menu.add")); |
|
61 |
|
62 addItem.addActionListener( |
|
63 new ActionListener() { |
|
64 @Override |
|
65 public void actionPerformed(ActionEvent e) { |
|
66 ComponentList list = ComponentList.this; |
|
67 Component[] comps = list.getComponents(); |
|
68 int index; |
|
69 for (index = comps.length - 1; index >= 0; index--) { |
|
70 if (comps[index] == ComponentListItem.this) { |
|
71 break; |
|
72 } |
|
73 } |
|
74 |
|
75 list.add(index + 1); |
|
76 } |
|
77 }); |
|
78 |
|
79 removeItem = new JMenuItem(Finder.getString( |
|
80 "service.settings.menu.remove")); |
|
81 |
|
82 removeItem.addActionListener( |
|
83 new ActionListener() { |
|
84 @Override |
|
85 public void actionPerformed(ActionEvent e) { |
|
86 if (ComponentList.this.getComponentCount() > 1) { |
|
87 // Mark for removal |
|
88 remove = true; |
|
89 setCollapsed(true); |
|
90 } |
|
91 } |
|
92 }); |
|
93 |
|
94 JPopupMenu menu = new JPopupMenu(); |
|
95 menu.add(addItem); |
|
96 menu.add(removeItem); |
|
97 setComponentPopupMenu(menu); |
|
98 } |
|
99 |
|
100 // |
|
101 // CollapsiblePane methods |
|
102 // |
|
103 |
|
104 @Override |
|
105 public void end() { |
|
106 if (remove) { |
|
107 Container parent = getParent(); |
|
108 if (parent != null) { |
|
109 parent.remove(this); |
|
110 } |
|
111 } |
|
112 } |
|
113 } |
|
114 |
|
115 // |
|
116 // Instance data |
|
117 // |
|
118 |
|
119 private ChangeListeners listeners = new ChangeListeners(); |
|
120 |
|
121 // |
|
122 // Constructors |
|
123 // |
|
124 |
|
125 public ComponentList(LayoutManager layout) { |
|
126 super(layout); |
|
127 setOpaque(false); |
|
128 |
|
129 JMenuItem addItem = new JMenuItem(Finder.getString( |
|
130 "service.settings.menu.add")); |
|
131 |
|
132 addItem.addActionListener( |
|
133 new ActionListener() { |
|
134 @Override |
|
135 public void actionPerformed(ActionEvent e) { |
|
136 add(0); |
|
137 } |
|
138 }); |
|
139 |
|
140 JPopupMenu menu = new JPopupMenu(); |
|
141 menu.add(addItem); |
|
142 setComponentPopupMenu(menu); |
|
143 |
|
144 addContainerListener( |
|
145 new ContainerAdapter() { |
|
146 @Override |
|
147 public void componentAdded(ContainerEvent e) { |
|
148 setRemoveMenuItemEnabled(); |
|
149 fireStateChanged(); |
|
150 } |
|
151 |
|
152 @Override |
|
153 public void componentRemoved(ContainerEvent e) { |
|
154 Component comp = e.getChild(); |
|
155 try { |
|
156 ComponentListItem item = (ComponentListItem)comp; |
|
157 @SuppressWarnings({"unchecked"}) |
|
158 C view = (C)item.getView(); |
|
159 disposeListComponent(view); |
|
160 } catch (ClassCastException ignore) { |
|
161 } |
|
162 |
|
163 setRemoveMenuItemEnabled(); |
|
164 fireStateChanged(); |
|
165 } |
|
166 }); |
|
167 } |
|
168 |
|
169 public ComponentList(int gap) { |
|
170 this(createDefaultLayout(gap)); |
|
171 } |
|
172 |
|
173 public ComponentList() { |
|
174 this(GUIUtil.getHalfGap()); |
|
175 } |
|
176 |
|
177 // |
|
178 // Container methods |
|
179 // |
|
180 |
|
181 @Override |
|
182 public ComponentListItem add(Component comp) { |
|
183 return add(comp, getComponentCount()); |
|
184 } |
|
185 |
|
186 @Override |
|
187 public ComponentListItem add(Component comp, int index) { |
|
188 ComponentListItem item = createItem(comp); |
|
189 item.setCollapsed(true); |
|
190 super.add(item, index); |
|
191 item.setCollapsed(false); |
|
192 return item; |
|
193 } |
|
194 |
|
195 // |
|
196 // ComponentList methods |
|
197 // |
|
198 |
|
199 public void add() { |
|
200 int index = getComponentCount(); |
|
201 add(createListComponent(index), index); |
|
202 } |
|
203 |
|
204 public void add(int index) { |
|
205 add(createListComponent(index), index); |
|
206 } |
|
207 |
|
208 public void addChangeListener(ChangeListener listener) { |
|
209 listeners.add(listener); |
|
210 } |
|
211 |
|
212 protected abstract C createListComponent(int index); |
|
213 |
|
214 protected void disposeListComponent(C comp) { |
|
215 } |
|
216 |
|
217 protected void fireStateChanged() { |
|
218 ChangeEvent e = new ChangeEvent(this); |
|
219 listeners.stateChanged(e); |
|
220 } |
|
221 |
|
222 @SuppressWarnings({"unchecked"}) |
|
223 protected C getListComponent(int index) { |
|
224 ComponentListItem item = (ComponentListItem)getComponent(index); |
|
225 return (C)item.getView(); |
|
226 } |
|
227 |
|
228 public void removeChangeListener(ChangeListener listener) { |
|
229 listeners.remove(listener); |
|
230 } |
|
231 |
|
232 protected void setRemoveMenuItemEnabled() { |
|
233 Component[] comps = getComponents(); |
|
234 boolean enabled = comps.length > 1; |
|
235 for (Component comp : comps) { |
|
236 ((ComponentListItem)comp).removeItem.setEnabled(enabled); |
|
237 } |
|
238 } |
|
239 |
|
240 // |
|
241 // Private methods |
|
242 // |
|
243 |
|
244 private ComponentListItem createItem(Component comp) { |
|
245 if (comp instanceof JComponent) { |
|
246 JComponent jComp = (JComponent)comp; |
|
247 if (!jComp.getInheritsPopupMenu() && |
|
248 jComp.getComponentPopupMenu() == null) { |
|
249 jComp.setInheritsPopupMenu(true); |
|
250 } |
|
251 } |
|
252 return new ComponentListItem(comp); |
|
253 } |
|
254 |
|
255 // |
|
256 // Static methods |
|
257 // |
|
258 |
|
259 private static LayoutManager createDefaultLayout(int gap) { |
|
260 ColumnLayout layout = new ColumnLayout(VerticalAnchor.FILL); |
|
261 |
|
262 ColumnLayoutConstraint c = new ColumnLayoutConstraint( |
|
263 HorizontalAnchor.FILL, gap); |
|
264 |
|
265 layout.setDefaultConstraint(c); |
|
266 |
|
267 return layout; |
|
268 } |
|
269 } |
|