繁体   English   中英

JProgressBar不可见,直到被告知显示

[英]JProgressBar not visible until told to show

我正在尝试制作仅在执行动作时显示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;
    }

}

忽略名称,我在创建歌曲时正在听那首歌。 :)

这可能不是应该设计的方式,但是此代码解决了问题,同时仍使用显示按钮和进度条所需的自然大小( pack() )。 这是通过调用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;
    }
}

您遇到的任何事件(来自Runnable#Thread )都不会调用EventDispashThread您必须将其包装到invokeLater ,否则由于JProgressBar是可见的,但是在长时间运行的任务结束后不应隐藏

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

2)您可以从Swing的ListenersSwingWorker的方法process done并调用EDV,并通过使用invokeLate r(在特殊情况下invokeAndWait )来调用对GUI的更改。

3)默认情况下, Runnable#Thread不会调用Swing的方法或EDT,必须将输出包装到invokeLater (在特殊情况下为invokeAndWait )的GUI中输出,更多内容请参见Scur ,Inc.中的Concurency 线程安全方法,如setText()append()等。

在您的线程中调用progressBar.setVisible(true); SwingUtilities.invokeAndWait()

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

我建议您提供显式的帧大小,例如frame.setSize(200,400) ,不要调用frame.pack()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM