试图在摇摆工人内部绘制矩形

时间:2014-04-25 03:39:18

标签: java swing jframe jpanel

我有代码来创建一堆垂直矩形来可视化排序算法。

class MyGUI extends JComponent {
static int rectangleArray[][] = new int[50][2];
boolean populated = false;



public void paint(Graphics g) {
    int margin = 5;
    if (!populated) {
        populate();
        populated = true;
    }
    for (int i = 0; i < rectangleArray.length; i++) {
        if (rectangleArray[i][1] == 0) {
            g.setColor(Color.BLACK);
        } else if (rectangleArray[i][1] == 1) {
            g.setColor(Color.RED);
        } else if (rectangleArray[i][1] == 2) {
            g.setColor(Color.BLUE);
        }
        g.fillRect (margin, 305 - rectangleArray[i][0], 10, rectangleArray[i][0]);
        margin += 15;
        g.setColor(Color.BLACK);
    }
    insertionSort(); //i want to visually show the swaps here
}


public static void main(String[] a) {
    JFrame window = new JFrame();
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBounds(30, 30, 800, 600);
    window.getContentPane().add(new MyGUI());
    window.setVisible(true);
}
}

我试图在插入排序的每次迭代后基本上重绘画布。我知道我需要把它放到一个摇摆工人身上,我这样做的尝试就在这里:

public class GUIv3 extends JPanel
{
static int rectangleArray[][] = new int[50][2];
boolean populated = false;

private class UpdateTextFieldThread extends SwingWorker<Void, Integer>
{
    static final int THREAD_DELAY = 50;

    protected Void doInBackground()
    {
        //this is the insertion sort code
        for (int i = 0; i < rectangleArray.length; i++) {  
            int value = rectangleArray[i][0];  
            int j = i - 1;  
            while (j >= 0 && rectangleArray[j][0] > value) {  
                rectangleArray[j + 1][0] = rectangleArray[j][0];  
                j = j - 1;  
            }  
            rectangleArray[j + 1][0] = value;  
            //printNumbers(rectangleArray);
            try {
                repaint();
                Thread.sleep(THREAD_DELAY);
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        } 
        return null;
    }

}

public GUIv3()
{
    JFrame window = new JFrame();
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBounds(30, 30, 800, 600);
    window.getContentPane().add(new GUIv3());
    window.setVisible(true);
    int margin = 5;
    if (!populated) {
        populate();
        populated = true;
    }
    for (int i = 0; i < rectangleArray.length; i++) {
        //i cant exactly do anything to g since it doesn't exist here...
        if (rectangleArray[i][1] == 0) {
            g.setColor(Color.BLACK);
        } else if (rectangleArray[i][1] == 1) {
            g.setColor(Color.RED);
        } else if (rectangleArray[i][1] == 2) {
            g.setColor(Color.BLUE);
        }
        g.fillRect (margin, 305 - rectangleArray[i][0], 10, rectangleArray[i][0]);
        margin += 15;
        g.setColor(Color.BLACK);
    }
}

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

    public void populate() {
    for (int i = 0; i < rectangleArray.length; i++) {
        rectangleArray[i][0] = (int)(Math.random() * 300) + 1;
    }
}
}

我已经评论了我遇到问题的地方。关于如何在没有使用Graphics g的paint方法的情况下创建对象,我很遗憾。

谢谢!

1 个答案:

答案 0 :(得分:2)

  

我试图在插入排序的每次迭代后基本上重绘画布。我知道我需要把它放到一个摇摆工人身上,我这样做的尝试就在这里:

哎呀最简单的方法是使用Swing Timer。由于你是一次一步地重复排序,实际的单步排序应该几乎不需要任何处理时间,因此Timer应该为你提供足够的延迟,而不必混淆创建一个SwingWorker或任何其他直接后台主题。

  

如果我没有使用Graphics g的paint方法创建对象,我很遗憾。

很简单,只需专注于排序由数组或ArrayList等集合保存的数字,然后在JPanel的paintComponent(Graphics g)方法中,遍历数组或集合并绘制矩形基于集合中找到的数字,并使用JVM为paintComponent覆盖提供的Graphics对象。不要忘记先调用super的方法,以便删除上一张图。


修改
你问:

  

如何在paintComponent上实现swing计时器?我可以就如何启用摆动计时器和执行这些覆盖获得一些指导吗?

一个人不直接与另一个人互动。

  • 每次调用其actionPerformed方法时,Swing Timer的ActionListener将在排序迭代中执行新步骤。
  • 然后它将使用新值
  • 填充类实例字段int数组或ArrayList<Integer>
  • 然后在绘图矩形上调用repaint()
  • repaint()的调用将激发绘画级联,通常,从而导致JVM调用绘图JPanel的paintComponent方法。
  • 然后,此方法将使用数字遍历实例字段,并使用数字绘制矩形。
  • 同样,paintComponent方法不直接与Timer交互,甚至不知道它的存在。它所知道的就是遍历一个集合并绘制集合的可视化表示。
  • 并且Timer与paintComponent方法或Graphics对象没有直接交互。所有这一切都是一个排序步骤,将数据填充到绘图代码可用的某个位置,然后通过调用repaint()触发绘制。