org.nuiton.jaxx.runtime.swing.OneClicListSelectionModel Maven / Gradle / Ivy
The newest version!
/*
* #%L
* JAXX :: Runtime
* %%
* Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.jaxx.runtime.swing;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import javax.swing.JList;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionListener;
import java.util.Arrays;
/**
* @author Tony Chemit - [email protected]
* @since 1.5
*/
public class OneClicListSelectionModel implements ListSelectionModel {
/** Logger */
static private final Logger log = LogManager.getLogger(OneClicListSelectionModel.class);
protected final ListSelectionModel delegate;
protected final ListModel model;
private boolean[] _states;
/**
* Convinient method to install a new {@link OneClicListSelectionModel} on
* a given {@link JList}.
*
* @param list the list onwhcih install the selection model
* @since 2.5.4
*/
public static void installModel(JList list) {
OneClicListSelectionModel newModel = new OneClicListSelectionModel(list);
list.setSelectionModel(newModel);
}
public OneClicListSelectionModel(JList list) {
this.delegate = list.getSelectionModel();
this.model = list.getModel();
delegate.clearSelection();
}
public OneClicListSelectionModel(ListSelectionModel delegate, ListModel model) {
this.delegate = delegate;
this.model = model;
delegate.clearSelection();
}
protected boolean[] getStates(int selectedIndex) {
int max = model.getSize();
if (_states == null || _states.length != max) {
_states = new boolean[max];
} else {
Arrays.fill(_states, false);
}
for (int i = 0; i < max; i++) {
_states[i] = i != selectedIndex && delegate.isSelectedIndex(i);
}
return _states;
}
@Override
public void setSelectionInterval(int index0, int index1) {
if (index0 != index1) {
// not a single selection (come from a click)
// use default behaviour
delegate.setSelectionInterval(index0, index1);
return;
}
delegate.setValueIsAdjusting(true);
try {
int max = model.getSize();
if (log.isDebugEnabled()) {
log.debug("single [index:" + index0 + "] [selected:" + isSelectedIndex(index0) + "] [size:" + max + "] [anchor:" + delegate.getAnchorSelectionIndex() + "] [lead:" + delegate.getLeadSelectionIndex() + "]");
}
if (!isSelectedIndex(index0)) {
// select it
delegate.addSelectionInterval(index0, index1);
return;
}
if (max == index0) {
// last selected index, so can directly remove it
delegate.removeIndexInterval(index0, index0);
return;
}
// must recompute the selection removing only the index0 item
boolean[] state = getStates(index0);
if (log.isDebugEnabled()) {
log.debug("state : " + Arrays.toString(state));
}
delegate.clearSelection();
for (int i = 0; i < max; i++) {
if (state[i]) {
delegate.addSelectionInterval(i, i);
}
}
} finally {
delegate.setValueIsAdjusting(false);
}
}
@Override
public void addSelectionInterval(int index0, int index1) {
delegate.addSelectionInterval(index0, index1);
}
@Override
public void removeSelectionInterval(int index0, int index1) {
delegate.removeSelectionInterval(index0, index1);
}
@Override
public int getMinSelectionIndex() {
return delegate.getMinSelectionIndex();
}
@Override
public int getMaxSelectionIndex() {
return delegate.getMaxSelectionIndex();
}
@Override
public boolean isSelectedIndex(int index) {
return delegate.isSelectedIndex(index);
}
@Override
public int getAnchorSelectionIndex() {
return delegate.getAnchorSelectionIndex();
}
@Override
public void setAnchorSelectionIndex(int index) {
delegate.setAnchorSelectionIndex(index);
}
@Override
public int getLeadSelectionIndex() {
return delegate.getLeadSelectionIndex();
}
@Override
public void setLeadSelectionIndex(int index) {
delegate.setLeadSelectionIndex(index);
}
@Override
public void clearSelection() {
delegate.clearSelection();
}
@Override
public boolean isSelectionEmpty() {
return delegate.isSelectionEmpty();
}
@Override
public void insertIndexInterval(int index, int length, boolean before) {
delegate.insertIndexInterval(index, length, before);
}
@Override
public void removeIndexInterval(int index0, int index1) {
delegate.removeIndexInterval(index0, index1);
}
@Override
public void setValueIsAdjusting(boolean valueIsAdjusting) {
delegate.setValueIsAdjusting(valueIsAdjusting);
}
@Override
public boolean getValueIsAdjusting() {
return delegate.getValueIsAdjusting();
}
@Override
public void setSelectionMode(int selectionMode) {
delegate.setSelectionMode(selectionMode);
}
@Override
public int getSelectionMode() {
return delegate.getSelectionMode();
}
@Override
public void addListSelectionListener(ListSelectionListener x) {
delegate.addListSelectionListener(x);
}
@Override
public void removeListSelectionListener(ListSelectionListener x) {
delegate.removeListSelectionListener(x);
}
}