java - 使用设定数量的线程写入设定数量的进度条

标签 java timer jprogressbar

我昨天发帖,当时我完全不知道进度条是如何工作的。在获得一些帮助并进行工作后,我完成了更多工作,但我在更新进度条时遇到了困难。

我试图使用我的 setProgress 方法并在每次轮换时发送更新,但这似乎不起作用

很多人告诉我使用 Swing 计时器来发送进度,但我似乎不知道如何实现它。如果有人能向我展示他们将如何做到这一点,我会从中学到很多东西。

编辑:需要注意的重要地方很可能是我在 Robot 中的 run 方法以及整个进度条类。

目前代码的问题是没有进度更新。

机器人类

public class Robot implements Runnable{
public static final int on = 0x0001;
public static final int clockwise = 0x0002;
public static final int counter = 0x0004;
int  opcode;
int moveCount = 0;
int rotation, increment, progress = 0;
boolean CW;

ProgressBar prgBar;
CyclicBarrier cyclicBarrier;
Controller c;
Motor m;

public Robot(CyclicBarrier cyclicBarrier, Motor m)
{
    opcode = 0;
    this.cyclicBarrier = cyclicBarrier;
    this.m = m;
}


public Boolean Set(int value)
{
    boolean bvalue = false;
    switch (value)
    {
    case on : 
        bvalue = true;
        break;
    case clockwise :
        if ( (opcode & counter) == 0 )
            bvalue = true;
        break;
    case counter :
        if ( (opcode & clockwise) == 0 )
            bvalue = true;
        break;
    }
    if (bvalue == true)
        opcode += value;
    return bvalue;
}

private String Validate()
{
    String sresult = "Executing: ";
    boolean bvalue = false;
    if ((opcode & on) > 0)
    {
        bvalue = true;
        sresult = "On";
        if ((opcode & (clockwise+counter)) == (clockwise+counter))
            bvalue = false;
        if (bvalue == true)
        {   
            if ((opcode & clockwise) > 0)
                sresult +="+Clockwise";
            if ((opcode & counter) > 0)
                sresult += "+Counter";
        }
        if (bvalue == false)
            sresult = "Invalid opcode";
    }
    return sresult;
}

public void robotExecute()
{
    String svalue = Validate();
    System.out.println(svalue);
    opcode = 0;
}

public void setOn(ProgressBar prgBar){
    this.prgBar = prgBar;
    Set(1);
}


public void run(){
    System.out.println("Running: ");


    m.Engage(this);
    prgBar.setProgress(this, progress);
    try {
        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        cyclicBarrier.await();

    } catch (Exception e){
        e.printStackTrace();
    }
    System.out.println("Engaging: ");
}

public void Rotate(){
        if ((opcode & clockwise) > 0){
            rotation++;
            if(rotation == 360){
                rotation = 0;
                moveCount++;
            }
        }
        if ((opcode & counter) > 0){
            rotation--;
            if(rotation == -360){
                rotation = 0;
                moveCount --;
            }
        }
        prgBar.setProgress(this, progress);
}
}

进度条

public class ProgressBar implements ActionListener {

final int MAX = 100;
final JFrame frame = new JFrame("JProgress ");
final JProgressBar pbOne = new JProgressBar();
final JProgressBar pbTwo = new JProgressBar();
final JProgressBar pbThree = new JProgressBar();

private Map<Robot, JProgressBar> robotBars = new HashMap<>();

    public ProgressBar(){ 

        pbOne.setMinimum(0);
        pbOne.setMaximum(MAX);
        pbOne.setStringPainted(true);

        pbTwo.setMinimum(0);
        pbTwo.setMaximum(MAX);
        pbTwo.setStringPainted(true);

        pbThree.setMinimum(0);
        pbThree.setMaximum(MAX);
        pbThree.setStringPainted(true);

        frame.setLayout(new FlowLayout());
        frame.getContentPane().add(pbOne);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }

    public ProgressBar(Robot[] robots){
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        frame.setVisible(true);

        for(Robot r: robots) {
            JProgressBar bar = new JProgressBar();
            robotBars.put(r, bar);
            bar.setMinimum(0);
            bar.setMaximum(MAX);
            frame.setLayout(new FlowLayout());
            frame.add(bar);
        }

        /*Timer timer = new Timer(1000, new ActionListener(){
            public void actionPerformed(ActionEvent evt){
                bar.setValue(progress);
            }
        });*/
    }


    public void setProgress(Robot r, int progress){

        final JProgressBar bar = robotBars.get(r);
        if(bar == null) { return;}
        try{
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    bar.setValue(progress);
                }
            });
            java.lang.Thread.sleep(100);
        } catch (InterruptedException e) {
        JOptionPane.showMessageDialog(frame, e.getMessage());
        }
    }
}

我的汽车课 公共(public)课电机{ boolean 值 CW;

public void setMotor(Boolean CW, int increment, Robot r){
    if(CW == true){
        r.Set(1<<1);
    }
    else if (CW == false)
        ((Robot)r).Set(1<<2);

    r.increment = increment;
}

public void Engage(Robot r){
    System.out.println("Rotating: ");
    for(int i = 1; i <= r.increment; i++){
        r.Rotate(); 
    }   

    r.robotExecute();
    System.out.println("Finished");
}

}

最后是我的主课

public class Controller {

public static void main(String[] args){
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
    Motor m = new Motor();


    Robot xRob = new Robot(cyclicBarrier, m);
    Robot yRob = new Robot(cyclicBarrier, m);
    Robot zRob = new Robot(cyclicBarrier, m);

    Robot[] robotList = new Robot[]{xRob, yRob, zRob};

    Thread xRobThread = new Thread(xRob);
    Thread yRobThread = new Thread(yRob);
    Thread zRobThread = new Thread(zRob);

    ProgressBar prgBar = new ProgressBar(robotList);

    xRob.setOn(prgBar);
    yRob.setOn(prgBar);
    zRob.setOn(prgBar);

    boolean clockwise = true, counterClockwise = false;




    m.setMotor(clockwise, 14400000, xRob);
    m.setMotor(clockwise, 0, yRob);
    m.setMotor(counterClockwise, 36000000, zRob);

    xRobThread.start();
    yRobThread.start();
    zRobThread.start();

    try {
        xRobThread.join();
        yRobThread.join();
        zRobThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


    System.out.printf("x = %d y = %d z = %d\n\n", xRob.moveCount, yRob.moveCount, zRob.moveCount);

    /*m.setMotor(counterClockwise,  360000000, xRob);
    m.setMotor(clockwise, 1440000000, yRob);
    m.setMotor(clockwise, 1440000000, zRob);*/

}
}

最佳答案

经过调查,您遇到了一些问题。

您创建 GUI 的方式不正确,因此导致您的 JProgressBar 未出现在框架中。

基本上是在 ProgressBar(Robot[]) 你正在做的事情

frame.setSize(300, 200);
frame.setVisible(true);

在添加进度条之前,这是一个问题。在添加子项之前调用 setSize(...)...setVisible(true) 会导致不可预测的行为。如果您在添加进度条后将这两行移动到,它们应该出现在框架中;然而,你所做的并不是一个好的风格。

我会推荐类似的东西

Container pane = frame.getContentPane();
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

for(Robot r: robots) {
    JProgressBar bar = new JProgressBar();
    robotBars.put(r, bar);
    bar.setMinimum(0);
    bar.setMaximum(MAX);
    pane.add(bar);
}

frame.pack();
frame.setVisible(true);

使用a proper layout并调用pack自动调整框架大小。

你也不是creating your GUI on the EDT ,基本上您的 main 逻辑需要包装在对 invokeLater 的调用中。您对 join 的调用使情况变得复杂。也许快速修复是这样的:

public static void main(String[] args){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            // ... create GUI ... create Threads ...

            new Thread(new Runnable() {
                @Override
                public void run() {
                    // ... start Threads ... join Threads ...
                }
            }).start();
        }
    }
}

您没有更新进度,因此进度始终为0。

我不确定您实际上想要如何更新进度。为了测试的目的,我将其更改为:

//                               vv
prgBar.setProgress(this, progress++);
<小时/>

完成这些操作后,我会在框架中看到 JProgressBar,并且看到它们正在更新:

updating

<小时/>

其他事情:

  • javax.swing.Timer将替代Thread。也许您的 Motor 会创建一个 Timer 在计时器事件内进行旋转。这将代替调用 sleep 来管理您的旋转增量。
  • Java 中的方法名称按照惯例以小写字母开头。您的设置、旋转、接合等应为设置、旋转、接合等

关于java - 使用设定数量的线程写入设定数量的进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27094712/

相关文章:

java - 获取@XmlAttribute/@XmlValue 需要引用映射到 XML 文本的 Java 类型

java - 在 GUI 中显示时间

java - 如何使用定时器延迟java中的返回语句

java - 如何在 Zip writer 中使用进度条?

Java Path2D.closePath 无法正常工作?

java - 为什么我的纹理不起作用?

java - 从另一个线程内调用 TimerTask 是线程安全的

java - 如何让 JProgressBar 转到 "wait"屏幕

java - 为什么JProgressBar值不刷新?

java - Java 小程序的焦点