2

Problem:

ClassA
    static JProgressBar progressBar;
ClassB
    ClassA.progressBar.setValue(0);
    ...
    ClassA.progressBar.setValue(10);
    ...
    ClassA.progressBar.setValue(20);

Progress bar displays 0, then 10 on top of the 0, then 20 on top of the 10.

Code:

public class ClassA
{
    static JProgressBar progressBar;
    public ClassA()
    {
        ...
        progressBar = new JProgressBar(0, 100);
        progressBar.setStringPainted(true);
        ...
    }
    public static void main(String[] args)
    {
        ClassA cA = new ClassA();
        cA.something();
    }
    public void something()
    {
        ...
        panel.add(progressBar, BorderLayout.CENTER);
        ...
    }
    ...
}
public class ClassB
{
    public void something()
    {
        ...
        ClassA.progressBar.setValue(0);
        ClassA.progressBar.update(ClassA.progressBar.getGraphics());
        ...
    }
    ...
}

I am also adding the progress bar to the panel. As it was mentioned above, it displays the progress bar and the percentage but it show each value on top of another.

EDIT: The problem is very similar to this: Java Swing revalidate() vs repaint(). However, instead of

the old content is still actually visible (though obscured by the the new content)

being problem with JPanel, mine is problem with JProgressBar. I tried ClassA.progressBar.revalidate(); and ClassA.progressBar.repaint(); but nothing works except ClassA.progressBar.update(ClassA.progressBar.getGraphics());, which, again, as it was mentioned above, displays new values on top of old values.

Community
  • 1
  • 1
Arthur
  • 223
  • 2
  • 16
  • Care to post a little context, a little more code, and a little more explanation? Also, why the static variable? – Hovercraft Full Of Eels Apr 23 '13 at 01:11
  • 3
    You'll get better answers if you provide a [SSCCE](http://sscce.org/) – MadProgrammer Apr 23 '13 at 01:11
  • @Hovercraft Full Of Eels, static variable because I am setting value without creating object. – Arthur Apr 23 '13 at 01:15
  • 1
    *"I am setting value without creating object*" ?? How is that possible? – MadProgrammer Apr 23 '13 at 01:16
  • "ClassA.progressBar.setValue(0);"? – Arthur Apr 23 '13 at 01:17
  • 1
    `"static variable because I am setting value without creating object."` -- That makes no sense at all whatsoever. – Hovercraft Full Of Eels Apr 23 '13 at 01:18
  • 2
    He means he's setting the value of `progressBar` without creating an instance of `ClassA`. – wchargin Apr 23 '13 at 01:25
  • OK, but what advantage is that? He's still stuck with a static component that can't be used in any sort of OOPs fashion. – Hovercraft Full Of Eels Apr 23 '13 at 01:33
  • @WChargin, sorry, yes. – Arthur Apr 23 '13 at 01:34
  • @Hovercraft Full Of Eels, if I create "ClassA cA = new ClassA();" and then, "cA.someMethodWhichContainsAPossibilityToAddToTheProgressBar(i);", it gives me an error. – Arthur Apr 23 '13 at 01:37
  • @WChargin: But he *still* needs to call the constructor to instantiate a *static* variable. This is very poor programming form. To the original poster, create and post an [sscce](http://sscce.org). Your little snippets are not helping us figure out your problem. – Hovercraft Full Of Eels Apr 23 '13 at 01:37
  • Arthur: "it gives me an error" doesn't tell us much. If you're getting an error, edit the original post, show the actual code, show the actual error message, and let us help you. – Hovercraft Full Of Eels Apr 23 '13 at 01:38
  • @HovercraftFullOfEels not necessarily; see [this example](http://pastebin.com/yPTN2Sd2). However, it definitely is poor form and an SSCCE would be much better. – wchargin Apr 23 '13 at 01:57
  • 1
    @WChargin: i'm not saying that it can't be done. You could use static initializer blocks, but it just suggests bad design all around for this program. – Hovercraft Full Of Eels Apr 23 '13 at 01:58
  • 1
    I think the problem is with the "ClassA.progressBar.update(ClassA.progressBar.getGraphics());" not the "JProgressBar progressBar;" being static. – Arthur Apr 23 '13 at 15:37
  • `.update()` isn't what you want to use - `repaint()` is closer to what you want - but really you shouldn't even need that - setting the value through `setValue` should update it. – Nate Apr 25 '13 at 16:35

2 Answers2

7

You don't need this line:

ClassA.progressBar.update(ClassA.progressBar.getGraphics());

Calling setValue() will update the progress bar UI.

Otherwise there is nothing wrong with the code you posted here. The issue must lie elsewhere. Here's a SSCCE based on your code, which works as expected with no paint issues.

public class ClassA {
    static JProgressBar progressBar;
    private ClassB classb;
    private JPanel panel;


    public ClassA() {
        progressBar = new JProgressBar(0, 100);
        progressBar.setStringPainted(true);

        classb = new ClassB();

        JButton button = new JButton("test");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                classb.something();
            }
        });

        panel = new JPanel();
        panel.add(button);
        panel.add(progressBar, BorderLayout.CENTER);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }


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

public class ClassB
{
    private int index;

    public void something()
    {
        ClassA.progressBar.setValue(++index);
        //ClassA.progressBar.update(ClassA.progressBar.getGraphics());
    }
}
martinez314
  • 12,162
  • 5
  • 36
  • 63
3

Arthur, your code snippet doesn't show how ClassB.something gets called. Most of Swing is not thread safe and unless the javadoc explicitly states otherwise, Swing ui components need to be modified from the Event Dispatch Thread. Usually if a Swing component is thread-safe it explicitly calls this out in the javadoc. I took a look at the JProgressBar javadoc and saw no disclaimer, actually it has a warning that Swing is not threadsafe.
If Swing components are accessed from other threads it can cause applications to behave strangely. I've seen components render strangely and incompletely because of improper threading. If ClassA is going to construct and modify swing components in the constructor, the constructor should get executed from the Event Dispatch Thread.

public class ClassA 
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new ClassA());
    }
}
Ryan
  • 2,061
  • 17
  • 28
  • +1, certainly worth a try since we don't have any context about where this is even getting called. – Brian May 01 '13 at 22:43