package com.bagri.tools.vvm.ui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
import javax.swing.*;
public class DualListBox<E> extends JPanel {
private static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
private static final String ADD_ALL_BUTTON_LABEL = ">>";
private static final String ADD_BUTTON_LABEL = ">";
private static final String REMOVE_ALL_BUTTON_LABEL = "<<";
private static final String REMOVE_BUTTON_LABEL = "<";
private static final String DEFAULT_SOURCE_CHOICE_LABEL = "Available Choices";
private static final String DEFAULT_DEST_CHOICE_LABEL = "Your Choices";
private JLabel sourceLabel;
private JList<E> sourceList;
private SortedListModel<E> sourceListModel;
private JList<E> destList;
private SortedListModel<E> destListModel;
private JLabel destLabel;
private JButton addButton;
private JButton addAllButton;
private JButton removeButton;
private JButton removeAllButton;
public DualListBox() {
initScreen();
}
public String getSourceChoicesTitle() {
return sourceLabel.getText();
}
public void setSourceChoicesTitle(String newValue) {
sourceLabel.setText(newValue);
}
public String getDestinationChoicesTitle() {
return destLabel.getText();
}
public void setDestinationChoicesTitle(String newValue) {
destLabel.setText(newValue);
}
public void clearSourceListModel() {
sourceListModel.clear();
}
public void clearDestinationListModel() {
destListModel.clear();
}
public void addSourceElements(ListModel<E> newValue) {
fillListModel(sourceListModel, newValue);
}
public void setSourceElements(ListModel<E> newValue) {
clearSourceListModel();
addSourceElements(newValue);
}
public void addDestinationElements(ListModel<E> newValue) {
fillListModel(destListModel, newValue);
}
private void fillListModel(SortedListModel<E> model, ListModel<E> newValues) {
int size = newValues.getSize();
for (int i = 0; i < size; i++) {
model.add(newValues.getElementAt(i));
}
}
public void addSourceElements(List<E> newValues) {
fillListModel(sourceListModel, newValues);
}
public void setSourceElements(List<E> newValues) {
clearSourceListModel();
addSourceElements(newValues);
}
public void addDestinationElements(List<E> values) {
fillListModel(destListModel, values);
}
public void setDestinationElements(List<E> values) {
setDestinationElements(values, true);
}
public void setDestinationElements(List<E> values, boolean subtractFromSource) {
clearDestinationListModel();
addDestinationElements(values);
if (subtractFromSource) {
ListModel<E> sourceModel = sourceList.getModel();
List<E> sourceElements = new ArrayList<E>(sourceModel.getSize());
for (int i = 0; i < sourceModel.getSize(); i++) {
sourceElements.add(sourceModel.getElementAt(i));
}
sourceElements.removeAll(values);
setSourceElements(sourceElements);
}
}
private void fillListModel(SortedListModel<E> model, List<E> newValues) {
model.addAll(newValues);
}
public Iterator sourceIterator() {
return sourceListModel.iterator();
}
public Iterator destinationIterator() {
return destListModel.iterator();
}
public void setSourceCellRenderer(ListCellRenderer<E> newValue) {
sourceList.setCellRenderer(newValue);
}
public ListCellRenderer getSourceCellRenderer() {
return sourceList.getCellRenderer();
}
public void setDestinationCellRenderer(ListCellRenderer<E> newValue) {
destList.setCellRenderer(newValue);
}
public ListCellRenderer getDestinationCellRenderer() {
return destList.getCellRenderer();
}
public void setVisibleRowCount(int newValue) {
sourceList.setVisibleRowCount(newValue);
destList.setVisibleRowCount(newValue);
}
public int getVisibleRowCount() {
return sourceList.getVisibleRowCount();
}
public void setSelectionBackground(Color newValue) {
sourceList.setSelectionBackground(newValue);
destList.setSelectionBackground(newValue);
}
public Color getSelectionBackground() {
return sourceList.getSelectionBackground();
}
public void setSelectionForeground(Color newValue) {
sourceList.setSelectionForeground(newValue);
destList.setSelectionForeground(newValue);
}
public Color getSelectionForeground() {
return sourceList.getSelectionForeground();
}
private void clearSourceSelected() {
// Object selected[] = sourceList.getSelectedValues();
// for (int i = selected.length - 1; i >= 0; --i) {
// sourceListModel.removeElement(selected[i]);
// }
List<E> selected = sourceList.getSelectedValuesList();
for (E sel : selected) {
sourceListModel.removeElement(sel);
}
sourceList.getSelectionModel().clearSelection();
}
private void clearDestinationSelected() {
// Object selected[] = destList.getSelectedValues();
// for (int i = selected.length - 1; i >= 0; --i) {
// destListModel.removeElement(selected[i]);
// }
List<E> selected = destList.getSelectedValuesList();
for (E sel : selected) {
destListModel.removeElement(sel);
}
destList.getSelectionModel().clearSelection();
}
private void initScreen() {
setBorder(BorderFactory.createEtchedBorder());
setLayout(new GridBagLayout());
sourceLabel = new JLabel(DEFAULT_SOURCE_CHOICE_LABEL);
sourceListModel = new SortedListModel<E>();
sourceList = new JList<E>(sourceListModel);
sourceList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount()>=2) {
addSelected();
}
}
});
add(sourceLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
add(new JScrollPane(sourceList), new GridBagConstraints(0, 1, 1, 9, .5,
1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
EMPTY_INSETS, 0, 0));
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
Dimension buttonsDimensions = new Dimension(50,26);
addAllButton = new JButton(ADD_ALL_BUTTON_LABEL);
addAllButton.addActionListener(new AddAllListener());
addAllButton.setAlignmentX(Component.CENTER_ALIGNMENT);
addAllButton.setMinimumSize(buttonsDimensions);
addAllButton.setPreferredSize(buttonsDimensions);
addAllButton.setMaximumSize(buttonsDimensions);
buttonPanel.add(addAllButton);
addButton = new JButton(ADD_BUTTON_LABEL);
addButton.addActionListener(new AddListener());
addButton.setAlignmentX(Component.CENTER_ALIGNMENT);
addButton.setMinimumSize(buttonsDimensions);
addButton.setPreferredSize(buttonsDimensions);
addButton.setMaximumSize(buttonsDimensions);
buttonPanel.add(addButton);
buttonPanel.add(new Box.Filler(new Dimension(0,20), new Dimension(0,20), new Dimension(0,20)));
removeButton = new JButton(REMOVE_BUTTON_LABEL);
removeButton.addActionListener(new RemoveListener());
removeButton.setAlignmentX(Component.CENTER_ALIGNMENT);
removeButton.setMinimumSize(buttonsDimensions);
removeButton.setPreferredSize(buttonsDimensions);
removeButton.setMaximumSize(buttonsDimensions);
buttonPanel.add(removeButton);
removeAllButton = new JButton(REMOVE_ALL_BUTTON_LABEL);
removeAllButton.setAlignmentX(Component.CENTER_ALIGNMENT);
removeAllButton.setMinimumSize(buttonsDimensions);
removeAllButton.setPreferredSize(buttonsDimensions);
removeAllButton.setMaximumSize (buttonsDimensions);
removeAllButton.addActionListener(new RemoveAllListener());
buttonPanel.add(removeAllButton);
/*
addButton = new JButton(ADD_BUTTON_LABEL);
add(addButton, new GridBagConstraints(1, 2, 1, 1, 0, .25,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
addButton.addActionListener(new AddListener());
add(new JButton(">>"), new GridBagConstraints(1, 3, 1, 1, 0, .25,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
removeButton = new JButton(REMOVE_BUTTON_LABEL);
add(removeButton, new GridBagConstraints(1, 7, 1, 1, 0, .25,
GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(
0, 5, 0, 5), 0, 0));
removeButton.addActionListener(new RemoveListener());
add(new JButton("<<"), new GridBagConstraints(1, 8, 1, 1, 0, .25,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
*/
add(buttonPanel, new GridBagConstraints(1, 2, 1, 1, 0, .25,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
destLabel = new JLabel(DEFAULT_DEST_CHOICE_LABEL);
destListModel = new SortedListModel<E>();
destList = new JList<E>(destListModel);
destList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount()>=2) {
removeSelected();
}
}
});
add(destLabel, new GridBagConstraints(2, 0, 1, 1, 0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
add(new JScrollPane(destList), new GridBagConstraints(2, 1, 1, 9, .5,
1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
EMPTY_INSETS, 0, 0));
}
private void removeSelected() {
List<E> selected = destList.getSelectedValuesList();
addSourceElements(selected);
clearDestinationSelected();
}
private void addSelected() {
List<E> selected = sourceList.getSelectedValuesList();
addDestinationElements(selected);
clearSourceSelected();
}
private class AddAllListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
ListModel<E> model = sourceList.getModel();
List<E> all = new ArrayList<E>(model.getSize());
for (int i=0; i< model.getSize(); i++) {
all.add(model.getElementAt(i));
}
addDestinationElements(all);
clearSourceListModel();
}
}
private class AddListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
addSelected();
}
}
private class RemoveListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
removeSelected();
}
}
private class RemoveAllListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
ListModel<E> model = destList.getModel();
List<E> all = new ArrayList<E>(model.getSize());
for (int i=0; i< model.getSize(); i++) {
all.add(model.getElementAt(i));
}
addSourceElements(all);
clearDestinationListModel();
}
}
public static void main(String args[]) {
JFrame f = new JFrame("Dual List Box Tester");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
DualListBox<MyNumber> dual = new DualListBox<MyNumber>();
// dual.addSourceElements(Arrays.asList(new String[] { "One", "Two", "Three" }));
// dual.addSourceElements(Arrays.asList(new String[] { "Four", "Five", "Six" }));
// dual.addSourceElements(Arrays.asList(new String[] { "Seven", "Eight", "Nine" }));
// dual.addSourceElements(Arrays.asList(new String[] { "Ten", "Eleven", "Twelve" }));
// dual.addSourceElements(Arrays.asList(new String[] { "Thirteen", "Fourteen","Fifteen" }));
// dual.addSourceElements(Arrays.asList(new String[] { "Sixteen", "Seventeen","Eighteen" }));
// dual.addSourceElements(Arrays.asList(new String[] { "Nineteen", "Twenty", "Thirty" }));
//
// dual.setDestinationElements(Arrays.asList("Nineteen", "Twenty", "Thirty"));
dual.addSourceElements(Arrays.asList( new MyNumber("One"), new MyNumber("Two"), new MyNumber("Three") ));
dual.addSourceElements(Arrays.asList( new MyNumber("Four"), new MyNumber("Five"), new MyNumber("Six") ));
dual.addSourceElements(Arrays.asList( new MyNumber("Seven"), new MyNumber("Eight"), new MyNumber("Nine") ));
dual.addSourceElements(Arrays.asList( new MyNumber("Ten"), new MyNumber("Eleven"), new MyNumber("Twelve") ));
dual.addSourceElements(Arrays.asList( new MyNumber("Thirteen"), new MyNumber("Fourteen"),new MyNumber("Fifteen") ));
dual.addSourceElements(Arrays.asList( new MyNumber("Sixteen"), new MyNumber("Seventeen"),new MyNumber("Eighteen") ));
dual.addSourceElements(Arrays.asList( new MyNumber("Nineteen"), new MyNumber("Twenty"), new MyNumber("Thirty") ));
dual.setDestinationElements(Arrays.asList(new MyNumber("Nineteen"), new MyNumber("Twenty"), new MyNumber("Thirty")));
f.getContentPane().add(dual, BorderLayout.CENTER);
f.setSize(400, 300);
f.setVisible(true);
}
private static class MyNumber implements Comparable<MyNumber> {
private String name;
private MyNumber(String name) {
this.name = name;
}
@Override
public int compareTo(MyNumber o) {
return this.name.compareTo(o.name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyNumber myNumber = (MyNumber) o;
if (!name.equals(myNumber.name)) return false;
return true;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public String toString() {
return name;
}
}
}