내 최종 목표는 사용자가 요소를 앞뒤로 이동할 수있는 두 개의 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에서 동일한 문제가 발생했습니다. –