|
1 /* |
|
2 * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 package com.sun.swingset3.demos.list; |
|
24 |
|
25 import java.awt.*; |
|
26 import java.awt.event.ActionEvent; |
|
27 import java.awt.event.FocusAdapter; |
|
28 import java.awt.event.FocusEvent; |
|
29 import java.awt.event.FocusListener; |
|
30 import java.util.Vector; |
|
31 import javax.swing.*; |
|
32 |
|
33 import com.sun.swingset3.DemoProperties; |
|
34 import com.sun.swingset3.demos.ResourceManager; |
|
35 |
|
36 /** |
|
37 * List Demo. This demo shows that it is not always necessary to have an array |
|
38 * of objects as big as the size of the list stored. |
|
39 * |
|
40 * Indeed, in this example, there is no array kept for the list data, rather it |
|
41 * is generated on the fly as only those elements are needed. |
|
42 * |
|
43 * @version 1.17 11/17/05 |
|
44 * @author Jeff Dinkins |
|
45 */ |
|
46 @DemoProperties( |
|
47 value = "JList Demo", |
|
48 category = "Data", |
|
49 description = "Demonstrates JList, a component which supports display/editing of a data list", |
|
50 sourceFiles = { |
|
51 "com/sun/swingset3/demos/list/ListDemo.java", |
|
52 "com/sun/swingset3/demos/list/Permuter.java", |
|
53 "com/sun/swingset3/demos/ResourceManager.java", |
|
54 "com/sun/swingset3/demos/list/resources/ListDemo.properties", |
|
55 "com/sun/swingset3/demos/list/resources/images/blue.gif", |
|
56 "com/sun/swingset3/demos/list/resources/images/cyan.gif", |
|
57 "com/sun/swingset3/demos/list/resources/images/gray.gif", |
|
58 "com/sun/swingset3/demos/list/resources/images/green.gif", |
|
59 "com/sun/swingset3/demos/list/resources/images/ListDemo.gif", |
|
60 "com/sun/swingset3/demos/list/resources/images/magenta.gif", |
|
61 "com/sun/swingset3/demos/list/resources/images/red.gif", |
|
62 "com/sun/swingset3/demos/list/resources/images/yellow.gif" |
|
63 } |
|
64 ) |
|
65 public final class ListDemo extends JPanel { |
|
66 |
|
67 private static final Dimension HGAP10 = new Dimension(10, 1); |
|
68 private static final Dimension VGAP10 = new Dimension(1, 10); |
|
69 private static final Dimension HGAP15 = new Dimension(15, 1); |
|
70 private static final Dimension HGAP30 = new Dimension(30, 1); |
|
71 |
|
72 private final ResourceManager resourceManager = new ResourceManager(this.getClass()); |
|
73 public static final String DEMO_TITLE = ListDemo.class.getAnnotation(DemoProperties.class).value(); |
|
74 |
|
75 private final JList<String> list; |
|
76 |
|
77 private JPanel prefixList; |
|
78 private JPanel suffixList; |
|
79 |
|
80 private Action prefixAction; |
|
81 private Action suffixAction; |
|
82 |
|
83 private final GeneratedListModel listModel; |
|
84 |
|
85 /** |
|
86 * main method allows us to run as a standalone demo. |
|
87 * |
|
88 * @param args |
|
89 */ |
|
90 public static void main(String[] args) { |
|
91 JFrame frame = new JFrame(DEMO_TITLE); |
|
92 |
|
93 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|
94 frame.getContentPane().add(new ListDemo()); |
|
95 frame.setPreferredSize(new Dimension(800, 600)); |
|
96 frame.pack(); |
|
97 frame.setLocationRelativeTo(null); |
|
98 frame.setVisible(true); |
|
99 } |
|
100 |
|
101 /** |
|
102 * ListDemo Constructor |
|
103 */ |
|
104 public ListDemo() { |
|
105 setLayout(new BorderLayout()); |
|
106 |
|
107 loadImages(); |
|
108 |
|
109 JLabel description = new JLabel(resourceManager.getString("ListDemo.description")); |
|
110 add(description, BorderLayout.NORTH); |
|
111 |
|
112 JPanel centerPanel = new JPanel(); |
|
113 centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS)); |
|
114 centerPanel.add(Box.createRigidArea(HGAP10)); |
|
115 add(centerPanel, BorderLayout.CENTER); |
|
116 |
|
117 JPanel listPanel = new JPanel(); |
|
118 listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS)); |
|
119 listPanel.add(Box.createRigidArea(VGAP10)); |
|
120 |
|
121 centerPanel.add(listPanel); |
|
122 centerPanel.add(Box.createRigidArea(HGAP30)); |
|
123 |
|
124 // Create the list |
|
125 list = new JList<>(); |
|
126 list.setCellRenderer(new CompanyLogoListCellRenderer()); |
|
127 listModel = new GeneratedListModel(); |
|
128 list.setModel(listModel); |
|
129 |
|
130 // Set the preferred row count. This affects the preferredSize |
|
131 // of the JList when it's in a scrollpane. |
|
132 list.setVisibleRowCount(22); |
|
133 |
|
134 // Add list to a scrollpane |
|
135 JScrollPane scrollPane = new JScrollPane(list); |
|
136 listPanel.add(scrollPane); |
|
137 listPanel.add(Box.createRigidArea(VGAP10)); |
|
138 |
|
139 // Add the control panel (holds the prefix/suffix list and prefix/suffix checkboxes) |
|
140 centerPanel.add(createControlPanel()); |
|
141 |
|
142 // create prefixes and suffixes |
|
143 addPrefix("Tera", true); |
|
144 addPrefix("Micro", false); |
|
145 addPrefix("Southern", false); |
|
146 addPrefix("Net", true); |
|
147 addPrefix("YoYo", true); |
|
148 addPrefix("Northern", false); |
|
149 addPrefix("Tele", false); |
|
150 addPrefix("Eastern", false); |
|
151 addPrefix("Neo", false); |
|
152 addPrefix("Digi", false); |
|
153 addPrefix("National", false); |
|
154 addPrefix("Compu", true); |
|
155 addPrefix("Meta", true); |
|
156 addPrefix("Info", false); |
|
157 addPrefix("Western", false); |
|
158 addPrefix("Data", false); |
|
159 addPrefix("Atlantic", false); |
|
160 addPrefix("Advanced", false); |
|
161 addPrefix("Euro", false); |
|
162 addPrefix("Pacific", false); |
|
163 addPrefix("Mobile", false); |
|
164 addPrefix("In", false); |
|
165 addPrefix("Computa", false); |
|
166 addPrefix("Digital", false); |
|
167 addPrefix("Analog", false); |
|
168 |
|
169 addSuffix("Tech", true); |
|
170 addSuffix("Soft", true); |
|
171 addSuffix("Telecom", true); |
|
172 addSuffix("Solutions", false); |
|
173 addSuffix("Works", true); |
|
174 addSuffix("Dyne", false); |
|
175 addSuffix("Services", false); |
|
176 addSuffix("Vers", false); |
|
177 addSuffix("Devices", false); |
|
178 addSuffix("Software", false); |
|
179 addSuffix("Serv", false); |
|
180 addSuffix("Systems", true); |
|
181 addSuffix("Dynamics", true); |
|
182 addSuffix("Net", false); |
|
183 addSuffix("Sys", false); |
|
184 addSuffix("Computing", false); |
|
185 addSuffix("Scape", false); |
|
186 addSuffix("Com", false); |
|
187 addSuffix("Ware", false); |
|
188 addSuffix("Widgets", false); |
|
189 addSuffix("Media", false); |
|
190 addSuffix("Computer", false); |
|
191 addSuffix("Hardware", false); |
|
192 addSuffix("Gizmos", false); |
|
193 addSuffix("Concepts", false); |
|
194 } |
|
195 |
|
196 private JPanel createControlPanel() { |
|
197 JPanel controlPanel = new JPanel() { |
|
198 private final Insets insets = new Insets(0, 4, 10, 10); |
|
199 |
|
200 @Override |
|
201 public Insets getInsets() { |
|
202 return insets; |
|
203 } |
|
204 }; |
|
205 controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS)); |
|
206 |
|
207 JPanel prefixPanel = new JPanel(); |
|
208 prefixPanel.setLayout(new BoxLayout(prefixPanel, BoxLayout.Y_AXIS)); |
|
209 prefixPanel.add(new JLabel(resourceManager.getString("ListDemo.prefixes"))); |
|
210 |
|
211 JPanel suffixPanel = new JPanel(); |
|
212 suffixPanel.setLayout(new BoxLayout(suffixPanel, BoxLayout.Y_AXIS)); |
|
213 suffixPanel.add(new JLabel(resourceManager.getString("ListDemo.suffixes"))); |
|
214 |
|
215 prefixList = new JPanel() { |
|
216 private final Insets insets = new Insets(0, 4, 0, 0); |
|
217 |
|
218 @Override |
|
219 public Insets getInsets() { |
|
220 return insets; |
|
221 } |
|
222 }; |
|
223 prefixList.setLayout(new BoxLayout(prefixList, BoxLayout.Y_AXIS)); |
|
224 JScrollPane scrollPane = new JScrollPane(prefixList); |
|
225 scrollPane.getVerticalScrollBar().setUnitIncrement(10); |
|
226 prefixPanel.add(scrollPane); |
|
227 prefixPanel.add(Box.createRigidArea(HGAP10)); |
|
228 |
|
229 suffixList = new JPanel() { |
|
230 private final Insets insets = new Insets(0, 4, 0, 0); |
|
231 |
|
232 @Override |
|
233 public Insets getInsets() { |
|
234 return insets; |
|
235 } |
|
236 }; |
|
237 suffixList.setLayout(new BoxLayout(suffixList, BoxLayout.Y_AXIS)); |
|
238 scrollPane = new JScrollPane(suffixList); |
|
239 scrollPane.getVerticalScrollBar().setUnitIncrement(10); |
|
240 suffixPanel.add(scrollPane); |
|
241 suffixPanel.add(Box.createRigidArea(HGAP10)); |
|
242 |
|
243 controlPanel.add(prefixPanel); |
|
244 controlPanel.add(Box.createRigidArea(HGAP15)); |
|
245 controlPanel.add(suffixPanel); |
|
246 return controlPanel; |
|
247 } |
|
248 |
|
249 private final FocusListener listFocusListener = new FocusAdapter() { |
|
250 @Override |
|
251 public void focusGained(FocusEvent e) { |
|
252 JComponent c = (JComponent) e.getComponent(); |
|
253 c.scrollRectToVisible(new Rectangle(0, 0, c.getWidth(), c.getHeight())); |
|
254 } |
|
255 }; |
|
256 |
|
257 private void addPrefix(String prefix, boolean selected) { |
|
258 if (prefixAction == null) { |
|
259 prefixAction = new UpdatePrefixListAction(listModel); |
|
260 } |
|
261 final JCheckBox cb = (JCheckBox) prefixList.add(new JCheckBox(prefix)); |
|
262 cb.setSelected(selected); |
|
263 cb.addActionListener(prefixAction); |
|
264 if (selected) { |
|
265 listModel.addPrefix(prefix); |
|
266 } |
|
267 cb.addFocusListener(listFocusListener); |
|
268 } |
|
269 |
|
270 private void addSuffix(String suffix, boolean selected) { |
|
271 if (suffixAction == null) { |
|
272 suffixAction = new UpdateSuffixListAction(listModel); |
|
273 } |
|
274 final JCheckBox cb = (JCheckBox) suffixList.add(new JCheckBox(suffix)); |
|
275 cb.setSelected(selected); |
|
276 cb.addActionListener(suffixAction); |
|
277 if (selected) { |
|
278 listModel.addSuffix(suffix); |
|
279 } |
|
280 cb.addFocusListener(listFocusListener); |
|
281 } |
|
282 |
|
283 private static class UpdatePrefixListAction extends AbstractAction { |
|
284 |
|
285 private final GeneratedListModel listModel; |
|
286 |
|
287 protected UpdatePrefixListAction(GeneratedListModel listModel) { |
|
288 this.listModel = listModel; |
|
289 } |
|
290 |
|
291 @Override |
|
292 public void actionPerformed(ActionEvent e) { |
|
293 JCheckBox cb = (JCheckBox) e.getSource(); |
|
294 if (cb.isSelected()) { |
|
295 listModel.addPrefix(cb.getText()); |
|
296 } else { |
|
297 listModel.removePrefix(cb.getText()); |
|
298 } |
|
299 } |
|
300 } |
|
301 |
|
302 private static class UpdateSuffixListAction extends AbstractAction { |
|
303 |
|
304 private final GeneratedListModel listModel; |
|
305 |
|
306 protected UpdateSuffixListAction(GeneratedListModel listModel) { |
|
307 this.listModel = listModel; |
|
308 } |
|
309 |
|
310 @Override |
|
311 public void actionPerformed(ActionEvent e) { |
|
312 JCheckBox cb = (JCheckBox) e.getSource(); |
|
313 if (cb.isSelected()) { |
|
314 listModel.addSuffix(cb.getText()); |
|
315 } else { |
|
316 listModel.removeSuffix(cb.getText()); |
|
317 } |
|
318 } |
|
319 } |
|
320 |
|
321 private static class GeneratedListModel extends AbstractListModel<String> { |
|
322 |
|
323 private Permuter permuter; |
|
324 |
|
325 private final Vector<String> prefix = new Vector<>(); |
|
326 private final Vector<String> suffix = new Vector<>(); |
|
327 |
|
328 private void update() { |
|
329 permuter = new Permuter(getSize()); |
|
330 fireContentsChanged(this, 0, getSize()); |
|
331 } |
|
332 |
|
333 public void addPrefix(String s) { |
|
334 if (!prefix.contains(s)) { |
|
335 prefix.addElement(s); |
|
336 update(); |
|
337 } |
|
338 } |
|
339 |
|
340 public void removePrefix(String s) { |
|
341 prefix.removeElement(s); |
|
342 update(); |
|
343 } |
|
344 |
|
345 public void addSuffix(String s) { |
|
346 if (!suffix.contains(s)) { |
|
347 suffix.addElement(s); |
|
348 update(); |
|
349 } |
|
350 } |
|
351 |
|
352 public void removeSuffix(String s) { |
|
353 suffix.removeElement(s); |
|
354 update(); |
|
355 } |
|
356 |
|
357 @Override |
|
358 public int getSize() { |
|
359 return prefix.size() * suffix.size(); |
|
360 } |
|
361 |
|
362 @Override |
|
363 public String getElementAt(int index) { |
|
364 if (permuter == null) { |
|
365 update(); |
|
366 } |
|
367 // morph the index to another int -- this has the benefit of |
|
368 // causing the list to look random. |
|
369 int j = permuter.map(index); |
|
370 int ps = prefix.size(); |
|
371 int ss = suffix.size(); |
|
372 return prefix.elementAt(j % ps) + suffix.elementAt((j / ps) % ss); |
|
373 } |
|
374 } |
|
375 |
|
376 private final ImageIcon[] images = new ImageIcon[7]; |
|
377 |
|
378 void loadImages() { |
|
379 images[0] = resourceManager.createImageIcon("red.gif", resourceManager.getString("ListDemo.red")); |
|
380 images[1] = resourceManager.createImageIcon("blue.gif", resourceManager.getString("ListDemo.blue")); |
|
381 images[2] = resourceManager.createImageIcon("yellow.gif", resourceManager.getString("ListDemo.yellow")); |
|
382 images[3] = resourceManager.createImageIcon("green.gif", resourceManager.getString("ListDemo.green")); |
|
383 images[4] = resourceManager.createImageIcon("gray.gif", resourceManager.getString("ListDemo.gray")); |
|
384 images[5] = resourceManager.createImageIcon("cyan.gif", resourceManager.getString("ListDemo.cyan")); |
|
385 images[6] = resourceManager.createImageIcon("magenta.gif", resourceManager.getString("ListDemo.magenta")); |
|
386 } |
|
387 |
|
388 private class CompanyLogoListCellRenderer extends DefaultListCellRenderer { |
|
389 |
|
390 @Override |
|
391 public Component getListCellRendererComponent( |
|
392 JList<?> list, |
|
393 Object value, |
|
394 int index, |
|
395 boolean isSelected, |
|
396 boolean cellHasFocus) { |
|
397 Component retValue = super.getListCellRendererComponent( |
|
398 list, value, index, isSelected, cellHasFocus |
|
399 ); |
|
400 setIcon(images[index % 7]); |
|
401 return retValue; |
|
402 } |
|
403 } |
|
404 } |