001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.gui.util;
025    
026    import javax.swing.ListSelectionModel;
027    import javax.swing.event.EventListenerList;
028    import javax.swing.event.ListSelectionEvent;
029    import javax.swing.event.ListSelectionListener;
030    
031    public class FastListSelectionModel implements ListSelectionModel {
032    
033            private final int selectionMode = SINGLE_INTERVAL_SELECTION;
034    
035            private int minIndex = -1;
036    
037            private int maxIndex = -1;
038    
039            private boolean valueIsAdjusting = false;
040    
041            public FastListSelectionModel() {
042            }
043    
044            protected EventListenerList listenerList = new EventListenerList();
045    
046            public void addListSelectionListener(ListSelectionListener l) {
047                    listenerList.add(ListSelectionListener.class, l);
048            }
049    
050            public void removeListSelectionListener(ListSelectionListener l) {
051                    listenerList.remove(ListSelectionListener.class, l);
052            }
053    
054            public void addSelectionInterval(int index0, int index1) {
055                    if (index1 > index0) {
056                            minIndex = Math.min(minIndex, index0);
057                            maxIndex = Math.max(maxIndex, index1);
058                    } else {
059                            minIndex = Math.min(minIndex, index1);
060                            maxIndex = Math.max(maxIndex, index0);
061                    }
062                    fireValueChanged();
063            }
064    
065            protected void fireValueChanged(int firstIndex, int lastIndex) {
066                    fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting());
067            }
068    
069            protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) {
070                    Object[] listeners = listenerList.getListenerList();
071                    ListSelectionEvent e = null;
072    
073                    for (int i = listeners.length - 2; i >= 0; i -= 2) {
074                            if (listeners[i] == ListSelectionListener.class) {
075                                    if (e == null) {
076                                            e = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting);
077                                    }
078                                    ((ListSelectionListener) listeners[i + 1]).valueChanged(e);
079                            }
080                    }
081            }
082    
083            public void clearSelection() {
084                    minIndex = -1;
085                    maxIndex = -1;
086                    fireValueChanged();
087            }
088    
089            private void fireValueChanged() {
090                    fireValueChanged(0, Integer.MAX_VALUE);
091            }
092    
093            public int getMinSelectionIndex() {
094                    return minIndex;
095            }
096    
097            public int getAnchorSelectionIndex() {
098                    return minIndex;
099            }
100    
101            public int getLeadSelectionIndex() {
102                    return maxIndex;
103            }
104    
105            public int getMaxSelectionIndex() {
106                    return maxIndex;
107            }
108    
109            public int getSelectionMode() {
110                    return selectionMode;
111            }
112    
113            public boolean getValueIsAdjusting() {
114                    return valueIsAdjusting;
115            }
116    
117            public void insertIndexInterval(int index, int length, boolean before) {
118                    minIndex = Math.min(minIndex, index);
119                    maxIndex = Math.max(maxIndex, index + length);
120                    fireValueChanged();
121            }
122    
123            public boolean isSelectedIndex(int index) {
124                    return index >= minIndex && index <= maxIndex;
125            }
126    
127            public boolean isSelectionEmpty() {
128                    return minIndex == -1 || maxIndex == -1;
129            }
130    
131            public void removeIndexInterval(int index0, int index1) {
132                    if (index1 >= index0) {
133                            minIndex = Math.max(minIndex, index0);
134                            maxIndex = Math.min(maxIndex, index1);
135                    } else {
136                            minIndex = Math.max(minIndex, index1);
137                            maxIndex = Math.min(maxIndex, index0);
138                    }
139                    fireValueChanged();
140            }
141    
142            public void removeSelectionInterval(int index0, int index1) {
143                    if (index1 >= index0) {
144                            minIndex = Math.max(minIndex, index0);
145                            maxIndex = Math.min(maxIndex, index1);
146                    } else {
147                            minIndex = Math.max(minIndex, index1);
148                            maxIndex = Math.min(maxIndex, index0);
149                    }
150                    fireValueChanged();
151            }
152    
153            public void setAnchorSelectionIndex(int index) {
154                    minIndex = Math.min(minIndex, index);
155                    fireValueChanged();
156            }
157    
158            public void setLeadSelectionIndex(int index) {
159                    maxIndex = Math.max(maxIndex, index);
160                    fireValueChanged();
161            }
162    
163            public void setSelectionInterval(int index0, int index1) {
164                    if (index1 > index0) {
165                            minIndex = index0;
166                            maxIndex = index1;
167                    } else {
168                            minIndex = index1;
169                            maxIndex = index0;
170                    }
171                    fireValueChanged();
172            }
173    
174            public void setSelectionMode(int selectionMode) {
175            }
176    
177            public void setValueIsAdjusting(boolean valueIsAdjusting) {
178                    this.valueIsAdjusting = valueIsAdjusting;
179            }
180    
181    }