我的最終目標是有兩個JList
之間的用戶可以來回移動元素。我正在使用TreeSet
,以便按字母順序插入元素。這裏有一個直觀表示:使用ListModel陰影TreeSet
下面是我的代碼到目前爲止,其在SSCCE。它主要是在工作,但我有時會得到一個ArrayOutOfBoundsException
。問題與程序思考有關,選擇的元素比實際選擇的要多。重新創建問題的一種方法是在左側選擇兩個元素,然後按右側按鈕兩次。
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;
public class GUI extends JFrame {
private GridBagLayout gridBag = new GridBagLayout();
private static final String[] ALL_STRINGS = { "B", "A", "C" };
private JButton leftButton = new JButton("<");
private JButton rightButton = new JButton(">");
private StringListModel listModel = new StringListModel(Arrays.asList(ALL_STRINGS));
private StringListModel queueModel = new StringListModel();
private JList<String> list = new JList<String>(listModel);
private JList<String> queue = new JList<String>(queueModel);
public GUI() {
setWindowProperties();
addComponents();
}
private void setWindowProperties() {
setLayout(gridBag);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(300, 200));
setTitle("JList, ListModel, and TreeSet");
setResizable(false);
setLocationRelativeTo(null);
}
private void addComponents() {
leftButton.addActionListener(new QueueListener());
rightButton.addActionListener(new QueueListener());
JScrollPane listScroll = new JScrollPane(list);
JScrollPane queueScroll = new JScrollPane(queue);
Dimension scrollSize = new Dimension(50, 100);
listScroll.setPreferredSize(scrollSize);
queueScroll.setPreferredSize(scrollSize);
add(listScroll);
add(leftButton);
add(rightButton);
add(queueScroll);
}
private class QueueListener implements ActionListener {
private JButton button;
@Override
public void actionPerformed(ActionEvent e) {
button = (JButton) e.getSource();
if (button.equals(leftButton)) {
removeFromQueue();
} else if (button.equals(rightButton)) {
addToQueue();
}
}
private void removeFromQueue() {
List<String> Strings = queue.getSelectedValuesList();
queueModel.removeAll(Strings);
listModel.addAll(Strings);
}
private void addToQueue() {
List<String> Strings = list.getSelectedValuesList();
listModel.removeAll(Strings);
queueModel.addAll(Strings);
}
}
private class StringListModel extends DefaultListModel<String> {
private TreeSet<String> model = new TreeSet<String>();
public StringListModel() {
}
public StringListModel(List<String> Strings) {
addAll(Strings);
}
public int getSize() {
return model.size();
}
public String getElementAt(int index) {
return (String) model.toArray()[index];
}
public void add(String String) {
if (model.add(String)) {
fireContentsChanged(this, 0, getSize());
}
}
public void addAll(List<String> quets) {
for (String String : quets) {
model.add(String);
}
fireContentsChanged(this, 0, getSize());
}
public void clear() {
model.clear();
fireContentsChanged(this, 0, getSize());
}
public boolean contains(Object element) {
return model.contains(element);
}
public String firstElement() {
return model.first();
}
public Iterator iterator() {
return model.iterator();
}
public String lastElement() {
return model.last();
}
public void removeAll(Collection<?> elements) {
for (Object element : elements) {
removeElement(element);
}
fireContentsChanged(this, 0, getSize());
}
public boolean removeElement(Object element) {
boolean removed = model.remove(element);
if (removed) {
fireContentsChanged(this, 0, getSize());
}
return removed;
}
}
public static void main(String[] args) {
new GUI().setVisible(true);
}
}
我沒有詳細檢查了它,但你的'StringListModel'是完全錯誤的。如果你從'DefaultListModel'擴展,你應該使用它的add/remove/...方法。我強烈建議你的情況直接實現接口或從'AbstractListModel'擴展而不是 – Robin
我遇到了與AbstractListModel相同的問題。 –