1 /*
2  *
3  * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  *   - Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *
12  *   - Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  *
16  *   - Neither the name of Oracle nor the names of its
17  *     contributors may be used to endorse or promote products derived
18  *     from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 
34 import javax.swing.*;
35 import javax.swing.event.*;
36 import javax.swing.text.*;
37 import javax.swing.border.*;
38 import javax.swing.colorchooser.*;
39 import javax.swing.filechooser.*;
40 import javax.accessibility.*;
41 
42 import java.awt.*;
43 import java.awt.event.*;
44 import java.beans.*;
45 import java.util.*;
46 import java.io.*;
47 import java.applet.*;
48 import java.net.*;
49 
50 /**
51  * List Demo. This demo shows that it is not
52  * always necessary to have an array of objects
53  * as big as the size of the list stored.
54  *
55  * Indeed, in this example, there is no array
56  * kept for the list data, rather it is generated
57  * on the fly as only those elements are needed.
58  *
59  * @author Jeff Dinkins
60  */
61 public class ListDemo extends DemoModule {
62     JList list;
63 
64     JPanel prefixList;
65     JPanel suffixList;
66 
67     Action prefixAction;
68     Action suffixAction;
69 
70     GeneratedListModel listModel;
71 
72     Vector checkboxes = new Vector();
73 
74     /**
75      * main method allows us to run as a standalone demo.
76      */
main(String[] args)77     public static void main(String[] args) {
78         ListDemo demo = new ListDemo(null);
79         demo.mainImpl();
80     }
81 
82     /**
83      * ListDemo Constructor
84      */
ListDemo(SwingSet2 swingset)85     public ListDemo(SwingSet2 swingset) {
86         super(swingset, "ListDemo", "toolbar/JList.gif");
87 
88         loadImages();
89 
90         JLabel description = new JLabel(getString("ListDemo.description"));
91         getDemoPanel().add(description, BorderLayout.NORTH);
92 
93         JPanel centerPanel = new JPanel();
94         centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS));
95         centerPanel.add(Box.createRigidArea(HGAP10));
96         getDemoPanel().add(centerPanel, BorderLayout.CENTER);
97 
98         JPanel listPanel = new JPanel();
99         listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
100         listPanel.add(Box.createRigidArea(VGAP10));
101 
102         centerPanel.add(listPanel);
103         centerPanel.add(Box.createRigidArea(HGAP30));
104 
105         // Create the list
106         list = new JList();
107         list.setCellRenderer(new CompanyLogoListCellRenderer());
108         listModel = new GeneratedListModel(this);
109         list.setModel(listModel);
110 
111         // Set the preferred row count. This affects the preferredSize
112         // of the JList when it's in a scrollpane.
113         list.setVisibleRowCount(22);
114 
115         // Add list to a scrollpane
116         JScrollPane scrollPane = new JScrollPane(list);
117         listPanel.add(scrollPane);
118         listPanel.add(Box.createRigidArea(VGAP10));
119 
120         // Add the control panel (holds the prefix/suffix list and prefix/suffix checkboxes)
121         centerPanel.add(createControlPanel());
122 
123         // create prefixes and suffixes
124         addPrefix("Tera", true);
125         addPrefix("Micro", false);
126         addPrefix("Southern", false);
127         addPrefix("Net", true);
128         addPrefix("YoYo", true);
129         addPrefix("Northern", false);
130         addPrefix("Tele", false);
131         addPrefix("Eastern", false);
132         addPrefix("Neo", false);
133         addPrefix("Digi", false);
134         addPrefix("National", false);
135         addPrefix("Compu", true);
136         addPrefix("Meta", true);
137         addPrefix("Info", false);
138         addPrefix("Western", false);
139         addPrefix("Data", false);
140         addPrefix("Atlantic", false);
141         addPrefix("Advanced", false);
142         addPrefix("Euro", false);
143         addPrefix("Pacific", false);
144         addPrefix("Mobile", false);
145         addPrefix("In", false);
146         addPrefix("Computa", false);
147         addPrefix("Digital", false);
148         addPrefix("Analog", false);
149 
150         addSuffix("Tech", true);
151         addSuffix("Soft", true);
152         addSuffix("Telecom", true);
153         addSuffix("Solutions", false);
154         addSuffix("Works", true);
155         addSuffix("Dyne", false);
156         addSuffix("Services", false);
157         addSuffix("Vers", false);
158         addSuffix("Devices", false);
159         addSuffix("Software", false);
160         addSuffix("Serv", false);
161         addSuffix("Systems", true);
162         addSuffix("Dynamics", true);
163         addSuffix("Net", false);
164         addSuffix("Sys", false);
165         addSuffix("Computing", false);
166         addSuffix("Scape", false);
167         addSuffix("Com", false);
168         addSuffix("Ware", false);
169         addSuffix("Widgets", false);
170         addSuffix("Media", false);
171         addSuffix("Computer", false);
172         addSuffix("Hardware", false);
173         addSuffix("Gizmos", false);
174         addSuffix("Concepts", false);
175     }
176 
updateDragEnabled(boolean dragEnabled)177     void updateDragEnabled(boolean dragEnabled) {
178         list.setDragEnabled(dragEnabled);
179     }
180 
createControlPanel()181     public JPanel createControlPanel() {
182         JPanel controlPanel = new JPanel() {
183             Insets insets = new Insets(0, 4, 10, 10);
184             public Insets getInsets() {
185                 return insets;
186             }
187         };
188         controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
189 
190         JPanel prefixPanel = new JPanel();
191         prefixPanel.setLayout(new BoxLayout(prefixPanel, BoxLayout.Y_AXIS));
192         prefixPanel.add(new JLabel(getString("ListDemo.prefixes")));
193 
194         JPanel suffixPanel = new JPanel();
195         suffixPanel.setLayout(new BoxLayout(suffixPanel, BoxLayout.Y_AXIS));
196         suffixPanel.add(new JLabel(getString("ListDemo.suffixes")));
197 
198         prefixList = new JPanel() {
199             Insets insets = new Insets(0, 4, 0, 0);
200             public Insets getInsets() {
201                 return insets;
202             }
203         };
204         prefixList.setLayout(new BoxLayout(prefixList, BoxLayout.Y_AXIS));
205         JScrollPane scrollPane = new JScrollPane(prefixList);
206         scrollPane.getVerticalScrollBar().setUnitIncrement(10);
207         prefixPanel.add(scrollPane);
208         prefixPanel.add(Box.createRigidArea(HGAP10));
209 
210         suffixList = new JPanel() {
211             Insets insets = new Insets(0, 4, 0, 0);
212             public Insets getInsets() {
213                 return insets;
214             }
215         };
216         suffixList.setLayout(new BoxLayout(suffixList, BoxLayout.Y_AXIS));
217         scrollPane = new JScrollPane(suffixList);
218         scrollPane.getVerticalScrollBar().setUnitIncrement(10);
219         suffixPanel.add(scrollPane);
220         suffixPanel.add(Box.createRigidArea(HGAP10));
221 
222         controlPanel.add(prefixPanel);
223         controlPanel.add(Box.createRigidArea(HGAP15));
224         controlPanel.add(suffixPanel);
225         return controlPanel;
226     }
227 
228     private FocusListener listFocusListener = new FocusAdapter() {
229         public void focusGained(FocusEvent e) {
230             JComponent c = (JComponent)e.getComponent();
231             c.scrollRectToVisible(new Rectangle(0, 0, c.getWidth(), c.getHeight()));
232         }
233     };
234 
addPrefix(String prefix, boolean selected)235     public void addPrefix(String prefix, boolean selected) {
236         if(prefixAction == null) {
237             prefixAction = new UpdatePrefixListAction(listModel);
238         }
239         final JCheckBox cb = (JCheckBox) prefixList.add(new JCheckBox(prefix));
240         checkboxes.addElement(cb);
241         cb.setSelected(selected);
242         cb.addActionListener(prefixAction);
243         if(selected) {
244             listModel.addPrefix(prefix);
245         }
246         cb.addFocusListener(listFocusListener);
247     }
248 
addSuffix(String suffix, boolean selected)249     public void addSuffix(String suffix, boolean selected) {
250         if(suffixAction == null) {
251             suffixAction = new UpdateSuffixListAction(listModel);
252         }
253         final JCheckBox cb = (JCheckBox) suffixList.add(new JCheckBox(suffix));
254         checkboxes.addElement(cb);
255         cb.setSelected(selected);
256         cb.addActionListener(suffixAction);
257         if(selected) {
258             listModel.addSuffix(suffix);
259         }
260         cb.addFocusListener(listFocusListener);
261     }
262 
263     class UpdatePrefixListAction extends AbstractAction {
264         GeneratedListModel listModel;
UpdatePrefixListAction(GeneratedListModel listModel)265         protected UpdatePrefixListAction(GeneratedListModel listModel) {
266             this.listModel = listModel;
267         }
268 
actionPerformed(ActionEvent e)269         public void actionPerformed(ActionEvent e) {
270             JCheckBox cb = (JCheckBox) e.getSource();
271             if(cb.isSelected()) {
272                 listModel.addPrefix(cb.getText());
273             } else {
274                 listModel.removePrefix(cb.getText());
275             }
276         }
277     }
278 
279     class UpdateSuffixListAction extends AbstractAction {
280         GeneratedListModel listModel;
UpdateSuffixListAction(GeneratedListModel listModel)281         protected UpdateSuffixListAction(GeneratedListModel listModel) {
282             this.listModel = listModel;
283         }
284 
actionPerformed(ActionEvent e)285         public void actionPerformed(ActionEvent e) {
286             JCheckBox cb = (JCheckBox) e.getSource();
287             if(cb.isSelected()) {
288                 listModel.addSuffix(cb.getText());
289             } else {
290                 listModel.removeSuffix(cb.getText());
291             }
292         }
293     }
294 
295 
296     class GeneratedListModel extends AbstractListModel {
297         ListDemo demo;
298         Permuter permuter;
299 
300         public Vector prefix = new Vector();
301         public Vector suffix = new Vector();
302 
GeneratedListModel(ListDemo demo)303         public GeneratedListModel (ListDemo demo) {
304             this.demo = demo;
305         }
306 
update()307         private void update() {
308             permuter = new Permuter(getSize());
309             fireContentsChanged(this, 0, getSize());
310         }
311 
addPrefix(String s)312         public void addPrefix(String s) {
313             if(!prefix.contains(s)) {
314                 prefix.addElement(s);
315                 update();
316             }
317         }
318 
removePrefix(String s)319         public void removePrefix(String s) {
320             prefix.removeElement(s);
321             update();
322         }
323 
addSuffix(String s)324         public void addSuffix(String s) {
325             if(!suffix.contains(s)) {
326                 suffix.addElement(s);
327                 update();
328             }
329         }
330 
removeSuffix(String s)331         public void removeSuffix(String s) {
332             suffix.removeElement(s);
333             update();
334         }
335 
getSize()336         public int getSize() {
337             return prefix.size() * suffix.size();
338         }
339 
getElementAt(int index)340         public Object getElementAt(int index) {
341             if(permuter == null) {
342                 update();
343             }
344             // morph the index to another int -- this has the benefit of
345             // causing the list to look random.
346             int j = permuter.map(index);
347             int ps = prefix.size();
348             int ss = suffix.size();
349             return (String) prefix.elementAt(j%ps) + (String) suffix.elementAt((j/ps)%ss);
350         }
351     }
352 
353     ImageIcon[] images = new ImageIcon[7];
loadImages()354     void loadImages() {
355             images[0] = createImageIcon("list/red.gif",  getString("ListDemo.red"));
356             images[1] = createImageIcon("list/blue.gif",  getString("ListDemo.blue"));
357             images[2] = createImageIcon("list/yellow.gif",  getString("ListDemo.yellow"));
358             images[3] = createImageIcon("list/green.gif",  getString("ListDemo.green"));
359             images[4] = createImageIcon("list/gray.gif",  getString("ListDemo.gray"));
360             images[5] = createImageIcon("list/cyan.gif",  getString("ListDemo.cyan"));
361             images[6] = createImageIcon("list/magenta.gif",  getString("ListDemo.magenta"));
362     }
363 
364     class CompanyLogoListCellRenderer extends DefaultListCellRenderer {
getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)365        public Component getListCellRendererComponent(
366             JList list,
367             Object value,
368             int index,
369             boolean isSelected,
370             boolean cellHasFocus)
371         {
372             Component retValue = super.getListCellRendererComponent(
373                 list, value, index, isSelected, cellHasFocus
374             );
375             setIcon(images[index%7]);
376             return retValue;
377         }
378     }
379 }
380