1

I am trying to combine 2 JProgressBars together so that I can represent statistics about a single thing.

My question is how could the two progress bars be combined or overlayed such that this would work?

One solution I came up with is to put 2 progress bars together in a JPanel:

enter image description here

But this is not an ideal solution.

Instead what I would like to do is make the top progress bar opaque and then overlap it. I believe that with components it is possible to .add() a second JProgressBar to the first. But when I added it I only can see the top bar. And even when I set it to be opaque it still does not show both of them.

bar1.setOpaque(false);
bar1.setBorder(null);
bar2.add(bar1);

It seems that it should be very easy so I must be missing some critical line of code.

JFreeman
  • 974
  • 1
  • 10
  • 26

2 Answers2

2

It "depends" on what you want to achieve, for example, a little bit of GridBagLayout magic...

(I know, I'm running on Mac, the less said about it the better ;))

Overlapping

public class TestPane extends JPanel {

    public TestPane() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weighty = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;

        JProgressBar pb1 = new JProgressBar();
        pb1.setValue(50);
        JProgressBar pb2 = new JProgressBar();
        pb2.setValue(25);

        add(pb1, gbc);

        gbc.insets = new Insets(4, 4, 0, 0);
        add(pb2, gbc, 0);
    }
}

You could look at removing the borders from the JProgressBar and implementing a single border around the containing panel or, if all else fails, simply make your own using custom painting

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2

You could simulate the second progress bar by overriding JProgressBar.paintComponent(Graphics g).
In the following over-simplified example it draws a line, the length of which represents the value of the second "bar":

class BasicDoubleProgressbar extends JProgressBar{

    private int secondaryBarValue;

    void setSecondValue(int value){
        secondaryBarValue = value;
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.CYAN);
        g2.setStroke( new BasicStroke(5));
        g2.drawLine(0, 10, secondaryBarValue,10);
    }
}

Test it:

public static void main(String[] args) {
    BasicDoubleProgressbar pBar = new BasicDoubleProgressbar();
    pBar.setMinimum(0); pBar.setMaximum(100);
    pBar.setValue(0);
    pBar.setForeground(Color.blue);

    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(pBar);
    f.pack();

    Timer timer = new Timer(100, new ActionListener() {
        int counter = 1;
        @Override
        public void actionPerformed(ActionEvent ae) {
            pBar.setValue(++counter);
            pBar.setSecondValue(counter/2);
            if (counter > 100) {
                counter = 0;
            }
        }
    });

    timer.start();
    f.setVisible(true);
}

enter image description here

(Copy-paste the complete code from here and run)

c0der
  • 18,467
  • 6
  • 33
  • 65
  • Thank you! I just took some time testing both solutions, I found the other solution (MadProgrammer) worked best for what I needed because it looks better with my program's theme. – JFreeman Apr 05 '19 at 09:02