以下代码是来自Core Java2 中AlgorithmAnimation类,
注释中的代码是为了给GUI提供一个重置的方法.但是现在发现一个BUG,无法修复.
运行时点击 Run 按扭,在没有排序完成的情况下,按下 Reset 就会有BUG..
求各位达人帮助.代码在下面;-)
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;
import java.util.concurrent.*;
import javax.swing.*;public class AlgorithmAnimation
{
public static void main(String[] args)
{
JFrame frame = new AnimationFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}class AnimationFrame extends JFrame
{
public AnimationFrame()
{
ArrayPanel panel = new ArrayPanel();
add(panel, BorderLayout.CENTER);

Double[] values = new Double[VALUES_LENGTH];
final Sorter sorter = new Sorter(values, panel);

JButton runButton = new JButton("Run");
runButton.addActionListener(new 
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
sorter.setRun();
}
});

// JButton resetButton = new JButton("Reset");
// resetButton.addActionListener(new 
// ActionListener()
// {
// public void actionPerformed(ActionEvent event)
// {
// sorter.reset();
// }
// });

JButton stepButton = new JButton("Step");
stepButton.addActionListener(new 
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
sorter.setStep();
}
});

JPanel buttons = new JPanel();
buttons.add(runButton);
// buttons.add(resetButton);
buttons.add(stepButton);
add(buttons, BorderLayout.NORTH);
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

for(int i = 0; i <  VALUES_LENGTH; i++)
values[i] = new Double(Math.random());

Thread t = new Thread(sorter);
t.start();
}

private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 300;
private static final int VALUES_LENGTH = 30;
}class Sorter implements Runnable
{
public Sorter(Double[] values, ArrayPanel panel)
{
this.values = values;
this.panel = panel;
this.gate = new Semaphore(1);
this.run = false;
// this.reset = false;
}

public void setRun()
{
run = true;
gate.release();
// reset = false;
}

public void setStep()
{
run = false;
// reset = false;
gate.release();
}

public void reset()
{
for(int i = 0; i <  values.length; i++)
values[i] = new Double(Math.random());
// reset = true;
run = false;
}

public void run() 
{
Comparator<Double> comp = new 
Comparator<Double>()
{
public int compare(Double i1, Double i2)
{
panel.setValues(values, i1, i2);
try
{
if(run)
Thread.sleep(DELAY);
else
gate.acquire();
}
catch(InterruptedException exception)
{
Thread.currentThread().interrupt();
}
return i1.compareTo(i2);
}
};
Arrays.sort(values, comp);
panel.setValues(values, null, null);
// while(true)
// {
// if(reset)
// {
// run();
// break;
// }
// try
// {
// Thread.sleep(100);
// }
// catch(InterruptedException e) {}
// }
}

private Double[] values;
private ArrayPanel panel;
private Semaphore gate;
private static final int DELAY = 100;
private boolean run;
// private boolean reset;
}class ArrayPanel extends JPanel
{
public void paintComponent(Graphics g)
{
if(values == null) return;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int width = getWidth() / values.length;
for(int i = 0; i < values.length; i++)
{
double height = values[i] * getHeight();
Rectangle2D bar = new Rectangle2D.Double(width * i, 0, width, height);
if(values[i] == ed1 || values[i] == ed2)
g2.fill(bar);
else
g2.draw(bar);
}
}

public void setValues(Double[] values, Double ed1, Double ed2)
{
this.values = values;
this.ed1 = ed1;
this.ed2 = ed2;
repaint();
}

private Double ed1;
private Double ed2;
private Double[] values;
}




解决方案 »

  1.   

    sycronized 一下那段代码试试
      

  2.   

    run方法加了 synchronized 还是不可以用.囧
      

  3.   

    本来以为是多线程的问题.现在发现原来不是.实际上是Arrays.sort(...);这个方法的实现上.理论上,当点击 Reset 时,应该让run方法重新去执行.否则, values发生了改变,Arrays.sort()中做的许多"工作成果"还保留在那里.并未清空.
    看来要给书上的那段代码添加 reset 功能得改很多东西=,= 努力ING