/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.controls; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import org.opensourcephysics.tools.FontSizer; /** * This modal dialog lets the user choose any number of items * from a supplied list. Items not selected are removed from the list. */ public class ListChooser extends JDialog { // instance fields private JPanel checkPane = new JPanel(); private Object[] objects; private boolean[] selections; private JCheckBox[] checkBoxes; private JLabel instructions; private boolean applyChanges = false; private String separator = ": "; //$NON-NLS-1$ private Font lightFont; /** * Constructs a dialog with the specified title and text. * * @param title the title of the dialog * @param text the label text */ public ListChooser(String title, String text) { this(title, text, (JDialog)null); } /** * Constructs a dialog with the specified title, text and owner. * * @param title the title of the dialog * @param text the label text * @param owner the component that owns the dialog (may be null) */ public ListChooser(String title, String text, Component owner) { super(JOptionPane.getFrameForComponent(owner), true); setTitle(title); instructions = new JLabel(" "+text); //$NON-NLS-1$ instructions.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 6)); createGUI(); } /** * Constructs a dialog with the specified title, text and owner. * * @param title the title of the dialog * @param text the label text * @param owner the component that owns the dialog (may be null) */ public ListChooser(String title, String text, JDialog owner) { super(owner, true); setTitle(title); instructions = new JLabel(" "+text); //$NON-NLS-1$ instructions.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 6)); createGUI(); } /** * Creates the GUI. */ private void createGUI() { // create the light font lightFont = new JLabel().getFont().deriveFont(Font.PLAIN); // create the buttons JButton cancelButton = new JButton(ControlsRes.getString("Chooser.Button.Cancel")); //$NON-NLS-1$ JButton okButton = new JButton(ControlsRes.getString("Chooser.Button.OK")); //$NON-NLS-1$ JButton selectAllButton = new JButton(ControlsRes.getString("Chooser.Button.SelectAll")); //$NON-NLS-1$ cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); } }); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { for(int i = 0; i<checkBoxes.length; i++) { selections[i] = checkBoxes[i].isSelected(); } applyChanges = true; setVisible(false); } }); selectAllButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { for(int i = 0; i<checkBoxes.length; i++) { checkBoxes[i].setSelected(true); } } }); getRootPane().setDefaultButton(okButton); // lay out the header pane JPanel headerPane = new JPanel(); headerPane.setLayout(new BoxLayout(headerPane, BoxLayout.X_AXIS)); headerPane.add(instructions); headerPane.add(Box.createHorizontalGlue()); headerPane.add(selectAllButton); headerPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); // lay out the scroll pane checkPane.setLayout(new BoxLayout(checkPane, BoxLayout.Y_AXIS)); checkPane.setBackground(Color.white); JScrollPane scroller = new JScrollPane(checkPane); scroller.setPreferredSize(new Dimension(250, 180)); JPanel scrollPane = new JPanel(new BorderLayout()); scrollPane.add(scroller, BorderLayout.CENTER); scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // lay out the button pane JPanel buttonPane = new JPanel(); buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); buttonPane.add(Box.createHorizontalGlue()); buttonPane.add(okButton); buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); buttonPane.add(cancelButton); // add everything to the content pane Container contentPane = getContentPane(); contentPane.add(headerPane, BorderLayout.NORTH); contentPane.add(scrollPane, BorderLayout.CENTER); contentPane.add(buttonPane, BorderLayout.SOUTH); pack(); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); Rectangle rect = new Rectangle(dim); if (getOwner()!=null) { rect = getOwner().getBounds(); } int x = rect.x+(rect.width-this.getBounds().width)/2; int y = rect.y+(rect.height-this.getBounds().height)/2; setLocation(x, y); } public void setSeparator(String separator) { if (separator!=null) { this.separator = separator; } } /** * Allows the user to choose from the supplied list. Items not selected are * removed from the list. * * @param choices a collection of objects to choose from * @param names an optional collection of descriptive names * @return <code>true</code> if OK button was clicked */ public boolean choose(Collection<?> choices, Collection<String> names) { return choose(choices, names, null); } /** * Allows the user to choose from the supplied list. Items not selected are * removed from the list. * * @param choices a collection of objects to choose from * @param names an optional collection of descriptive names * @param values an optional collection of values * @return <code>true</code> if OK button was clicked */ public boolean choose(Collection<?> choices, Collection<String> names, Collection<?> values) { boolean[] selected = new boolean[choices.size()]; // all false by default return choose(choices, names, values, selected); } /** * Allows the user to choose from the supplied list. Items not selected are * removed from the list. * * @param choices a collection of objects to choose from * @param names an optional collection of descriptive names * @param values an optional collection of values * @param selected an array of initially selected states * @return <code>true</code> if OK button was clicked */ public boolean choose(Collection<?> choices, Collection<String> names, Collection<?> values, boolean[] selected) { boolean[] disabled = new boolean[choices.size()]; // all false by default return choose(choices, names, values, selected, disabled); } /** * Allows the user to choose from the supplied list. Items not selected are * removed from the list. * * @param choices a collection of objects to choose from * @param names an optional collection of descriptive names * @param values an optional collection of values * @param selected an array of initially selected states * @param disabled an array of disabled states (true = disabled) * @return <code>true</code> if OK button was clicked */ public boolean choose(Collection<?> choices, Collection<String> names, Collection<?> values, boolean[] selected, boolean[] disabled) { return choose(choices, names, values, null, selected, disabled); } /** * Allows the user to choose from the supplied list. Items not selected are * removed from the list. * * @param choices a collection of objects to choose from * @param names an optional collection of descriptive names * @param values an optional collection of values * @param descriptions an optional collection of descriptions * @param selected an array of initially selected states * @return <code>true</code> if OK button was clicked */ public boolean choose(Collection<?> choices, Collection<String> names, Collection<?> values, Collection<String> descriptions, boolean[] selected) { boolean[] disabled = new boolean[choices.size()]; // all false by default return choose(choices, names, values, descriptions, selected, disabled); } /** * Allows the user to choose from the supplied list. Items not selected are * removed from the list. * * @param choices a collection of objects to choose from * @param names an optional collection of descriptive names * @param values an optional collection of values * @param descriptions an optional collection of descriptions * @param selected an array of initially selected states * @param disabled an array of disabled states (true = disabled) * @return <code>true</code> if OK button was clicked */ public boolean choose(Collection<?> choices, Collection<String> names, Collection<?> values, Collection<String> descriptions, boolean[] selected, boolean[] disabled) { checkPane.removeAll(); checkBoxes = new JCheckBox[choices.size()]; selections = new boolean[choices.size()]; objects = new Object[choices.size()]; ArrayList<String> nameList = new ArrayList<String>(); if(names!=null) { nameList.addAll(names); } ArrayList<Object> valueList = new ArrayList<Object>(); if(values!=null) { valueList.addAll(values); } ArrayList<String> descriptionList = new ArrayList<String>(); if(descriptions!=null) { descriptionList.addAll(descriptions); } Iterator<?> it = choices.iterator(); int i = 0; while(it.hasNext()) { objects[i] = it.next(); selections[i] = false; if((nameList.size()<=i)||(nameList.get(i)==null)) { checkBoxes[i] = new JCheckBox(objects[i].toString()); } else { String text = nameList.get(i); if (valueList.size()>i && valueList.get(i)!=null) { text += separator+valueList.get(i); } checkBoxes[i] = new JCheckBox(text); } checkBoxes[i].setSelected(selected[i]); checkBoxes[i].setEnabled(!disabled[i]); checkBoxes[i].setBackground(Color.white); checkBoxes[i].setFont(lightFont); checkBoxes[i].setIconTextGap(10); Box box = Box.createHorizontalBox(); box.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 8)); box.add(checkBoxes[i]); box.add(Box.createHorizontalGlue()); checkPane.add(box); if (descriptionList.size()>i && descriptionList.get(i)!=null) { JLabel label = new JLabel(descriptionList.get(i)); label.setFont(lightFont); box.add(label); } i++; } FontSizer.setFonts(this, FontSizer.getLevel()); this.pack(); setVisible(true); if(!applyChanges) { return false; } for(i = 0; i<objects.length; i++) { if(!selections[i]) { choices.remove(objects[i]); } } return true; } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */