Java 在 JProgressBar 中摆动不透明的 JProgressBar

Java swing opaque JProgressBar inside JProgressBar

我正在尝试将 2 个 JProgressBars 组合在一起,以便我可以表示有关单个事物的统计信息。

我的问题是如何将两个进度条合并或叠加才能起作用?

我想到的一个解决方案是将 2 个进度条放在一个 JPanel 中:

但这不是一个理想的解决方案。

相反,我想做的是使顶部进度条不透明,然后将其重叠。我相信使用组件可以 .add() 第二个 JProgressBar 到第一个。但是当我添加它时,我只能看到顶部栏。即使我将它设置为 opaque,它仍然不会同时显示它们。

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

看起来应该很简单所以我一定是漏掉了一些关键的代码行。

就"depends"你想达到的效果,比如一点点GridBagLayout魔法...

(我知道,我在 Mac 上 运行,越少说越好 ;))

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

您可以考虑从 JProgressBar 中删除边框并在包含面板周围实现单个边框,或者,如果所有其他方法都失败,只需使用自定义绘画制作您自己的边框

您可以通过覆盖 JProgressBar.paintComponent(Graphics g) 来模拟第二个进度条。
在以下过度简化的示例中,它绘制了一条线,其长度表示第二个 "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);
    }
}

测试一下:

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

(从 here 和 运行 复制粘贴完整代码)