首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 多线程在SWING下的问题
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-14 21:35:54 楼主
    以下代码是来自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] == marked1 ¦ ¦ values[i] == marked2)
    g2.fill(bar);
    else
    g2.draw(bar);
    }
    }

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

    private Double marked1;
    private Double marked2;
    private Double[] values;
    }






    50  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-14 21:41:021楼 得分:0
    sycronized 一下那段代码试试
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-14 21:46:552楼 得分:0
    run方法加了 synchronized 还是不可以用.囧
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-15 00:13:273楼 得分:0
    本来以为是多线程的问题.现在发现原来不是.实际上是Arrays.sort(...);这个方法的实现上.理论上,当点击 Reset 时,应该让run方法重新去执行.否则, values发生了改变,Arrays.sort()中做的许多"工作成果"还保留在那里.并未清空.
    看来要给书上的那段代码添加 reset 功能得改很多东西=,= 努力ING
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-15 05:55:534楼 得分:0
    尽信书不如无书. 通过实践得出的才是真理.
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved