0

I posted yesterday, when I had absolutely no knowledge of how progress bar works. After getting some help and working on it I have a lot more done, but I'm getting stuck at updating the bars with progress.

I was trying to use my setProgress method and sending updates everytime there was a rotation, but that doesn't seem to be working

Many people told me to use a swing timer to send the progress, but I don't seem to get how to implement it. If somebody could show me how they would do it I would learn a great deal from that.

Edit: The important places to look at would most likely be my run method in Robot and the entirety of my progressbar class.

The problem with the code currently is no progress is updated.

Robot Class

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);
}
}

ProgressBar

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());
        }
    }
}

My Motor class public class Motor { 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");
}

}

and last my Main Class

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);*/

}
}
Arian.No
  • 3
  • 1
  • 5
  • What is the symptom here? What seems to be the problem? Consider posting an [MCVE](http://stackoverflow.com/help/mcve). – Radiodef Nov 23 '14 at 21:50
  • The issue is progress isn't being updated. I included all the code incase somebody wanted to debug, but the MCVE would be my Robot class and the ProgressBar Class with the other two being unimportant to the problem. – Arian.No Nov 23 '14 at 21:56

1 Answers1

1

On investigation, you have a couple of problems.

The way you are creating your GUI is incorrect, so it is causing your JProgressBars to not appear in the frame.

Basically in ProgressBar(Robot[]) you are doing

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

before adding your progress bars and it is a problem. Calling setSize(...)...setVisible(true) before the children are added leads to unpredictable behavior. If you just move these two lines to after you add the progress bars, they should appear in the frame; however, what you are doing is not a good style.

I would recommend something like

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);

Using a proper layout and calling pack to size the frame automatically.

You are also not creating your GUI on the EDT, basically your main logic needs to be wrapped in a call to invokeLater. This is complicated by your calls to join. Maybe a quick fix is something like:

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();
        }
    }
}

You are not updating progress so progress is always 0.

I am not sure how you actually want to update the progress. For the purpose of testing I changed it to this:

//                               vv
prgBar.setProgress(this, progress++);

Once I did those things, I see the JProgressBars in the frame and I see them updating:

updating


Other things:

  • javax.swing.Timer would be a replacement for Threads. Maybe your Motor would create a Timer that did a rotation inside the timer event. This would be instead of calling sleep to manage your rotation increments.
  • Method names in Java start with a lowercase letter by convention. Your Set, Rotate, Engage, etc should be set, rotate, engage, etc.
Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • Oh, thanks. I missed this, but I ended up doing pretty much exactly what you said here, besides the boxlayout. And it's working now. Thank you very much for your advice. Those methods were actually given to me by my instructor funny enough, and yeah I do remember the naming convention. I'll change them. – Arian.No Nov 24 '14 at 07:24
  • Oh thanks for letting me know. I had no idea about that sorry. I was wondering how I could give you credit for answering without being able to vote yet... – Arian.No Nov 24 '14 at 08:02