JProgressBar直到被告知显示才可见

时间:2012-01-11 05:35:15

标签: java swing jprogressbar

我正在尝试创建一个仅在执行操作时显示JProgressBar的应用程序。我的问题是,当程序首次打开时,我将JProgressBar可见性设置为false,然后在执行某个操作时设置为true,并在完成后返回{{ 1}}。看起来它会起作用,而且确实如此,只是当我默认它不可见时。如果默认情况下可见性为false,那么效果很好,但这并不是我想要的。我怎么能这样做,直到我把它设置为可见才能看到它?

SSCCE只是因为我的问题不够明确:

true

忽略这个名字,我在创作时正在听那首歌。 :)

4 个答案:

答案 0 :(得分:2)

这可能不是它应该设计的方式,但是此代码修复了问题,同时仍然使用显示按钮和进度条所需的自然大小(pack())。这可以通过在调用包之后将进度条设置为不可见的来实现,但之前设置GUI可见。

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 :(得分:2)

您案例中的任何事件(来自Runnable#Thread)都不会调用EventDispashThread您必须将其包含到invokeLater中,否则JProgressBar将会显示但不久之后不应该隐藏运行的结束

1)所有对GUI的更改必须在EDT上完成

2)您可以从Swing's ListenersSwingWorker的方法processdone调用EDV,并使用invokeLate r调用GUI的更改(在特殊情况下invokeAndWait

3)Runnable#Thread默认情况下不会调用Swing的方法或EDT,必须输出到包含在invokeLater中的GUI(在特殊情况下为invokeAndWait),更多在{ {3}},inc。线程安全的方法,如setText()append()等。

答案 2 :(得分:1)

在你的帖子中调用progressBar.setVisible(true);内的SwingUtilities.invokeAndWait()

答案 3 :(得分:0)

您发布的代码效果非常好。问题是当您调用frame.pack()时,框架会调整大小以适合所有可见组件。当progressBar可见性设置为false时,框架会忽略此组件并相应地调整大小。因此,稍后调用progressBar.setVisible(true)时,会显示该组件,但框架不够大,您无法查看该组件。如果您只是拖动并增加框架的大小,则可以看到progressBar

我建议您提供明确的框架尺寸,例如frame.setSize(200,400),不要拨打frame.pack()