0

我正在做一个程序,它创建一个由 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();
}

我遇到的问题是,当我单击面板时,框架中没有任何内容被绘制。有人可以告诉我我在做什么有什么问题吗?

如果有帮助,这是来自 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>
4

1 回答 1

3

以下是一些建议:

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

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

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

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

  5. 看起来像drawPass颠倒绘制矩形。

这是一个使用现有代码的示例,只进行了最少的更改:

在此处输入图像描述 在此处输入图像描述

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);
    }
}
于 2013-04-18T04:22:06.643 回答