gpt4 book ai didi

java - 使用 ListModel 来隐藏 TreeSet

转载 作者:行者123 更新时间:2023-12-01 23:36:43 25 4
gpt4 key购买 nike

我的最终目标是拥有两个 JList,用户可以在它们之间来回移动元素。我使用 TreeSet 以便按字母顺序插入元素。这是一个直观的表示:

enter image description here

下面是我迄今为止的代码,位于 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);
}
}

最佳答案

这个实现似乎有效。请注意,我将 TreeSet 更改为简单的 List。缺点是插入/删除会慢一些,但至少我可以触发正确的事件。鉴于它是一个 UI 小部件,我认为这是可以接受的,因为底层模型永远不会很大(否则 UI 将变得不可用)。

我从 AbstractListModel 扩展,但您也可以从 DefaultListModel 扩展。在这种情况下,您可能希望确保 addElement 方法计算正确的索引并调用 super.add(calculatedIndex, element)

import java.awt.Dimension;
import java.awt.EventQueue;
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 AbstractListModel<String> {
private List<String> model = new ArrayList<>();

public StringListModel() {
}

public StringListModel( List<String> strings ) {
addAll( strings );
}

@Override
public int getSize() {
return model.size();
}

@Override
public String getElementAt( int index ) {
return model.toArray( new String[model.size()])[index];
}

public void addAll( Collection<String> strings ){
for ( String string : strings ) {
add( string );
}
}
public void add( String string ){
int index = calculateIndex( string );
model.add( index, string );
fireIntervalAdded( this, index, index );
}

public void remove( String string ){
int index = model.indexOf( string );
if ( index != -1 ){
model.remove( index );
fireIntervalRemoved( this, index, index );
}
}

public void removeAll( Collection<String> strings ){
for ( String next : strings ) {
remove( next );
}
}
private int calculateIndex( String input ){
if ( model.size() == 0 ){
return 0;
}
int index = 0;
while ( model.get( index ).compareTo( input ) <=0 ){
index++;
if ( index == model.size() ){
return index;
}
}
return index;
}
}

public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
@Override
public void run() {
new GUI().setVisible( true );
}
} );

}
}

关于java - 使用 ListModel 来隐藏 TreeSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18560930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com