Java качели непрозрачные JProgressBar внутри JProgressBar - PullRequest
1 голос
/ 02 апреля 2019

Я пытаюсь объединить 2 JProgressBars вместе, чтобы я мог представлять статистику об одной вещи.

У меня вопрос: как можно объединить или наложить два индикатора выполнения так, чтобы это работало?

Одно из решений, которое я придумал, - это объединить 2 индикатора выполнения в JPanel:

enter image description here

Но это не идеальное решение.

Вместо этого я хотел бы сделать непрозрачным верхний индикатор выполнения, а затем перекрыть его. Я считаю, что с компонентами можно .add() второй JProgressBar до первого. Но когда я добавил его, я вижу только верхнюю панель. И даже когда я установил его на opaque, он все равно не показывает их обоих.

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

Кажется, это должно быть очень легко, поэтому я должен пропустить какую-то критическую строку кода.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Вы можете смоделировать второй индикатор выполнения, переопределив JProgressBar.paintComponent(Graphics g).В следующем упрощенном примере он рисует линию, длина которой представляет значение второго «бара»:

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

enter image description here

(скопируйте и вставьте полный код с здесь и запустите)

2 голосов
/ 02 апреля 2019

Это «зависит» от того, чего вы хотите достичь, например, немного GridBagLayout магии ...

(я знаю, я бегу на Mac, тем не менее об этом сказанотем лучше;))

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

Можно посмотреть на удаление границ из JProgressBar и реализацию единой границы вокруг содержащей панели.или, если ничего не помогает, просто создайте свою собственную, используя собственную картину

...