Coverage Report - us.daveread.basicquery.ReorderDialog
 
Classes in this File Line Coverage Branch Coverage Complexity
ReorderDialog
0%
0/74
0%
0/9
0
 
 1  
 package us.daveread.basicquery;
 2  
 
 3  
 import java.util.List;
 4  
 import java.awt.BorderLayout;
 5  
 import java.awt.FlowLayout;
 6  
 import java.awt.event.ActionEvent;
 7  
 import java.awt.event.ActionListener;
 8  
 import java.awt.event.WindowEvent;
 9  
 import java.awt.event.WindowListener;
 10  
 
 11  
 import javax.swing.JButton;
 12  
 import javax.swing.JDialog;
 13  
 import javax.swing.JFrame;
 14  
 import javax.swing.JList;
 15  
 import javax.swing.JPanel;
 16  
 import javax.swing.JScrollPane;
 17  
 import javax.swing.ListSelectionModel;
 18  
 import javax.swing.WindowConstants;
 19  
 import javax.swing.event.ListSelectionEvent;
 20  
 import javax.swing.event.ListSelectionListener;
 21  
 
 22  
 import org.apache.log4j.Logger;
 23  
 
 24  
 import us.daveread.basicquery.gui.GUIUtility;
 25  
 import us.daveread.basicquery.util.Resources;
 26  
 
 27  
 /**
 28  
  * <p>
 29  
  * Title: ReorderDialog
 30  
  * </p>
 31  
  * <p>
 32  
  * Description: Display list of objects and allow them to be reordered.
 33  
  * </p>
 34  
  * <p>
 35  
  * Copyright: Copyright (c) 2004-2014, David Read
 36  
  * </p>
 37  
  * <p>
 38  
  * This program is free software; you can redistribute it and/or modify it under
 39  
  * the terms of the GNU General Public License as published by the Free Software
 40  
  * Foundation; either version 2 of the License, or (at your option) any later
 41  
  * version.
 42  
  * </p>
 43  
  * <p>
 44  
  * This program is distributed in the hope that it will be useful, but WITHOUT
 45  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 46  
  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 47  
  * details.
 48  
  * </p>
 49  
  * <p>
 50  
  * You should have received a copy of the GNU General Public License along with
 51  
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 52  
  * Place, Suite 330, Boston, MA 02111-1307 USA
 53  
  * </p>
 54  
  * <p>
 55  
  * </p>
 56  
  * 
 57  
  * @author David Read
 58  
  */
 59  
 
 60  
 public class ReorderDialog extends JDialog implements ActionListener,
 61  
     WindowListener,
 62  
     ListSelectionListener {
 63  
   /**
 64  
    * Serial UID for the class
 65  
    */
 66  
   private static final long serialVersionUID = 1013157031020796234L;
 67  
 
 68  
   /**
 69  
    * Logger
 70  
    */
 71  0
   private static final Logger LOGGER = Logger.getLogger(ReorderDialog.class);
 72  
 
 73  
   /**
 74  
    * Maximum row height of the list display
 75  
    */
 76  
   private static final int MAXIMUM_ROWS_TO_DISPLAY = 20;
 77  
 
 78  
   /**
 79  
    * List of objects the user can reorder
 80  
    */
 81  
   private List<Object> ordered;
 82  
 
 83  
   /**
 84  
    * Detect if the order of the object was changed by the user
 85  
    */
 86  
   private boolean didReorder;
 87  
 
 88  
   /**
 89  
    * Move the selected item up
 90  
    */
 91  
   private JButton up;
 92  
 
 93  
   /**
 94  
    * Move the selected item down
 95  
    */
 96  
   private JButton down;
 97  
 
 98  
   /**
 99  
    * Close the dialog (accepting any changes made)
 100  
    */
 101  
   private JButton close;
 102  
 
 103  
   /**
 104  
    * Cancel the dialog (ignoring any changes made)
 105  
    */
 106  
   private JButton cancel;
 107  
 
 108  
   /**
 109  
    * The reordered list of objects
 110  
    */
 111  
   private JList reordered;
 112  
 
 113  
   /**
 114  
    * The model backing the reorderable list display
 115  
    */
 116  
   private ReorderListModel<Object> reorderedModel;
 117  
 
 118  
   /**
 119  
    * Constructs the JDialog as a modal dialog and sets-up the components.
 120  
    * Finally
 121  
    * it makes itself visible.
 122  
    * 
 123  
    * @param parent
 124  
    *          JFrame The parent JFrame that owns this dialog.
 125  
    * @param objects
 126  
    *          List The list of data to be presented in the list.
 127  
    */
 128  
   public ReorderDialog(JFrame parent, List<Object> objects) {
 129  0
     super(parent, true);
 130  0
     ordered = objects;
 131  
 
 132  0
     addWindowListener(this);
 133  0
     setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
 134  0
     setTitle(Resources.getString("dlgReorderDlgTitle"));
 135  0
     setup();
 136  0
     pack();
 137  
 
 138  0
     if (getWidth() > parent.getWidth()) {
 139  0
       setSize(parent.getWidth(), getHeight());
 140  
     }
 141  
 
 142  0
     GUIUtility.center(this, parent);
 143  
 
 144  0
     setVisible(true);
 145  0
   }
 146  
 
 147  
   /**
 148  
    * Setup the GUI components.
 149  
    */
 150  
   private void setup() {
 151  
     JPanel buttons;
 152  0
     getContentPane().setLayout(new BorderLayout());
 153  
 
 154  
     // Center is list of objects;
 155  0
     getContentPane().add(new JScrollPane(reordered = new JList(reorderedModel =
 156  
         new ReorderListModel<Object>(ordered))), BorderLayout.CENTER);
 157  0
     reordered.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 158  0
     reordered.addListSelectionListener(this);
 159  0
     reordered
 160  
         .setVisibleRowCount(ordered.size() < MAXIMUM_ROWS_TO_DISPLAY ? ordered
 161  
             .size() : MAXIMUM_ROWS_TO_DISPLAY);
 162  
 
 163  
     // Buttons
 164  0
     buttons = new JPanel();
 165  0
     buttons.setLayout(new FlowLayout(FlowLayout.CENTER));
 166  0
     buttons.add(up = new JButton(Resources.getString("ctlReorderSQLMoveUp")));
 167  0
     up.addActionListener(this);
 168  0
     up.setEnabled(false);
 169  0
     buttons
 170  
         .add(down = new JButton(Resources.getString("ctlReorderSQLMoveDown")));
 171  0
     down.addActionListener(this);
 172  0
     down.setEnabled(false);
 173  0
     buttons.add(close = new JButton(Resources.getString("ctlReorderSQLOkay")));
 174  0
     close.addActionListener(this);
 175  0
     buttons
 176  
         .add(cancel = new JButton(Resources.getString("ctlReorderSQLCancel")));
 177  0
     cancel.addActionListener(this);
 178  0
     getContentPane().add(buttons, BorderLayout.SOUTH);
 179  0
   }
 180  
 
 181  
   /**
 182  
    * User canceled changes. This method clears the reorder boolean and
 183  
    * disposes of the dialog.
 184  
    */
 185  
   private void cancelDialog() {
 186  0
     didReorder = false;
 187  0
     dispose();
 188  0
   }
 189  
 
 190  
   /**
 191  
    * User requested that the dialog be closed. The current list, which may
 192  
    * or may not be reordered from its original state, is obtrained from the
 193  
    * model
 194  
    * and the dialog is closed.
 195  
    */
 196  
   private void closeDialog() {
 197  0
     ordered = reorderedModel.getList();
 198  0
     dispose();
 199  0
   }
 200  
 
 201  
   /**
 202  
    * Move the selected entry up one position (move to lower index value) which
 203  
    * in the GUI will result in the selected line moving up one line vertically.
 204  
    */
 205  
   private void moveUp() {
 206  0
     reorderedModel.moveUp(reordered.getSelectedIndex());
 207  0
     reordered.setSelectedIndex(reordered.getSelectedIndex() - 1);
 208  0
     reordered.ensureIndexIsVisible(reordered.getSelectedIndex());
 209  0
     didReorder = true;
 210  0
   }
 211  
 
 212  
   /**
 213  
    * Move the selected entry down one position (move to higher index value)
 214  
    * which
 215  
    * in the GUI will result in the selected line moving down one line
 216  
    * vertically.
 217  
    */
 218  
   private void moveDown() {
 219  0
     reorderedModel.moveDown(reordered.getSelectedIndex());
 220  0
     reordered.setSelectedIndex(reordered.getSelectedIndex() + 1);
 221  0
     reordered.ensureIndexIsVisible(reordered.getSelectedIndex());
 222  0
     didReorder = true;
 223  0
   }
 224  
 
 225  
   /**
 226  
    * Get the list that backs the model.
 227  
    * 
 228  
    * @return List The list which may have been reordered.
 229  
    */
 230  
   public List<Object> getAsOrdered() {
 231  0
     return ordered;
 232  
   }
 233  
 
 234  
   /**
 235  
    * Return whether or not the list was reordered from its original state.
 236  
    * 
 237  
    * @return boolean Whether the list was reordered.
 238  
    */
 239  
   public boolean isReordered() {
 240  0
     return didReorder;
 241  
   }
 242  
 
 243  
   // Begin ActionListener Interface
 244  
 
 245  
   /**
 246  
    * Depending on which option the user has invoked the
 247  
    * appropriate action is performed
 248  
    * 
 249  
    * @param evt
 250  
    *          Specifies the action event that has taken place
 251  
    */
 252  
   public void actionPerformed(ActionEvent evt) {
 253  0
     if (evt.getSource() == cancel) {
 254  0
       cancelDialog();
 255  0
     } else if (evt.getSource() == close) {
 256  0
       closeDialog();
 257  0
     } else if (evt.getSource() == up) {
 258  0
       moveUp();
 259  0
     } else if (evt.getSource() == down) {
 260  0
       moveDown();
 261  
     }
 262  0
   }
 263  
 
 264  
   // End ActionListener Interface
 265  
 
 266  
   // Begin ListSelectionListener Interface
 267  
 
 268  
   @Override
 269  
   public void valueChanged(ListSelectionEvent evt) {
 270  0
     if (reordered.getSelectedIndex() != -1) {
 271  0
       up.setEnabled(reordered.getSelectedIndex() != 0);
 272  0
       down.setEnabled(reordered.getSelectedIndex() 
 273  
           < reordered.getModel().getSize() - 1);
 274  
     }
 275  0
   }
 276  
 
 277  
   // End ListSelectionListener Interface
 278  
 
 279  
   // Begin WindowListener Interface
 280  
 
 281  
   @Override
 282  
   public void windowActivated(WindowEvent evt) {
 283  0
   }
 284  
 
 285  
   @Override
 286  
   public void windowClosed(WindowEvent evt) {
 287  0
   }
 288  
 
 289  
   @Override
 290  
   public void windowClosing(WindowEvent evt) {
 291  
     try {
 292  0
       dispose();
 293  0
     } catch (Throwable any) {
 294  
       // This fails periodically with a NP exception
 295  
       // from Container.removeNotify
 296  0
       LOGGER.error("Failure during dialog clean-up", any);
 297  0
     }
 298  0
   }
 299  
 
 300  
   @Override
 301  
   public void windowDeactivated(WindowEvent evt) {
 302  0
   }
 303  
 
 304  
   @Override
 305  
   public void windowDeiconified(WindowEvent evt) {
 306  0
   }
 307  
 
 308  
   @Override
 309  
   public void windowIconified(WindowEvent evt) {
 310  0
   }
 311  
 
 312  
   @Override
 313  
   public void windowOpened(WindowEvent evt) {
 314  0
   }
 315  
 
 316  
   // End WindowListener Interface
 317  
 }