ListDemo.java revision 13978:1993af50385d
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 */ 23package com.sun.swingset3.demos.list; 24 25import java.awt.*; 26import java.awt.event.ActionEvent; 27import java.awt.event.FocusAdapter; 28import java.awt.event.FocusEvent; 29import java.awt.event.FocusListener; 30import java.util.Vector; 31import javax.swing.*; 32 33import com.sun.swingset3.DemoProperties; 34import 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) 65public 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} 405