Java 绘制视觉选择排序

Java 绘制视觉选择排序,java,swing,sorting,Java,Swing,Sorting,我正在做一个程序,创建一个由50个数字组成的数组,然后在面板中将它们绘制为矩形,大小基于数字。单击面板时,将对数组进行排序,并重新绘制面板,以显示正在排序的数字的动画排序。 以下是单击面板前后的外观: 这是我的代码: public class AnimatedSelectionSortPanel extends javax.swing.JPanel { int[] numbers = new int[50]; int min = 20; int max = 100; private voi

我正在做一个程序,创建一个由50个数字组成的数组,然后在面板中将它们绘制为矩形,大小基于数字。单击面板时,将对数组进行排序,并重新绘制面板,以显示正在排序的数字的动画排序。 以下是单击面板前后的外观:

这是我的代码:

public class AnimatedSelectionSortPanel extends javax.swing.JPanel {

int[] numbers = new int[50];
int min = 20;
int max = 100;

private void loadArray() {
    int num;
    for (int i = 0; i < numbers.length; i++) {
        numbers[i] = min + (int) Math.random() * ((max - min) + 1);
    }
}

public static void selectionSort(int[] x) {
    for (int i = 0; i < x.length - 1; i++) {
        int minIndex = i;      // Index of smallest remaining value.
        for (int j = i + 1; j < x.length; j++) {
            if (x[minIndex] > x[j]) {
                minIndex = j;  // Remember index of new minimum
            }
        }
        if (minIndex != i) {
            //...  Exchange current element with smallest remaining.
            int temp = x[i];
            x[i] = x[minIndex];
            x[minIndex] = temp;
        }
    }
}

private void drawPass(Graphics g) {
    int xPos = 10;
    int yPos = 120;
    int rectWidth = 1;

    for (int num : numbers) {
        g.setColor(Color.black);
        g.drawRect(xPos, yPos, rectWidth, num);
        xPos += 11;
    }
}

@Override
public void paintComponent (Graphics g) {
    while (numbers.length == 0) {
        loadArray();
    }
    drawPass(g);
}

private void sortPanelMouseClicked(java.awt.event.MouseEvent evt) {
    selectionSort(numbers);
    sortPanel.repaint();
}
public类AnimatedSelectionSortPanel扩展javax.swing.JPanel{
整数[]个数=新整数[50];
int min=20;
int max=100;
私有void loadArray(){
int-num;
for(int i=0;ix[j]){
minIndex=j;//记住新最小值的索引
}
}
if(minIndex!=i){
//…将当前元素与剩余的最小元素交换。
int temp=x[i];
x[i]=x[minIndex];
x[minIndex]=温度;
}
}
}
专用空心抽油孔(图g){
int xPos=10;
int yPos=120;
int rectWidth=1;
for(整数:数字){
g、 设置颜色(颜色为黑色);
g、 drawRect(xPos、YPO、rectWidth、num);
xPos+=11;
}
}
@凌驾
公共组件(图形g){
while(number.length==0){
loadArray();
}
抽油通道(g);
}
私有void sortPanelMouseClicked(java.awt.event.MouseEvent evt){
选择排序(数字);
sortPanel.repaint();
}
我遇到的问题是,当我单击面板时,框架中没有任何东西被绘制。有人能告诉我我所做的有什么问题吗

以下是GUI生成器自动生成的代码(如果有帮助):

    private void initComponents() {

    sortPanel = new javax.swing.JPanel();

    sortPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
    sortPanel.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            sortPanelMouseClicked(evt);
        }
    });

    javax.swing.GroupLayout sortPanelLayout = new javax.swing.GroupLayout(sortPanel);
    sortPanel.setLayout(sortPanelLayout);
    sortPanelLayout.setHorizontalGroup(
        sortPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 398, Short.MAX_VALUE)
    );
    sortPanelLayout.setVerticalGroup(
        sortPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 165, Short.MAX_VALUE)
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(sortPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addComponent(sortPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
}// </editor-fold>
private void initComponents(){
sortPanel=newjavax.swing.JPanel();
setBorder(javax.swing.BorderFactory.createLineBorder(新java.awt.Color(0,0,0));
addMouseListener(新java.awt.event.MouseAdapter(){
public void mouseClicked(java.awt.event.MouseEvent evt){
sortPanelMouseClicked(evt);
}
});
javax.swing.GroupLayout sortPanelayout=新建javax.swing.GroupLayout(sortPanel);
sortPanel.setLayout(sortPanelLayout);
SortPanelayout.setHorizontalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0,398,短。最大值)
);
sortPanelLayout.setVerticalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0,165,短。最大值)
);
javax.swing.GroupLayout=newjavax.swing.GroupLayout(this);
这个.setLayout(布局);
layout.setHorizontalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(sortPanel,javax.swing.GroupLayout.PREFERRED\u大小,javax.swing.GroupLayout.DEFAULT\u大小,javax.swing.GroupLayout.PREFERRED\u大小)
);
layout.setVerticalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(sortPanel,javax.swing.GroupLayout.PREFERRED\u大小,javax.swing.GroupLayout.DEFAULT\u大小,javax.swing.GroupLayout.PREFERRED\u大小)
.addContainerGap(javax.swing.GroupLayout.DEFAULT\u SIZE,Short.MAX\u VALUE))
);
}// 

以下是一些建议:

  • 请发布一个可编译的示例-SSCCE

  • 不要在
    paintComponent
    中加入太多逻辑,也不要用这种方法分配数据。它的目的是绘制。提前准备好数字数组

  • min+(int)Math.random()*((max-min)+1);
    始终为20,因为
    (int)Math.random()
    始终为零。您应该强制转换结果,即:
    min+(int)(Math.random()*((max-min)+1));

  • 将排序过程包装到线程或计时器中。在迭代之间等待并调用
    repaint()
    绘制中间结果。包装到Swing计时器更干净、更可取,但在发布的代码中,将
    selectionSort
    的整个逻辑转储到线程中可能更容易/更快。有关一些示例,请参阅教程。另请参阅

  • 看起来像是
    drawPass
    将矩形倒置绘制

  • 下面是一个使用现有代码进行最小更改的示例:

    import java.awt.*;
    导入java.awt.event.*;
    导入javax.swing.JFrame;
    导入javax.swing.SwingUtilities;
    公共类AnimatedSelectionSortPanel扩展了javax.swing.JPanel{
    公共静态void main(字符串[]args){
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    JFrame=新JFrame();
    frame.add(新的动画SelectionSortPanel());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setLocationByPlatform(真);
    frame.setVisible(true);
    }
    });
    }
    私有整数[]个数=新整数[50];
    私有整数最小值=20;
    私人int最大值=100;
    私有布尔洗牌=false;
    公共静态最终int迭代_SLEEP=100;
    公共动画选择或面板(){
    loadArray();
    addMouseListener(新的MouseAdapter(){
    @凌驾
    公共无效mouseClicked(MouseEvent e){
    如果(洗牌)
    loadArray();
    选择排序(数字);
    洗牌=正确;
    }
    });
    }
    @凌驾
    公共维度getPreferredSize(){
    返回新维度(300100);
    }
    私有void loadArray(){
    F
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    public class AnimatedSelectionSortPanel extends javax.swing.JPanel {
    
        public static void main(String[] args){
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new AnimatedSelectionSortPanel());
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationByPlatform(true);
                    frame.setVisible(true);
                }
            });
        }
    
    
        private int[] numbers = new int[50];
        private int min = 20;
        private int max = 100;
        private boolean shuffle = false;
        public static final int ITERATION_SLEEP = 100;
    
        public AnimatedSelectionSortPanel() {
            loadArray();
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (shuffle)
                        loadArray();
                    selectionSort(numbers);
                    shuffle = true;
                }
            });
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 100);
        }
    
        private void loadArray() {
            for (int i = 0; i < numbers.length; i++) {
                numbers[i] = min + (int) (Math.random() * ((max - min) + 1));
            }
        }
    
        public void selectionSort(final int[] x) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                        for (int i = 0; i < x.length - 1; i++) {
                        int minIndex = i; // Index of smallest remaining value.
                        for (int j = i + 1; j < x.length; j++) {
                            if (x[minIndex] > x[j]) {
                                minIndex = j; // Remember index of new minimum
                            }
                        }
                        if (minIndex != i) {
                            // ... Exchange current element with smallest remaining.
                            int temp = x[i];
                            x[i] = x[minIndex];
                            x[minIndex] = temp;
                        }
                        repaint();
                        try {
                            Thread.sleep(ITERATION_SLEEP);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }               
                }
            }).start();
        }
    
        private void drawPass(Graphics g) {
            int rectWidth = 1;
    
            int width = getWidth() - 1;
            int height = getHeight() - 1;
            int colSpan = Math.round((float)width / (float)numbers.length);
            int x = 0;
    
            for (int num : numbers) {
                int colHeight = (int) ((float) height * ((float) num / (float) 100));
                g.fillRect(x, height - colHeight, rectWidth, colHeight);
                 x += colSpan;
            }
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            drawPass(g);
        }
    }