Home | History | Annotate | Download | only in gui
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2009 Eric Lafortune (eric (at) graphics.cornell.edu)
      6  *
      7  * This program is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by the Free
      9  * Software Foundation; either version 2 of the License, or (at your option)
     10  * any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along
     18  * with this program; if not, write to the Free Software Foundation, Inc.,
     19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  */
     21 package proguard.gui;
     22 
     23 import java.awt.*;
     24 import java.awt.event.*;
     25 import java.util.List;
     26 import java.util.*;
     27 
     28 import javax.swing.*;
     29 import javax.swing.event.*;
     30 
     31 /**
     32  * This <code>Jpanel</code> allows the user to move and remove entries in a
     33  * list and between lists. Extensions of this class should add buttons to add
     34  * and possibly edit entries, and to set and get the resulting list.
     35  *
     36  * @author Eric Lafortune
     37  */
     38 abstract class ListPanel extends JPanel
     39 {
     40     protected final DefaultListModel listModel = new DefaultListModel();
     41     protected final JList            list      = new JList(listModel);
     42 
     43     protected int firstSelectionButton = 2;
     44 
     45 
     46     protected ListPanel()
     47     {
     48         GridBagLayout layout = new GridBagLayout();
     49         setLayout(layout);
     50 
     51         GridBagConstraints listConstraints = new GridBagConstraints();
     52         listConstraints.gridheight = GridBagConstraints.REMAINDER;
     53         listConstraints.fill       = GridBagConstraints.BOTH;
     54         listConstraints.weightx    = 1.0;
     55         listConstraints.weighty    = 1.0;
     56         listConstraints.anchor     = GridBagConstraints.NORTHWEST;
     57         listConstraints.insets     = new Insets(0, 2, 0, 2);
     58 
     59         // Make sure some buttons are disabled or enabled depending on whether
     60         // the selection is empty or not.
     61         list.addListSelectionListener(new ListSelectionListener()
     62         {
     63             public void valueChanged(ListSelectionEvent e)
     64             {
     65                 enableSelectionButtons();
     66             }
     67         });
     68 
     69         add(new JScrollPane(list), listConstraints);
     70 
     71         // something like the following calls are up to the extending class:
     72         //addAddButton();
     73         //addEditButton();
     74         //addRemoveButton();
     75         //addUpButton();
     76         //addDownButton();
     77         //
     78         //enableSelectionButtons();
     79     }
     80 
     81 
     82     protected void addRemoveButton()
     83     {
     84         JButton removeButton = new JButton(msg("remove"));
     85         removeButton.addActionListener(new ActionListener()
     86         {
     87             public void actionPerformed(ActionEvent e)
     88             {
     89                 // Remove the selected elements.
     90                 removeElementsAt(list.getSelectedIndices());
     91             }
     92         });
     93 
     94         addButton(tip(removeButton, "removeTip"));
     95     }
     96 
     97 
     98     protected void addUpButton()
     99     {
    100         JButton upButton = new JButton(msg("moveUp"));
    101         upButton.addActionListener(new ActionListener()
    102         {
    103             public void actionPerformed(ActionEvent e)
    104             {
    105                 int[] selectedIndices = list.getSelectedIndices();
    106                 if (selectedIndices.length > 0 &&
    107                     selectedIndices[0] > 0)
    108                 {
    109                     // Move the selected elements up.
    110                     moveElementsAt(selectedIndices, -1);
    111                 }
    112             }
    113         });
    114 
    115         addButton(tip(upButton, "moveUpTip"));
    116     }
    117 
    118 
    119     protected void addDownButton()
    120     {
    121         JButton downButton = new JButton(msg("moveDown"));
    122         downButton.addActionListener(new ActionListener()
    123         {
    124             public void actionPerformed(ActionEvent e)
    125             {
    126                 int[] selectedIndices = list.getSelectedIndices();
    127                 if (selectedIndices.length > 0 &&
    128                     selectedIndices[selectedIndices.length-1] < listModel.getSize()-1)
    129                 {
    130                     // Move the selected elements down.
    131                     moveElementsAt(selectedIndices, 1);
    132                 }
    133             }
    134         });
    135 
    136         addButton(tip(downButton, "moveDownTip"));
    137     }
    138 
    139 
    140     /**
    141      * Adds a button that allows to copy or move entries to another ListPanel.
    142      *
    143      * @param buttonTextKey the button text key.
    144      * @param tipKey        the tool tip key.
    145      * @param panel         the other ListPanel.
    146      */
    147     public void addCopyToPanelButton(String          buttonTextKey,
    148                                      String          tipKey,
    149                                      final ListPanel panel)
    150     {
    151         JButton moveButton = new JButton(msg(buttonTextKey));
    152         moveButton.addActionListener(new ActionListener()
    153         {
    154             public void actionPerformed(ActionEvent e)
    155             {
    156                 int[]    selectedIndices  = list.getSelectedIndices();
    157                 Object[] selectedElements = list.getSelectedValues();
    158 
    159                 // Remove the selected elements from this panel.
    160                 removeElementsAt(selectedIndices);
    161 
    162                 // Add the elements to the other panel.
    163                 panel.addElements(selectedElements);
    164             }
    165         });
    166 
    167         addButton(tip(moveButton, tipKey));
    168     }
    169 
    170 
    171     protected void addButton(JComponent button)
    172     {
    173         GridBagConstraints buttonConstraints = new GridBagConstraints();
    174         buttonConstraints.gridwidth = GridBagConstraints.REMAINDER;
    175         buttonConstraints.fill      = GridBagConstraints.HORIZONTAL;
    176         buttonConstraints.anchor    = GridBagConstraints.NORTHWEST;
    177         buttonConstraints.insets    = new Insets(0, 2, 0, 2);
    178 
    179         add(button, buttonConstraints);
    180     }
    181 
    182 
    183     /**
    184      * Returns a list of all right-hand side buttons.
    185      */
    186     public List getButtons()
    187     {
    188         List list = new ArrayList(getComponentCount()-1);
    189 
    190         // Add all buttons.
    191         for (int index = 1; index < getComponentCount(); index++)
    192         {
    193             list.add(getComponent(index));
    194         }
    195 
    196         return list;
    197     }
    198 
    199 
    200     protected void addElement(Object element)
    201     {
    202         listModel.addElement(element);
    203 
    204         // Make sure it is selected.
    205         list.setSelectedIndex(listModel.size() - 1);
    206     }
    207 
    208 
    209     protected void addElements(Object[] elements)
    210     {
    211         // Add the elements one by one.
    212         for (int index = 0; index < elements.length; index++)
    213         {
    214             listModel.addElement(elements[index]);
    215         }
    216 
    217         // Make sure they are selected.
    218         int[] selectedIndices = new int[elements.length];
    219         for (int index = 0; index < selectedIndices.length; index++)
    220         {
    221             selectedIndices[index] =
    222                 listModel.size() - selectedIndices.length + index;
    223         }
    224         list.setSelectedIndices(selectedIndices);
    225     }
    226 
    227 
    228     protected void moveElementsAt(int[] indices, int offset)
    229     {
    230         // Remember the selected elements.
    231         Object[] selectedElements = list.getSelectedValues();
    232 
    233         // Remove the selected elements.
    234         removeElementsAt(indices);
    235 
    236         // Update the element indices.
    237         for (int index = 0; index < indices.length; index++)
    238         {
    239             indices[index] += offset;
    240         }
    241 
    242         // Reinsert the selected elements.
    243         insertElementsAt(selectedElements, indices);
    244     }
    245 
    246 
    247     protected void insertElementsAt(Object[] elements, int[] indices)
    248     {
    249         for (int index = 0; index < elements.length; index++)
    250         {
    251             listModel.insertElementAt(elements[index], indices[index]);
    252         }
    253 
    254         // Make sure they are selected.
    255         list.setSelectedIndices(indices);
    256     }
    257 
    258 
    259     protected void setElementAt(Object element, int index)
    260     {
    261         listModel.setElementAt(element, index);
    262 
    263         // Make sure it is selected.
    264         list.setSelectedIndex(index);
    265     }
    266 
    267 
    268     protected void setElementsAt(Object[] elements, int[] indices)
    269     {
    270         for (int index = 0; index < elements.length; index++)
    271         {
    272             listModel.setElementAt(elements[index], indices[index]);
    273         }
    274 
    275         // Make sure they are selected.
    276         list.setSelectedIndices(indices);
    277     }
    278 
    279 
    280     protected void removeElementsAt(int[] indices)
    281     {
    282         for (int index = indices.length - 1; index >= 0; index--)
    283         {
    284             listModel.removeElementAt(indices[index]);
    285         }
    286 
    287         // Make sure nothing is selected.
    288         list.clearSelection();
    289 
    290         // Make sure the selection buttons are properly enabled,
    291         // since the above method doesn't seem to notify the listener.
    292         enableSelectionButtons();
    293     }
    294 
    295 
    296     protected void removeAllElements()
    297     {
    298         listModel.removeAllElements();
    299 
    300         // Make sure the selection buttons are properly enabled,
    301         // since the above method doesn't seem to notify the listener.
    302         enableSelectionButtons();
    303     }
    304 
    305 
    306     /**
    307      * Enables or disables the buttons that depend on a selection.
    308      */
    309     protected void enableSelectionButtons()
    310     {
    311         boolean selected = !list.isSelectionEmpty();
    312 
    313         // Loop over all components, except the list itself and the Add button.
    314         for (int index = firstSelectionButton; index < getComponentCount(); index++)
    315         {
    316             getComponent(index).setEnabled(selected);
    317         }
    318     }
    319 
    320 
    321     /**
    322      * Attaches the tool tip from the GUI resources that corresponds to the
    323      * given key, to the given component.
    324      */
    325     private static JComponent tip(JComponent component, String messageKey)
    326     {
    327         component.setToolTipText(msg(messageKey));
    328 
    329         return component;
    330     }
    331 
    332 
    333     /**
    334      * Returns the message from the GUI resources that corresponds to the given
    335      * key.
    336      */
    337     private static String msg(String messageKey)
    338     {
    339          return GUIResources.getMessage(messageKey);
    340     }
    341 }
    342