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 }