JProgressBar не виден, пока не будет показано, чтобы показать - PullRequest
1 голос
/ 11 января 2012

Я пытаюсь создать приложение, которое показывает JProgressBar только во время выполнения действий.Моя проблема в том, что когда программа открывается впервые, я устанавливаю JProgressBar видимость на false, затем на true, когда выполняется действие, и после того, как оно выполнено, обратно на false.Кажется, что это будет работать, и это работает, но только не тогда, когда я делаю его невидимым по умолчанию.Если видимость по умолчанию true, то она работает хорошо, но это не совсем то, что я хочу.Как я мог сделать так, чтобы он не был виден, пока я не установил его как видимый?

SSCCE, только если мой вопрос не был достаточно ясен:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class SmileBack {

    private JFrame frame;

    private JPanel panel, container;

    private JButton loadButton;

    private JProgressBar progressBar;

    public static void main(String[] arguments) {
        new SmileBack().constructFrame();
    }

    public void constructFrame() {
        frame = new JFrame("RSTracker");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(getContentPane());
        frame.pack();
        frame.setVisible(true);
    }

    public JPanel getContentPane() {
        panel = new JPanel(new BorderLayout());

        progressBar = new JProgressBar();
        progressBar.setIndeterminate(true);
        //progressBar.setVisible(false); // doesn't work when this is uncommented

        loadButton = new JButton("Load memberlist");
        loadButton.setEnabled(true);
        loadButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        progressBar.setVisible(true);
                        // do my stuff here...
                        try {
                            Thread.sleep(2000); // just for the sake of example
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        progressBar.setVisible(false);
                    }

                }).start();
            }

        });

        container = new JPanel(new FlowLayout());
        container.add(loadButton);
        container.add(progressBar);

        panel.add(container);

        return panel;
    }

}

Игнорировать имяЯ слушал эту песню, создавая это.:)

Ответы [ 4 ]

2 голосов
/ 11 января 2012

любые события в вашем случае (из Runnable#Thread) не вызывают EventDispashThread, вы должны обернуть это в invokeLater, в противном случае, поскольку JProgressBar будет видно, но после долгого выполнения завершенных тактов не должно быть скрыто

1) все изменения в графическом интерфейсе должны быть выполнены в EDT

2) вы можете вызывать EDV из приемников Swing , SwingWorker process иdone и вызовите изменения в графическом интерфейсе с помощью invokeLate r (в особых случаях invokeAndWait)

3) Runnable#Thread по умолчанию не вызывает ни методы Swing, ни EDT, их необходимо вывести вграфический интерфейс в invokeLater (в особых случаях invokeAndWait), больше в Concurency в Swing , вкл.Потокобезопасные методы, такие как setText(), append() и т. д.

2 голосов
/ 11 января 2012

Вероятно, это не так, как должно быть , предназначенное , но этот код устраняет проблему, все еще используя естественный размер (pack()), необходимый для отображения кнопки и индикатора выполнения. Это достигается путем установки индикатора выполнения на невидимый после вызова пакета , но до установки графического интерфейса пользователя видимым.

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class SmileBack {

    private JFrame frame;

    private JPanel panel, container;

    private JButton loadButton;

    private JProgressBar progressBar;

    public static void main(String[] arguments) {
        new SmileBack().constructFrame();
    }

    public void constructFrame() {
        frame = new JFrame("RSTracker");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(getContentPane());
        // after this, everything is instantiated;
        frame.pack();
        setProgressBarVisibility(false);
        frame.setVisible(true);
    }

    public void setProgressBarVisibility(boolean visible) {
        progressBar.setVisible(visible);
    }

    public JPanel getContentPane() {
        panel = new JPanel(new BorderLayout());

        progressBar = new JProgressBar();
        progressBar.setIndeterminate(true);

        loadButton = new JButton("Load memberlist");
        loadButton.setEnabled(true);
        loadButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        progressBar.setVisible(true);
                        // do my stuff here...
                        try {
                            Thread.sleep(2000); // just for the sake of example
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        progressBar.setVisible(false);
                    }

                }).start();
            }

        });

        container = new JPanel(new FlowLayout());
        container.add(loadButton);
        container.add(progressBar);

        panel.add(container);

        return panel;
    }
}
1 голос
/ 11 января 2012

В вашей теме вызовите progressBar.setVisible(true); внутри SwingUtilities.invokeAndWait().

0 голосов
/ 11 января 2012

Код, который вы разместили, работает отлично.Проблема в том, что при вызове frame.pack() размер рамки изменяется, чтобы соответствовать всем видимым компонентам.Когда для progressBar видимости установлено значение false, фрейм игнорирует этот компонент и размеры соответственно.Поэтому, когда progressBar.setVisible(true) вызывается позже, компонент отображается, но рамка недостаточно велика, чтобы вы могли увидеть компонент.Если вы просто перетащите и увеличите размер фрейма, вы увидите progressBar

. Я предлагаю вам указать явный размер фрейма, например frame.setSize(200,400), и не вызывать frame.pack().

...