问题
I am looking for a Java Swing Version of 2 JLists that interact with one another. An "available" list and a "selected" list. You can move elements from one list to the other. I also would like to be able to move items in the "selected" list up and down...
回答1:
Been looking all over for this and couldn't find it so I decided to code it myself and share it.. This is a Dual JList which allows moving elements from one to the other via buttons or mouse double click. I used the example here to come up with the following result. Hope this can help others. If anyone can make it prettier it would be much appreciated.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ListSelectionModel;
import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
public class DualListBox extends JPanel {
private static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
private static final String UP_BUTTON_LABEL = "^";
private static final String DOWN_BUTTON_LABEL = "v";
private static final String ADD_BUTTON_LABEL = "Add >";
private static final String ADD_ALL_BUTTON_LABEL = "Add All >>";
private static final String REMOVE_BUTTON_LABEL = "< Remove";
private static final String REMOVE_ALL_BUTTON_LABEL = "<< Remove All";
private static final String DEFAULT_SOURCE_CHOICE_LABEL = "Available";
private static final String DEFAULT_DEST_CHOICE_LABEL = "Selected";
private JLabel sourceLabel;
private JList sourceList;
private MyListModel sourceListModel;
private JList destList;
private MyListModel destListModel;
private JLabel destLabel;
private JButton addButton;
private JButton removeButton;
private JButton addAllButton;
private JButton removeAllButton;
private JButton upButton;
private JButton downButton;
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 newValue) {
fillListModel(sourceListModel, newValue);
}
public void setSourceElements(ListModel newValue) {
clearSourceListModel();
addSourceElements(newValue);
}
public void addDestinationElements(ListModel newValue) {
fillListModel(destListModel, newValue);
}
private void fillListModel(MyListModel model, ListModel newValues) {
int size = newValues.getSize();
for (int i = 0; i < size; i++) {
model.add(newValues.getElementAt(i));
System.out.println("adding .."+newValues.getElementAt(i));
}
}
public void addSourceElements(Object newValue[]) {
fillListModel(sourceListModel, newValue);
}
public void setSourceElements(Object newValue[]) {
clearSourceListModel();
addSourceElements(newValue);
}
public void addDestinationElements(Object newValue[]) {
fillListModel(destListModel, newValue);
}
private void fillListModel(MyListModel model, Object newValues[]) {
model.addAll(newValues);
}
public Iterator sourceIterator() {
return sourceListModel.iterator();
}
public Iterator destinationIterator() {
return destListModel.iterator();
}
public void setSourceCellRenderer(ListCellRenderer newValue) {
sourceList.setCellRenderer(newValue);
}
public ListCellRenderer getSourceCellRenderer() {
return sourceList.getCellRenderer();
}
public void setDestinationCellRenderer(ListCellRenderer 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]);
}
sourceList.getSelectionModel().clearSelection();
}
private void clearDestinationSelected() {
Object selected[] = destList.getSelectedValues();
for (int i = selected.length - 1; i >= 0; --i) {
destListModel.removeElement(selected[i]);
}
destList.getSelectionModel().clearSelection();
}
private void clearSourceAll() {
Object selected[] = ((MyListModel)sourceList.getModel()).toArray();
for (int i = selected.length - 1; i >= 0; --i) {
sourceListModel.removeElement(selected[i]);
}
sourceList.getSelectionModel().clearSelection();
}
private void clearDestinationAll() {
Object selected[] = ((MyListModel)destList.getModel()).toArray();
for (int i = selected.length - 1; i >= 0; --i) {
destListModel.removeElement(selected[i]);
}
destList.getSelectionModel().clearSelection();
}
private void initScreen() {
setBorder(BorderFactory.createEtchedBorder());
setLayout(new GridBagLayout());
sourceLabel = new JLabel(DEFAULT_SOURCE_CHOICE_LABEL);
sourceListModel = new MyListModel();
sourceList = new JList(sourceListModel);
sourceList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
if (me.getClickCount() == 2)
{
addDestinationElements(new Object[] { sourceList.getSelectedValue() });
clearSourceSelected();
}
}
});
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, 5, .5,
1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
EMPTY_INSETS, 0, 0));
addButton = new JButton(ADD_BUTTON_LABEL);
add(addButton, new GridBagConstraints(1, 1, 1, 1, 0, .1,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
addButton.addActionListener(new AddListener());
addAllButton = new JButton(ADD_ALL_BUTTON_LABEL);
add(addAllButton, new GridBagConstraints(1, 2, 1, 1, 0, .1,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
addAllButton.addActionListener(new AddAllListener());
removeButton = new JButton(REMOVE_BUTTON_LABEL);
add(removeButton, new GridBagConstraints(1, 4, 1, 1, 0, .1,
GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(
0, 5, 0, 5), 0, 0));
removeButton.addActionListener(new RemoveListener());
removeAllButton = new JButton(REMOVE_ALL_BUTTON_LABEL);
add(removeAllButton, new GridBagConstraints(1, 5, 1, 1, 0, .1,
GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(
0, 5, 0, 5), 0, 0));
removeAllButton.addActionListener(new RemoveAllListener());
destLabel = new JLabel(DEFAULT_DEST_CHOICE_LABEL);
destListModel = new MyListModel();
destList = new JList(destListModel);
destList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
destList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
if (me.getClickCount() == 2)
{
System.out.println("Double clicked on " + destList.getSelectedValue());
addSourceElements(new Object[] { destList.getSelectedValue() });
clearDestinationSelected();
}
}
});
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, 5, .5,
1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
EMPTY_INSETS, 0, 0));
upButton = new JButton(UP_BUTTON_LABEL) ;
upButton.addActionListener(new MoveUpListener());
downButton = new JButton(DOWN_BUTTON_LABEL) ;
downButton.addActionListener(new MoveDownListener());
add(upButton, new GridBagConstraints(3, 1, 1, 1, 0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
add(downButton, new GridBagConstraints(3, 2, 1, 1, 0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
EMPTY_INSETS, 0, 0));
}
public static void main(String args[]) {
JFrame f = new JFrame("Dual List Box Tester");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DualListBox dual = new DualListBox();
dual.addSourceElements(new String[] { "One", "Two", "Three" });
dual.addSourceElements(new String[] { "Four", "Five", "Six" });
dual.addSourceElements(new String[] { "Seven", "Eight", "Nine" });
dual.addSourceElements(new String[] { "Ten", "Eleven", "Twelve" });
dual
.addSourceElements(new String[] { "Thirteen", "Fourteen",
"Fifteen" });
dual.addSourceElements(new String[] { "Sixteen", "Seventeen",
"Eighteen" });
dual.addSourceElements(new String[] { "Nineteen", "Twenty", "Thirty" });
f.getContentPane().add(dual, BorderLayout.CENTER);
f.setSize(400, 300);
f.setVisible(true);
}
private class MoveUpListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object selected[] = destList.getSelectedValues();
int[] selectedindices = destList.getSelectedIndices();
destListModel.moveUp(selected);
int[] newselectedindices = new int[selectedindices.length];
for(int i =0; i <selectedindices.length;i++)
{
int oldindex = selectedindices[i];
if(oldindex != 0)
{
newselectedindices[i] = oldindex-1;
}
}
destList.setSelectedIndices(newselectedindices);
}
}
private class MoveDownListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object selected[] = destList.getSelectedValues();
int[] selectedindices = destList.getSelectedIndices();
destListModel.moveDown(selected);
int[] newselectedindices = new int[selectedindices.length];
for(int i =0; i <selectedindices.length;i++)
{
int oldindex = selectedindices[i];
if(oldindex != ((MyListModel)destList.getModel()).getSize())
{
newselectedindices[i] = oldindex+1;
}
}
destList.setSelectedIndices(newselectedindices);
}
}
private class AddListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object selected[] = sourceList.getSelectedValues();
addDestinationElements(selected);
clearSourceSelected();
}
}
private class AddAllListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object selected[] = ((MyListModel)sourceList.getModel()).toArray();
addDestinationElements(selected);
clearSourceAll();
}
}
private class RemoveListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object selected[] = destList.getSelectedValues();
addSourceElements(selected);
clearDestinationSelected();
}
}
private class RemoveAllListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object selected[] = ((MyListModel)destList.getModel()).toArray();
addSourceElements(selected);
clearDestinationAll();
}
}
}
class MyListModel extends AbstractListModel {
Vector model;
public MyListModel() {
model = new Vector();
}
public void moveUp(Object[] values)
{
for(int i=0; i <values.length; i++)
{
int firstindex = model.indexOf(values[i]);
Object selected = values[i];
if(firstindex == 0) break;
else
{
Object tempobj = model.get(firstindex-1);
model.set(firstindex-1,selected);
model.set(firstindex,tempobj);
fireContentsChanged(this, 0, getSize());
}
}
}
public void moveDown(Object[] values)
{
// for(int i=0; i <values.length; i++)
for(int i=values.length-1; i >=0; i--)
{
int firstindex = model.indexOf(values[i]);
Object selected = values[i];
if(firstindex == model.size()-1 ) break;
else
{
Object tempobj = model.get(firstindex+1);
model.set(firstindex+1,selected);
model.set(firstindex,tempobj);
fireContentsChanged(this, 0, getSize());
}
}
}
public int getSize() {
return model.size();
}
public Object getElementAt(int index) {
return model.toArray()[index];
}
public void add(Object element) {
if (model.add(element)) {
fireContentsChanged(this, 0, getSize());
}
}
public void addAll(Object elements[])
{
Collection c = Arrays.asList(elements);
model.addAll(c);
fireContentsChanged(this, 0, getSize());
}
public void clear() {
model.clear();
fireContentsChanged(this, 0, getSize());
}
public boolean contains(Object element) {
return model.contains(element);
}
public Iterator iterator() {
return model.iterator();
}
public Object[] toArray()
{
return model.toArray();
}
public boolean removeElement(Object element) {
boolean removed = model.remove(element);
if (removed) {
fireContentsChanged(this, 0, getSize());
}
return removed;
}
}
来源:https://stackoverflow.com/questions/62245469/java-swing-version-of-controlsfx-listselection-view