基于组件对JPanel进行排序

时间:2015-10-02 09:42:08

标签: java swing sorting jpanel

我的程序会生成0到12之间的随机数,但如果结果为12则会将短划线设置为JLabel的文本,而不是生成的数字。

现在,我想根据JPanel内容按升序对JLabel进行排序。如果数字相似,则黑色JPanels位于左侧。它工作正常,除非包含破折号,否则它不能正确排序。我想在任何地方插入包含短划线的JPanels,但它没有按预期工作。

来自我的程序的较短版本的屏幕截图:

纯数字:

enter image description here

包括短划线:

enter image description here

这是我的代码的较短版本(使用整数排序的逻辑):

import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.Comparator;

public class SortFrames extends JFrame
{
    static ArrayList<JPanel> panels = new ArrayList<JPanel>();
    JPanel panel = new JPanel();
    JPanel sortPane = new JPanel();
    int toWrite = 0;
    int colorGen = 0;
    int comparison = 0;
    Random rand = new Random();

    public SortFrames()
    {
        for(int i = 0; i<4;i++)
        {
            panels.add(new JPanel());
        }

        for(JPanel p: panels)
        {
            toWrite = rand.nextInt(13);
            colorGen = rand.nextInt(2);     
            p.add(new JLabel());
            JLabel lblToSet = (JLabel)p.getComponent(0);

            if(colorGen == 0)
            {
                p.setBackground(Color.BLACK);
                lblToSet.setForeground(Color.WHITE);
            }

            if(colorGen == 1)
            {
                p.setBackground(Color.WHITE);
                lblToSet.setForeground(Color.BLACK);
            }

            if(toWrite != 12){lblToSet.setText("" +toWrite);}           
            if(toWrite == 12){lblToSet.setText("-");}           
            p.setPreferredSize(new Dimension(30, 30));
            panel.add(p);
        }


        sortMethod();

        for(JPanel p: panels)
        {
            panel.add(p);
            panel.revalidate();
        }

        add(panel);
        panel.setPreferredSize(new Dimension(300, 300));
        setPreferredSize(new Dimension(300, 300));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        pack();
        setLocationRelativeTo(null);
    }

    public void sortMethod()
    {
        for(int i = 0; i<(panels.size());i++)
        {
            for(int j = i+1; j<(panels.size());j++)
            {
                JLabel one = (JLabel)(panels.get(i)).getComponent(0);
                JLabel two = (JLabel)(panels.get(j)).getComponent(0);
                String lblOne = one.getText();
                String lblTwo = two.getText();

                if(!lblOne.equals("-") && !lblTwo.equals("-"))
                {
                    int comp1 = Integer.parseInt(lblOne);
                    int comp2 = Integer.parseInt(lblTwo);
                    JPanel pnl1 = panels.get(i);
                    JPanel pnl2 = panels.get(j);        

                    if(comp1 == comp2)
                    {
                        if(pnl1.getBackground() == Color.BLACK && pnl2.getBackground() == Color.WHITE)          
                        {
                            panels.set(i, pnl1);
                            panels.set(j, pnl2);
                        }       

                        if(pnl1.getBackground() == Color.WHITE && pnl2.getBackground() == Color.BLACK)          
                        {
                            panels.set(i, pnl2);
                            panels.set(j, pnl1);
                        }
                    }

                    if(comp1 != comp2)
                    {
                        if(comp1>comp2)
                        {
                            panels.set(i, pnl2);
                            panels.set(j, pnl1);
                        }
                    }
                }

                if(lblOne.equals("-") && !lblTwo.equals("-"))
                {
                    JPanel pnl1 = panels.get(i);
                    panels.set(rand.nextInt(panels.size()), pnl1);
                }           

                if(!lblOne.equals("-") && lblTwo.equals("-"))
                {
                    JPanel pnl2 = panels.get(j);
                    panels.set(rand.nextInt(panels.size()), pnl2);
                }
            }       
        }
    }

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

我还有另一个方法,就是使用Comparator类也会产生同样的问题(根据前景排序相同的数字,但仍然相同,根据背景排序相同的数字,所以它没有效果在上述问题上)。

private static class JPanelSort implements Comparator<JPanel>
{
    @Override
    public int compare(JPanel arg0, JPanel arg1) 
    {
        JLabel one = ((JLabel) arg0.getComponent(0));
        JLabel two = ((JLabel) arg1.getComponent(0));
        String firstContent = one.getText();
        String secondContent = two.getText();       

        try
        {           
            comparisonRes = Integer.compare(Integer.parseInt(firstContent), Integer.parseInt(secondContent));       
            if(comparisonRes == 0)
            {           
                if(one.getForeground() == Color.BLACK && two.getForeground() == Color.WHITE)
                {
                    comparisonRes = 1;      
                }
                if(two.getForeground() == Color.BLACK && one.getForeground() == Color.WHITE)
                {
                    comparisonRes = -1;             
                }
            }
        }

        catch(NumberFormatException e)
        {
            comparisonRes = 0;
        }

       return comparisonRes;
     }       
}   

请告诉我你的想法。谢谢。

1 个答案:

答案 0 :(得分:3)

对数据进行排序比对JPanels排序要容易得多。

这是显示您的号码的mu GUI。

Sort Frames GUI

因此,让我们创建一个Java对象来保存卡数据。

public class DataModel {
    private final int number;
    private final int colorNumber;

    private final Color backgroundColor;
    private final Color foregroundColor;

    public DataModel(int number, int colorNumber, Color backgroundColor,
            Color foregroundColor) {
        this.number = number;
        this.colorNumber = colorNumber;
        this.backgroundColor = backgroundColor;
        this.foregroundColor = foregroundColor;
    }

    public int getNumber() {
        return number;
    }

    public int getColorNumber() {
        return colorNumber;
    }

    public Color getBackgroundColor() {
        return backgroundColor;
    }

    public Color getForegroundColor() {
        return foregroundColor;
    }

}

非常简单。我们有字段来保存信息和getter来检索信息。我们可以将所有字段设为最终字段,因为一旦设置了值,我们就不会更改任何字段。

排序类也非常简单。

public class DataModelComparator implements Comparator<DataModel> {

    @Override
    public int compare(DataModel o1, DataModel o2) {
        if (o1.getNumber() < o2.getNumber()) {
            return -1;
        } else if (o1.getNumber() > o2.getNumber()) {
            return 1;
        } else {
            if (o1.getColorNumber() < o2.getColorNumber()) {
                return -1;
            } else if (o1.getColorNumber() > o2.getColorNumber()) {
                return 1;
            } else {
                return 0;
            }
        }
    }

}

由于我们保留了颜色编号,因此按颜色排序就像对数字进行排序一样简单。

现在我们已经将数据移动到它自己的List中,我们可以专注于创建GUI。

package com.ggl.testing;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SortFrames implements Runnable {
    private List<DataModel> dataModels;

    private JPanel[] panels;

    private JLabel[] labels;

    private Random random = new Random();

    public SortFrames() {
        this.dataModels = new ArrayList<>();
        this.random = new Random();

        for (int i = 0; i < 4; i++) {
            int number = random.nextInt(13);
            int colorNumber = random.nextInt(2);
            Color backgroundColor = Color.BLACK;
            Color foregroundColor = Color.WHITE;
            if (colorNumber == 1) {
                backgroundColor = Color.WHITE;
                foregroundColor = Color.BLACK;
            }
            dataModels.add(new DataModel(number, colorNumber, backgroundColor,
                    foregroundColor));
        }

        Collections.sort(dataModels, new DataModelComparator());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Sort Frames");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel mainPanel = new JPanel();

        panels = new JPanel[dataModels.size()];
        labels = new JLabel[dataModels.size()];

        for (int i = 0; i < dataModels.size(); i++) {
            DataModel dataModel = dataModels.get(i);
            panels[i] = new JPanel();
            panels[i].setBackground(dataModel.getBackgroundColor());

            labels[i] = new JLabel(getDisplayText(dataModel));
            labels[i].setBackground(dataModel.getBackgroundColor());
            labels[i].setForeground(dataModel.getForegroundColor());

            panels[i].add(labels[i]);
            mainPanel.add(panels[i]);
        }

        frame.add(mainPanel);

        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }

    private String getDisplayText(DataModel dataModel) {
        if (dataModel.getNumber() == 12) {
            return "-";
        } else {
            return Integer.toString(dataModel.getNumber());
        }
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new SortFrames());
    }

    public class DataModel {
        private final int number;
        private final int colorNumber;

        private final Color backgroundColor;
        private final Color foregroundColor;

        public DataModel(int number, int colorNumber, Color backgroundColor,
                Color foregroundColor) {
            this.number = number;
            this.colorNumber = colorNumber;
            this.backgroundColor = backgroundColor;
            this.foregroundColor = foregroundColor;
        }

        public int getNumber() {
            return number;
        }

        public int getColorNumber() {
            return colorNumber;
        }

        public Color getBackgroundColor() {
            return backgroundColor;
        }

        public Color getForegroundColor() {
            return foregroundColor;
        }

    }

    public class DataModelComparator implements Comparator<DataModel> {

        @Override
        public int compare(DataModel o1, DataModel o2) {
            if (o1.getNumber() < o2.getNumber()) {
                return -1;
            } else if (o1.getNumber() > o2.getNumber()) {
                return 1;
            } else {
                if (o1.getColorNumber() < o2.getColorNumber()) {
                    return -1;
                } else if (o1.getColorNumber() > o2.getColorNumber()) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }

    }
}

这里要学到的经验是:

  1. 将数据与视图分开。
  2. 一次关注问题的一部分。分而治之。