001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.components;
017    
018    import java.awt.event.ActionEvent;
019    import java.awt.event.ActionListener;
020    import java.util.Arrays;
021    import java.util.List;
022    
023    import javax.swing.JButton;
024    import javax.swing.JComponent;
025    import javax.swing.JList;
026    import javax.swing.event.ListSelectionEvent;
027    import javax.swing.event.ListSelectionListener;
028    
029    import org.springframework.richclient.core.UIConstants;
030    import org.springframework.richclient.factory.AbstractControlFactory;
031    import org.springframework.richclient.util.GuiStandardUtils;
032    import org.springframework.util.Assert;
033    
034    /**
035     * @author Keith Donald
036     */
037    public class ListItemUpDownButtonPanel extends AbstractControlFactory {
038    
039        private static final String DOWN_BUTTON_MESSAGE_CODE = "button.down";
040    
041        private static final String UP_BUTTON_MESSAGE_CODE = "button.up";
042        
043        private final ListSelectionListener listSelectionChangeHandler = new ListSelectionChangeHandler();
044    
045        private final UpAction upAction = new UpAction();
046    
047        private final DownAction downAction = new DownAction();
048    
049        private final JList list;
050    
051        private JButton upButton;
052    
053        private JButton downButton;
054    
055        public ListItemUpDownButtonPanel(JList list) {
056            this.list = list;
057            Assert.isTrue(list.getModel() instanceof List, "List model must implement the List collection interface");
058            subscribe();
059        }
060    
061        protected JList getList() {
062            return list;
063        }
064    
065        protected List getListModel() {
066            return (List)list.getModel();
067        }
068    
069        protected JComponent createControl() {
070            return createUpDownButtonPanel();
071        }
072    
073        private void subscribe() {
074            this.list.addListSelectionListener(listSelectionChangeHandler);
075        }
076    
077        protected void onEmptySelection() {
078            upButton.setEnabled(false);
079            downButton.setEnabled(false);
080        }
081    
082        protected void onSelection() {
083            if (!isContiguousSelection(getList())) {
084                upButton.setEnabled(false);
085                downButton.setEnabled(false);
086            }
087            else {
088                if (getList().getMinSelectionIndex() == 0) {
089                    upButton.setEnabled(false);
090                }
091                else {
092                    upButton.setEnabled(true);
093                }
094                if (getList().getMaxSelectionIndex() == (getListModel().size() - 1)) {
095                    downButton.setEnabled(false);
096                }
097                else {
098                    downButton.setEnabled(true);
099                }
100            }
101        }
102    
103        private boolean isContiguousSelection(JList list) {
104            for (int i = list.getMinSelectionIndex(); i <= list.getMaxSelectionIndex(); i++) {
105                if (!list.isSelectedIndex(i)) {
106                    return false;
107                }
108            }
109            return true;
110        }
111    
112        private JComponent createUpDownButtonPanel() {
113            upButton = getComponentFactory().createButton(UP_BUTTON_MESSAGE_CODE);
114            upButton.setEnabled(false);
115            upButton.addActionListener(upAction);
116    
117            downButton = getComponentFactory().createButton(DOWN_BUTTON_MESSAGE_CODE);
118            downButton.setEnabled(false);
119            downButton.addActionListener(downAction);
120    
121            JComponent panel = GuiStandardUtils.createCommandButtonColumn(new JButton[] {upButton, downButton});
122            panel.setBorder(GuiStandardUtils.createLeftAndRightBorder(UIConstants.ONE_SPACE));
123            return panel;
124        }
125    
126        private class ListSelectionChangeHandler implements ListSelectionListener {
127    
128            public void valueChanged(ListSelectionEvent e) {
129                if (!e.getValueIsAdjusting()) {
130                    if (list.isSelectionEmpty()) {
131                        onEmptySelection();
132                    }
133                    else {
134                        onSelection();
135                    }
136                }
137            }
138        }
139    
140        private class DownAction implements ActionListener {
141            public void actionPerformed(ActionEvent e) {
142                int[] indices = getList().getSelectedIndices();
143                Object[] array = new Object[indices.length];
144                Arrays.sort(indices);
145                List model = getListModel();
146                if (indices[indices.length - 1] == model.size() - 1) {
147                    return;
148                }
149                for (int i = 0; i < indices.length; i++) {
150                    array[i] = model.get(indices[i] - i);
151                    model.remove(indices[i] - i);
152                }
153                int[] newIndices = new int[indices.length];
154                for (int i = 0; i < indices.length; i++) {
155                    int newIndex = indices[0] + 1 + i;
156                    model.add(newIndex, array[i]);
157                    newIndices[i] = newIndex;
158                }
159                getList().setSelectedIndices(newIndices);
160            }
161        }
162    
163        private class UpAction implements ActionListener {
164            public void actionPerformed(ActionEvent e) {
165                int[] indices = getList().getSelectedIndices();
166                Object[] array = new Object[indices.length];
167                Arrays.sort(indices);
168                if (indices[0] == 0) {
169                    return;
170                }
171                List model = getListModel();
172                for (int i = 0; i < indices.length; i++) {
173                    array[i] = model.get(indices[i] - i);
174                    model.remove(indices[i] - i);
175                }
176                int[] newIndices = new int[indices.length];
177                for (int i = 0; i < indices.length; i++) {
178                    int newIndex = indices[0] - 1 + i;
179                    model.add(newIndex, array[i]);
180                    newIndices[i] = newIndex;
181                }
182                getList().setSelectedIndices(newIndices);
183            }
184        }
185    }