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