Coverage Report - org.argouml.uml.ui.UMLAddDialog
 
Classes in this File Line Coverage Branch Coverage Complexity
UMLAddDialog
0%
0/143
0%
0/50
2.857
UMLAddDialog$1
0%
0/3
N/A
2.857
 
 1  
 /* $Id: UMLAddDialog.java 17881 2010-01-12 21:09:28Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    tfmorris
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2008 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies.  This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.uml.ui;
 40  
 
 41  
 import java.awt.BorderLayout;
 42  
 import java.awt.Component;
 43  
 import java.awt.Container;
 44  
 import java.awt.Dimension;
 45  
 import java.awt.FlowLayout;
 46  
 import java.awt.Frame;
 47  
 import java.awt.event.ActionEvent;
 48  
 import java.awt.event.ActionListener;
 49  
 import java.awt.event.WindowAdapter;
 50  
 import java.awt.event.WindowEvent;
 51  
 import java.util.ArrayList;
 52  
 import java.util.List;
 53  
 import java.util.Vector;
 54  
 
 55  
 import javax.swing.AbstractListModel;
 56  
 import javax.swing.BorderFactory;
 57  
 import javax.swing.Box;
 58  
 import javax.swing.JButton;
 59  
 import javax.swing.JDialog;
 60  
 import javax.swing.JLabel;
 61  
 import javax.swing.JList;
 62  
 import javax.swing.JOptionPane;
 63  
 import javax.swing.JPanel;
 64  
 import javax.swing.JScrollPane;
 65  
 import javax.swing.ListCellRenderer;
 66  
 import javax.swing.ListModel;
 67  
 import javax.swing.ListSelectionModel;
 68  
 import javax.swing.SwingUtilities;
 69  
 import javax.swing.WindowConstants;
 70  
 
 71  
 import org.argouml.application.helpers.ResourceLoaderWrapper;
 72  
 import org.argouml.i18n.Translator;
 73  
 import org.argouml.uml.util.SortedListModel;
 74  
 
 75  
 /**
 76  
  * UMLAddDialog is a modal dialog which allows the user to do a multiple select
 77  
  * from a list of choices. The dialog has two possible uses:
 78  
  * <ol>
 79  
  * <li>As dialog as described above with a custom cellrenderer or a default
 80  
  * cellrenderer.
 81  
  * <li>As dialog with a UMLCellRenderer. Cells in the choices list and selected
 82  
  * list are presented with their name instead of their toString function.
 83  
  * </ol>
 84  
  * <p>
 85  
  * <em>NOTE:</em> An incompatible change to the API contract was made between
 86  
  * 0.24 and 0.26.  A number of internal methods which had public visibility
 87  
  * were made private.
 88  
  */
 89  0
 public class UMLAddDialog extends JPanel implements ActionListener {
 90  
 
 91  
     /**
 92  
      * The GUI list for the choices
 93  
      */
 94  0
     private JList choicesList = null;
 95  
 
 96  
     /**
 97  
      * The GUI list for the selected choices
 98  
      */
 99  0
     private JList selectedList = null;
 100  
 
 101  0
     private JButton addButton = null;
 102  
 
 103  0
     private JButton removeButton = null;
 104  
 
 105  0
     private JButton okButton = null;
 106  
 
 107  0
     private JButton cancelButton = null;
 108  
 
 109  0
     private JDialog dialog = null;
 110  
 
 111  0
     private String title = null;
 112  
 
 113  0
     private boolean multiSelectAllowed = false;
 114  
 
 115  
     /**
 116  
      * The returnvalue of the method showDialog. Returnvalue can be either
 117  
      * JOptionPane.OK_OPTION or JOptionPane.CANCEL_OPTION
 118  
      */
 119  
     private int returnValue;
 120  
 
 121  
     private boolean exclusive;
 122  
 
 123  
     /**
 124  
      * Constructs a UMLAddDialog with a UMLListCellRenderer. Modelelements are
 125  
      * represented with their names in the choices list and the selected list.
 126  
      *
 127  
      * @param theChoices
 128  
      *            A List containing the choices a user has.
 129  
      * @param preselected
 130  
      *            A List containing the preselected choices
 131  
      * @param theTitle
 132  
      *            The title of the dialog
 133  
      * @param multiselectAllowed
 134  
      *            True if the user may select multiple choices
 135  
      * @param isExclusive
 136  
      *            True if choices in the selected list may not appear in the
 137  
      *            choices list. If true preselected choices are removed from the
 138  
      *            choices list.
 139  
      */
 140  
     public UMLAddDialog(final List theChoices, final List preselected,
 141  
             final String theTitle, final boolean multiselectAllowed,
 142  
             final boolean isExclusive) {
 143  0
         this(theChoices, preselected, theTitle, new UMLListCellRenderer2(true),
 144  
                 multiselectAllowed, isExclusive);
 145  0
     }
 146  
 
 147  
     /**
 148  
      * Constructs a UMLAddDialog with a given UMLListCellRenderer.
 149  
      *
 150  
      * @param theChoices
 151  
      *            A List containing the choices a user has.
 152  
      * @param preselected
 153  
      *            A List containing the preselected choices
 154  
      * @param theTitle
 155  
      *            The title of the dialog
 156  
      * @param renderer
 157  
      *            The cellrenderer of the choices list and the selected list
 158  
      * @param multiselectAllowed
 159  
      *            True if the user may select multiple choices
 160  
      * @param isExclusive
 161  
      *            True if choices in the selected list may not appear in the
 162  
      *            choices list. If true preselected choices are removed from the
 163  
      *            choices list.
 164  
      */
 165  
     public UMLAddDialog(final List theChoices, final List preselected,
 166  
             final String theTitle, final ListCellRenderer renderer,
 167  0
             final boolean multiselectAllowed, final boolean isExclusive) {
 168  0
         multiSelectAllowed = multiselectAllowed;
 169  0
         if (theChoices == null) {
 170  0
             throw new IllegalArgumentException(
 171  
                     "There should always be choices in UMLAddDialog");
 172  
         }
 173  0
         exclusive = isExclusive;
 174  0
         List choices = new ArrayList(theChoices);
 175  0
         if (isExclusive && preselected != null && !preselected.isEmpty()) {
 176  0
             choices.removeAll(preselected);
 177  
         }
 178  0
         if (theTitle != null) {
 179  0
             title = theTitle;
 180  
         } else {
 181  0
             title = "";
 182  
         }
 183  
 
 184  0
         setLayout(new BorderLayout());
 185  
 
 186  0
         JPanel upperPanel = new JPanel();
 187  0
         JPanel panelChoices = new JPanel(new BorderLayout());
 188  0
         JPanel panelSelected = new JPanel(new BorderLayout());
 189  
 
 190  0
         choicesList = new JList(constructListModel(choices));
 191  0
         choicesList.setMinimumSize(new Dimension(150, 300));
 192  0
         if (renderer != null) {
 193  0
             choicesList.setCellRenderer(renderer);
 194  
         }
 195  0
         if (multiselectAllowed) {
 196  0
             choicesList.setSelectionMode(
 197  
                     ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 198  
         } else {
 199  0
             choicesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 200  
         }
 201  0
         choicesList.setVisibleRowCount(15);
 202  0
         JScrollPane choicesScroll = new JScrollPane(choicesList);
 203  0
         panelChoices.add(new JLabel(Translator.localize("label.choices")),
 204  
                 BorderLayout.NORTH);
 205  0
         panelChoices.add(choicesScroll, BorderLayout.CENTER);
 206  
 
 207  0
         addButton = new JButton(ResourceLoaderWrapper
 208  
                 .lookupIconResource("NavigateForward"));
 209  0
         addButton.addActionListener(this);
 210  0
         removeButton = new JButton(ResourceLoaderWrapper
 211  
                 .lookupIconResource("NavigateBack"));
 212  0
         removeButton.addActionListener(this);
 213  0
         Box buttonBox = Box.createVerticalBox();
 214  
         // buttonBox.add(Box.createRigidArea(new Dimension(0, 20)));
 215  0
         buttonBox.add(addButton);
 216  0
         buttonBox.add(Box.createRigidArea(new Dimension(0, 5)));
 217  0
         buttonBox.add(removeButton);
 218  
 
 219  0
         selectedList = new JList(constructListModel(preselected));
 220  0
         selectedList.setMinimumSize(new Dimension(150, 300));
 221  0
         if (renderer != null) {
 222  0
             selectedList.setCellRenderer(renderer);
 223  
         }
 224  0
         selectedList
 225  
                 .setSelectionMode(
 226  
                         ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 227  0
         selectedList.setVisibleRowCount(15);
 228  0
         JScrollPane selectedScroll = new JScrollPane(selectedList);
 229  0
         panelSelected.add(new JLabel(Translator.localize("label.selected")),
 230  
                 BorderLayout.NORTH);
 231  0
         panelSelected.add(selectedScroll, BorderLayout.CENTER);
 232  
 
 233  0
         upperPanel.add(panelChoices);
 234  0
         upperPanel.add(Box.createRigidArea(new Dimension(5, 0)));
 235  0
         upperPanel.add(buttonBox);
 236  0
         upperPanel.add(Box.createRigidArea(new Dimension(5, 0)));
 237  0
         upperPanel.add(panelSelected);
 238  
         // upperPanel.setBorder(BorderFactory.createEtchedBorder());
 239  
 
 240  0
         add(upperPanel, BorderLayout.NORTH);
 241  
 
 242  0
         JPanel okCancelPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
 243  
 
 244  0
         okButton = new JButton(Translator.localize("button.ok"));
 245  0
         okButton.addActionListener(this);
 246  0
         cancelButton = new JButton(Translator.localize("button.cancel"));
 247  0
         cancelButton.addActionListener(this);
 248  0
         okCancelPanel.add(okButton);
 249  0
         okCancelPanel.add(cancelButton);
 250  0
         okCancelPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 10));
 251  
 
 252  0
         add(okCancelPanel, BorderLayout.SOUTH);
 253  0
         setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 10));
 254  0
         update();
 255  0
     }
 256  
 
 257  
     /*
 258  
      * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
 259  
      */
 260  
     public void actionPerformed(ActionEvent e) {
 261  0
         Object source = e.getSource();
 262  0
         if (source.equals(addButton)) {
 263  0
             addSelection();
 264  0
             update();
 265  
         }
 266  0
         if (source.equals(removeButton)) {
 267  0
             removeSelection();
 268  0
             update();
 269  
         }
 270  0
         if (source.equals(okButton)) {
 271  0
             ok();
 272  
         }
 273  0
         if (source.equals(cancelButton)) {
 274  0
             cancel();
 275  
         }
 276  0
     }
 277  
 
 278  
     /**
 279  
      * Updates the add and remove button (sets enabled/disabled). Called
 280  
      * whenever the model is changed.
 281  
      */
 282  
     private void update() {
 283  0
         if (choicesList.getModel().getSize() == 0) {
 284  0
             addButton.setEnabled(false);
 285  
         } else {
 286  0
             addButton.setEnabled(true);
 287  
         }
 288  0
         if (selectedList.getModel().getSize() == 0) {
 289  0
             removeButton.setEnabled(false);
 290  
         } else {
 291  0
             removeButton.setEnabled(true);
 292  
         }
 293  0
         if (selectedList.getModel().getSize() > 1 && !multiSelectAllowed) {
 294  0
             addButton.setEnabled(false);
 295  0
             okButton.setEnabled(false);
 296  
         }
 297  
         else {
 298  0
             addButton.setEnabled(true);
 299  0
             okButton.setEnabled(true);
 300  
         }
 301  0
     }
 302  
 
 303  
     /**
 304  
      * Utility method to construct a AbstractListModel from a List
 305  
      * 
 306  
      * @param list the given list
 307  
      * @return AbstractListModel
 308  
      */
 309  
     protected AbstractListModel constructListModel(List list) {
 310  0
         SortedListModel model = new SortedListModel();
 311  0
         if (list != null) {
 312  0
             model.addAll(list);
 313  
         }
 314  0
         return model;
 315  
     }
 316  
 
 317  
     /**
 318  
      * Shows the dialog. First a dialog must be constructed using one of the
 319  
      * constructors of this class. After that this method should be called to
 320  
      * actually show the dialog. This method returns either
 321  
      * JOptionPane.OK_OPTION if the user wants to select his choices or
 322  
      * JOptionPane.CANCEL_OPTION if he does not want to.
 323  
      *
 324  
      * @param parent
 325  
      *            The parent frame of this dialog.
 326  
      * @return int The returnvalue, can be either JOptionPane.OK_OPTION or
 327  
      *         JOptionPane.CANCEL_OPTION
 328  
      */
 329  
     public int showDialog(Component parent) {
 330  0
         Frame frame = parent instanceof Frame ? (Frame) parent
 331  
                 : (Frame) SwingUtilities
 332  
                         .getAncestorOfClass(Frame.class, parent);
 333  
 
 334  
         // String title = getUI().getDialogTitle(this);
 335  
 
 336  0
         dialog = new JDialog(frame, title, true);
 337  0
         Container contentPane = dialog.getContentPane();
 338  0
         contentPane.setLayout(new BorderLayout());
 339  0
         contentPane.add(this, BorderLayout.CENTER);
 340  
 
 341  0
         dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
 342  0
         dialog.addWindowListener(new WindowAdapter() {
 343  
             public void windowClosing(WindowEvent we) {
 344  0
                 cancel();
 345  0
             }
 346  
         });
 347  
 
 348  0
         dialog.pack();
 349  0
         dialog.setLocationRelativeTo(parent);
 350  
 
 351  0
         dialog.setVisible(true);
 352  0
         return returnValue;
 353  
     }
 354  
 
 355  
     /**
 356  
      * Returns the choices a user can make.
 357  
      * @return List of choices
 358  
      */
 359  
     private List getChoices() {
 360  0
         List result = new ArrayList();
 361  0
         for (int index : choicesList.getSelectedIndices()) {
 362  0
             result.add(choicesList.getModel().getElementAt(index));
 363  
         }
 364  0
         return result;
 365  
     }
 366  
     
 367  
     /**
 368  
      * Returns the selected elements in the selected list
 369  
      *
 370  
      * @return List
 371  
      */
 372  
     private List getSelectedChoices() {
 373  0
         List result = new ArrayList();
 374  0
         for (int index : selectedList.getSelectedIndices()) {
 375  0
             result.add(selectedList.getModel().getElementAt(index));
 376  
         }
 377  0
         return result;
 378  
     }
 379  
 
 380  
     /**
 381  
      * Returns the elements of the right-hand "selected" list.  Note
 382  
      * that these are not the elements selected (ie highlighted) in the
 383  
      * Swing sense, but rather the entire contents of the list containing
 384  
      * the user selections.
 385  
      *
 386  
      * @return a Vector of selected elements.
 387  
      */
 388  
     public Vector getSelected() {
 389  0
         Vector result = new Vector();
 390  0
         ListModel list = selectedList.getModel();
 391  0
         for (int i = 0; i < list.getSize(); i++) {
 392  0
             result.add(list.getElementAt(i));
 393  
         }
 394  0
         return result;
 395  
     }
 396  
     
 397  
     /**
 398  
      * Adds the selected elements in the choices list to the selected list.
 399  
      * 
 400  
      */
 401  
     private void addSelection() {
 402  0
         List theChoices = getChoices();
 403  0
         if (exclusive) {
 404  0
             ((SortedListModel) choicesList.getModel()).removeAll(theChoices);
 405  
         }
 406  0
         ((SortedListModel) selectedList.getModel()).addAll(theChoices);
 407  
 
 408  0
     }
 409  
 
 410  
     /**
 411  
      * Removes the selected elements in the selected list and adds them to the
 412  
      * choices list. The GUI will be updated by the ListModel listeners.
 413  
      */
 414  
     private void removeSelection() {
 415  0
         List theChoices = getSelectedChoices();
 416  0
         ((SortedListModel) selectedList.getModel()).removeAll(theChoices);
 417  0
         if (exclusive) {
 418  0
             ((SortedListModel) choicesList.getModel()).addAll(theChoices);
 419  
         }
 420  0
     }
 421  
 
 422  
     /**
 423  
      * Called when the OK button is pressed. Closes this dialog and sets the
 424  
      * return value to JOptionPane.OK_OPTION.
 425  
      */
 426  
     private void ok() {
 427  0
         if (dialog != null) {
 428  0
             dialog.setVisible(false);
 429  0
             returnValue = JOptionPane.OK_OPTION;
 430  
         }
 431  0
     }
 432  
 
 433  
     /**
 434  
      * Called when the cancel button is pressed. Closes this dialog and sets the
 435  
      * returnvalue to JOptionPane.CANCEL_OPTION. The state of any selections
 436  
      * is indeterminate after cancel is called.
 437  
      */
 438  
     private void cancel() {
 439  0
         if (dialog != null) {
 440  0
             dialog.setVisible(false);
 441  0
             returnValue = JOptionPane.CANCEL_OPTION;
 442  
         }
 443  0
     }
 444  
 }