7

I tried out the function of the JProgressBar in Java. But there is a problem I couldn't solve:

When I set the minimum to zero, the maximum value to 100 and the current value to 6 then nothing will be displayed. The progress bar is empty. If I put 7 as current value then it works. It seems to be a problem with any empty border or other space. The problem occurs with Windows 7 and only if the UIManager is set to SystemLookAndFeel.

Does anyone knows this problem and has a solution for this? Below is my code:

package lab;

import java.awt.FlowLayout;

import javax.swing.JDialog;
import javax.swing.JProgressBar;
import javax.swing.UIManager;

import core.Config;


public class ProgressSample extends JDialog {

public ProgressSample() {

    setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    getContentPane().setLayout(new FlowLayout());

              // Nothing is displayed
    JProgressBar progressSix = new JProgressBar(0, 100);
    progressSix.setValue(6);
    getContentPane().add(progressSix);

              // This works
    JProgressBar progressSeven = new JProgressBar(0, 100);
    progressSeven.setValue(7);
    getContentPane().add(progressSeven);

    pack();
}

public static void main(String[] args) {

    try {
        UIManager.setLookAndFeel(UIManager
        .getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }

    ProgressSample dialogTest = new ProgressSample();
    dialogTest.setVisible(true);
}

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Benchy
  • 126
  • 1
  • 4
  • 2
    Huh. Interesting. It kicks in at around 66/1000ths. That is odd. Have you checked the [Bug DB](http://bugs.sun.com/)? Check it, and if you cannot find anything similar, post a new report for evaluation. – Andrew Thompson Jan 28 '13 at 11:16
  • I couldn't find any Bug reported for this. If I can't fix the problem I will post a report. But as you see, my knowledge in english isn't very well... – Benchy Jan 28 '13 at 11:32
  • 1
    in JDK7_011 presented too – mKorbel Jan 28 '13 at 11:38
  • 2
    *"my knowledge in english isn't very well"* Your use of English is good enough for me to know exactly what you mean. At least I think I do. It does not really matter anyway, since it is mostly the code that 'does the talking' - and it speaks loud & clear. :) – Andrew Thompson Jan 28 '13 at 11:44
  • @AndrewThompson ah great words! +1 – joey rohan Jan 28 '13 at 12:19

3 Answers3

8

The java code for a Windows native look-and-feel progress bar renders using PROGRESSCHUNKSIZE steps in the manner of the original windows progress bar. Please see the source for the Windows JProgressBar.

It's just not rendering it smoothly. If you step the progress bar you can see the chunks.

It may be customizable, but I don't know how you would accomplish it.

Origin of the Issue

The original windows XP progress bar was in little boxes. The theme defined a size of the box, and the gap between the box. For Vista and later, the theme was changed to specify the gap between the box as 0, but never reset the size of the box to 1 pixel. Reading the value through the OpenThemeData and GetThemeInt Win32API functions reveals that the chunk size is 6 for my theme (Windows 8).

Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
  • I was unconvinced of this answer till I saw your comment about 'string painted' and tried it! This is a tricky bug indeed. – Andrew Thompson Jan 28 '13 at 12:44
  • I can extend BasicProgressBarUI and override getCellLength() and getCellSpacing(). But when I try to extend from WindowsProgressBarUI an error occurs: "Access restriction: The type WindowsProgressBarUI is not accessible due to restriction on required library" – Benchy Jan 28 '13 at 18:40
  • 1
    Your error is a 'for your own safety' mechanism in eclipse. I tried a copy-paste of the method from the implementation, but a bunch of the classes/types are non-public, and so can't be used. – Anya Shenanigans Jan 28 '13 at 20:32
2

It looks like a layout issue / bug when setting the system L&F.

I managed to hide the bug by setting a preferred size to the progress bar with the issue:

progressSix.setPreferredSize(new Dimension(200, 15));

It seems to be related to the progress bar size. If I use a BoxLayout instead of the FlowLayout and resize the container enough, I can see it displaying even for smaller values.

Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • Interesting. So much as 1 pixel wider than preferred size fixes the problem. – Andrew Thompson Jan 28 '13 at 11:23
  • 2
    I tried out this but the only improvement is, that it displays current values greater than 4 (instead of 6). If i put values between 1 and 4 I have the same problem. – Benchy Jan 28 '13 at 11:26
  • Anyone remember the XP default progress bar which had little rectangles? This is a symptom of this. It displays the progress bar in chunks. Joey Rohan's answer actually reverts the look and feel to metal because of the use of the `setStringPainted(true)`, which makes it not a windows-style progress bar – Anya Shenanigans Jan 28 '13 at 12:41
0

The progress indicator becomes smooth after you set:

progressBar.setStringPainted(true);

It however now shows a percentage, and the color changed to blue. You can do this:

progressBar.setString(""); // null means automatic percentage
progressBar.setForeground(new Color(0, 210, 40)); // Windows7-green

I think this works because the bar is now drawn (partially) by SWING instead of by the OS. The bar looks different as the progress indicator is missing the glass-like highlight and is painted solid. The background still looks the same. My guess is that SWING lets the OS draw it as if the progress is 0% and then draws a filled rectangle and the text on top.

The last setting, the color, could possibly be improved by querying a UI constant. However, within all the ProgressBar.* keys of the WindowsLookAndFeel, I could only find the blue colors.

Mark Jeronimus
  • 9,278
  • 3
  • 37
  • 50