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<String> list; 63 64 JPanel prefixList; 65 JPanel suffixList; 66 67 Action prefixAction; 68 Action suffixAction; 69 70 GeneratedListModel listModel; 71 72 Vector<JCheckBox> checkboxes = new Vector<>(); 73 74 /** 75 * main method allows us to run as a standalone demo. 76 */ 77 public static void main(String[] args) { 78 ListDemo demo = new ListDemo(null); 79 demo.mainImpl(); 80 } 81 82 /** 83 * ListDemo Constructor 84 */ 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 177 void updateDragEnabled(boolean dragEnabled) { 178 list.setDragEnabled(dragEnabled); 179 } 180 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 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 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; 265 protected UpdatePrefixListAction(GeneratedListModel listModel) { 266 this.listModel = listModel; 267 } 268 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; 281 protected UpdateSuffixListAction(GeneratedListModel listModel) { 282 this.listModel = listModel; 283 } 284 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<String> { 297 ListDemo demo; 298 Permuter permuter; 299 300 public Vector<String> prefix = new Vector<>(); 301 public Vector<String> suffix = new Vector<>(); 302 303 public GeneratedListModel (ListDemo demo) { 304 this.demo = demo; 305 } 306 307 private void update() { 308 permuter = new Permuter(getSize()); 309 fireContentsChanged(this, 0, getSize()); 310 } 311 312 public void addPrefix(String s) { 313 if(!prefix.contains(s)) { 314 prefix.addElement(s); 315 update(); 316 } 317 } 318 319 public void removePrefix(String s) { 320 prefix.removeElement(s); 321 update(); 322 } 323 324 public void addSuffix(String s) { 325 if(!suffix.contains(s)) { 326 suffix.addElement(s); 327 update(); 328 } 329 } 330 331 public void removeSuffix(String s) { 332 suffix.removeElement(s); 333 update(); 334 } 335 336 public int getSize() { 337 return prefix.size() * suffix.size(); 338 } 339 340 public String 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]; 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 { 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 }