SortedListModel和JList数字排序

时间:2016-02-27 06:39:54

标签: java sorting model jlist sortedlist

我有两个JLists来回移动项目。我在前面添加了一个带数字值的项目,例如。

1. A

2. B

3. C

...

10. j

问题是列表当前排序为1. 10. 2. 3.,10.紧跟在一个之后,并且不是最后一个项目,因为它应该通过数字排序。有人可以对此有所了解或帮我解决这个问题吗?谢谢!

import java.awt.*;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class DualListBox extends JPanel
{
    private static final Insets EMPTY_INSETS                = new Insets(0, 0, 0, 0);
    private static final String ADD_BUTTON_LABEL            = ">>";
    private static final String REMOVE_BUTTON_LABEL         = "<<";
    private static final String DEFAULT_TITLE               = "";
    private static final String DEFAULT_SOURCE_CHOICE_LABEL = "Included";
    private static final String DEFAULT_DEST_CHOICE_LABEL   = "Excluded";
    private JTextField          title;
    private JLabel              sourceLabel;
    private JList               sourceList;
    private SortedListModel     sourceListModel;
    private JList               destList;
    private SortedListModel     destListModel;
    private JLabel              destLabel;
    private JButton             addButton;
    private JButton             removeButton;

    public DualListBox()
    {
        initScreen();
    }

    private String getSourceChoicesTitle()
    {
        return sourceLabel.getText();
    }

    private void setSourceChoicesTitle(String newValue)
    {
        sourceLabel.setText(newValue);
    }

    private String getDestinationChoicesTitle()
    {
        return destLabel.getText();
    }

    private void setDestinationChoicesTitle(String newValue)
    {
        destLabel.setText(newValue);
    }

    private void clearSourceListModel()
    {
        sourceListModel.clear();
    }

    private void clearDestinationListModel()
    {
        destListModel.clear();
    }

    public void addSourceElements(ListModel newValue)
    {
        fillListModel(sourceListModel, newValue);
    }

    private void setSourceElements(ListModel newValue)
    {
        clearSourceListModel();
        addSourceElements(newValue);
    }

    public void addDestinationElements(ListModel newValue)
    {
        fillListModel(destListModel, newValue);
    }

    private void fillListModel(SortedListModel model, ListModel newValues)
    {
        int size = newValues.getSize();
        for (int i = 0; i < size; i++)
        {
            model.add(newValues.getElementAt(i));
        }
    }

    public void addSourceElements(Object newValue[])
    {
        fillListModel(sourceListModel, newValue);
    }

    private void setSourceElements(Object newValue[])
    {
        clearSourceListModel();
        addSourceElements(newValue);
    }

    public void addDestinationElements(Object newValue[])
    {
        fillListModel(destListModel, newValue);
    }

    private void fillListModel(SortedListModel model, Object newValues[])
    {
        model.addAll(newValues);
    }

    private Iterator sourceIterator()
    {
        return sourceListModel.iterator();
    }

    private Iterator destinationIterator()
    {
        return destListModel.iterator();
    }

    private void setSourceCellRenderer(ListCellRenderer newValue)
    {
        sourceList.setCellRenderer(newValue);
    }

    private ListCellRenderer getSourceCellRenderer()
    {
        return sourceList.getCellRenderer();
    }

    private void setDestinationCellRenderer(ListCellRenderer newValue)
    {
        destList.setCellRenderer(newValue);
    }

    private ListCellRenderer getDestinationCellRenderer()
    {
        return destList.getCellRenderer();
    }

    private void setVisibleRowCount(int newValue)
    {
        sourceList.setVisibleRowCount(newValue);
        destList.setVisibleRowCount(newValue);
    }

    private int getVisibleRowCount()
    {
        return sourceList.getVisibleRowCount();
    }

    private void setSelectionBackground(Color newValue)
    {
        sourceList.setSelectionBackground(newValue);
        destList.setSelectionBackground(newValue);
    }

    private Color getSelectionBackground()
    {
        return sourceList.getSelectionBackground();
    }

    private void setSelectionForeground(Color newValue)
    {
        sourceList.setSelectionForeground(newValue);
        destList.setSelectionForeground(newValue);
    }

    private 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();
    }

    public ArrayList<String> getSourceListModel()
    {
        ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i < sourceListModel.getSize(); ++i)
            list.add(sourceListModel.getElementAt(i).toString());
        return list;
    }

    public void printSource(ArrayList<String> list)
    {
        String str = "";
        for (int i = 0; i < list.size(); i++)
        {
            System.out.println(fixString((String) list.get(i)));
        }
    }

    public String fixString(String str)
    {
        str = str.replaceAll("\\d+\\.\\s", "");
        return str;
    }

    public boolean containsItem(SortedListModel list, String search)
    {
        return true;
    }

    private void initScreen()
    {
        setBorder(BorderFactory.createEtchedBorder());
        setLayout(new GridBagLayout());
        title = new JTextField("");
        title.setEditable(false);
        add(title, new GridBagConstraints(0, 0, 3, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                EMPTY_INSETS, 0, 0));

        sourceLabel = new JLabel(DEFAULT_SOURCE_CHOICE_LABEL);
        sourceListModel = new SortedListModel();

        sourceList = new JList(sourceListModel);
        sourceList.addListSelectionListener(new AddSelectionListener());
        add(sourceLabel, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
                EMPTY_INSETS, 0, 0));
        add(new JScrollPane(sourceList), new GridBagConstraints(0, 2, 1, 5, .5, 1, GridBagConstraints.CENTER,
                GridBagConstraints.BOTH, EMPTY_INSETS, 0, 0));

        addButton = new JButton(ADD_BUTTON_LABEL);
        add(addButton, new GridBagConstraints(1, 3, 1, 2, 0, .25, GridBagConstraints.CENTER, GridBagConstraints.NONE,
                EMPTY_INSETS, 0, 0));
        addButton.addActionListener(new AddListener());
        removeButton = new JButton(REMOVE_BUTTON_LABEL);
        add(removeButton, new GridBagConstraints(1, 5, 1, 2, 0, .25, GridBagConstraints.CENTER, GridBagConstraints.NONE,
                new Insets(0, 5, 0, 5), 0, 0));
        removeButton.addActionListener(new RemoveListener());

        destLabel = new JLabel(DEFAULT_DEST_CHOICE_LABEL);
        destListModel = new SortedListModel();

        destList = new JList(destListModel);
        destList.addListSelectionListener(new RemoveSelectionListener());
        add(destLabel, new GridBagConstraints(2, 1, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
                EMPTY_INSETS, 0, 0));
        add(new JScrollPane(destList), new GridBagConstraints(2, 2, 1, 5, .5, 1.0, GridBagConstraints.CENTER,
                GridBagConstraints.BOTH, EMPTY_INSETS, 0, 0));
    }

    public class AddListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            Object selected[] = sourceList.getSelectedValues();
            addDestinationElements(selected);
            title.setText("");
            clearSourceSelected();
            clearDestinationSelected();
        }
    }

    public class RemoveListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            Object selected[] = destList.getSelectedValues();
            addSourceElements(selected);
            title.setText("");
            clearSourceSelected();
            clearDestinationSelected();
        }
    }

    public class AddSelectionListener implements ListSelectionListener
    {
        public void valueChanged(ListSelectionEvent e)
        {
            if (!e.getValueIsAdjusting())
            {
                if (!sourceList.isSelectionEmpty())
                    title.setText(fixString(sourceList.getSelectedValue().toString()));
            }
        }
    }

    public class RemoveSelectionListener implements ListSelectionListener
    {
        public void valueChanged(ListSelectionEvent e)
        {
            if (!e.getValueIsAdjusting())
            {
                if (!destList.isSelectionEmpty())
                    title.setText(fixString(destList.getSelectedValue().toString()));
            }
        }
    }

}

class SortedListModel extends AbstractListModel
{

    SortedSet model;

    public SortedListModel()
    {
        model = new TreeSet();
    }

    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 Object firstElement()
    {
        return model.first();
    }

    public Iterator iterator()
    {
        return model.iterator();
    }

    public Object lastElement()
    {
        return model.last();
    }

    public boolean removeElement(Object element)
    {
        boolean removed = model.remove(element);
        if (removed)
        {
            fireContentsChanged(this, 0, getSize());
        }
        return removed;
    }
}

预先设置数组列表,并使用list.add("abc")等分配值。然后我们迭代数组并为每个元素添加数字,使其为1. abc等。

ArrayList<String>list = null;
String[] arr;

使用此类的Call样本是:

dual = new DualListBox();
arr = SharedFunctions.appendToArray(list, 0);
dual.addSourceElements(arr);
content.add(dual);

有问题的共享函数只是添加增量并在0处启动计数器。

public static String[] appendToArray(ArrayList<String> list, int count)
{
    count++;
    String[] temp = new String[list.size()];
    for (int i = 0; i < temp.length; i++)
    {
        temp[i] = count + ". " + list.get(i);
        count++;
    }
    return temp;        
}

如果您有任何疑问,请告诉我,如果您能帮我弄清楚如何解决这个问题,那么它会进行正确的数字排序,我真的很感激! :)

1 个答案:

答案 0 :(得分:0)

您应该将“索引”与“值”分开,以便您可以自定义排序以仅对“索引”值起作用,最终您如何做到这一点取决于您,例如,如果您要指定值的索引,您可以将两个参数分别传递给模型,这样可以让模型将值包装在可以自行管理的POJO中,例如......

Sorted

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.swing.AbstractListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            SortedListModel model = new SortedListModel();

            setLayout(new BorderLayout());
            add(new JScrollPane(new JList(model)));

            Random rnd = new Random();
            for (int index = 0; index < 100; index++) {
                int value = rnd.nextInt(100);

                model.add(value, "This is some data for " + index);
            }
        }

        public class SortedListModel extends AbstractListModel {

            private SortedSet<Data> model;

            public SortedListModel() {
                model = new TreeSet<>(new Comparator<Data>() {
                    @Override
                    public int compare(Data o1, Data o2) {
                        return o1.getIndex() - o2.getIndex();
                    }
                });
            }

            public void add(int index, Object value) {
                Data data = new Data(index, value);
                if (!model.contains(data)) {
                    model.add(data);
//                  int insertIndex = new ArrayList<Data>(model).indexOf(data);
                    int insertIndex = model.headSet(data).size();

                    fireIntervalAdded(data, insertIndex, insertIndex);
                }
            }

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

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

            protected class Data {
                private int index;
                private Object value;

                public Data(int index, Object data) {
                    this.index = index;
                    this.value = data;
                }

                public Object getValue() {
                    return value;
                }

                public int getIndex() {
                    return index;
                }

                @Override
                public String toString() {
                    return getIndex() + ". " + getValue();
                }

                @Override
                public int hashCode() {
                    int hash = 7;
                    hash = 97 * hash + this.index;
                    hash = 97 * hash + Objects.hashCode(this.value);
                    return hash;
                }

                @Override
                public boolean equals(Object obj) {
                    if (this == obj) {
                        return true;
                    }
                    if (obj == null) {
                        return false;
                    }
                    if (getClass() != obj.getClass()) {
                        return false;
                    }
                    final Data other = (Data) obj;
                    if (this.index != other.index) {
                        return false;
                    }
                    if (!Objects.equals(this.value, other.value)) {
                        return false;
                    }
                    return true;
                }



            }

        }
    }

}

如果索引不重要(并且只是渲染副作用),您可以使用自定义ListCellRenderer代替JScrollPane中的行标题来呈现“行”数字,进一步分离这两个概念