Java JProgressBar在被告知显示之前不可见

Java JProgressBar在被告知显示之前不可见,java,swing,jprogressbar,Java,Swing,Jprogressbar,我试图制作一个只在执行操作时显示JProgressBar的应用程序。我的问题是,当程序第一次打开时,我将JProgressBar可见性设置为false,然后在执行操作时将其设置为true,然后在操作完成后将其设置为false。它似乎可以工作,而且确实可以,只是当我默认设置它不可见时就不行了。如果可见性在默认情况下为true,那么它工作得很好,但这不是我想要的。如何使它在设置为可见之前不可见 以防我的问题不够清楚: import java.awt.BorderLayout; import java

我试图制作一个只在执行操作时显示JProgressBar的应用程序。我的问题是,当程序第一次打开时,我将JProgressBar可见性设置为false,然后在执行操作时将其设置为true,然后在操作完成后将其设置为false。它似乎可以工作,而且确实可以,只是当我默认设置它不可见时就不行了。如果可见性在默认情况下为true,那么它工作得很好,但这不是我想要的。如何使它在设置为可见之前不可见

以防我的问题不够清楚:

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

}

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

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


我建议您提供明确的帧大小,如frame.setSize200400,不要调用frame.pack

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


我建议您提供明确的帧大小,如frame.setSize200400,不要调用frame.pack

在线程中调用progressBar.setVisibletrue;内部SwingUtilities.invokeAndWait

在线程中调用progressBar.setVisibletrue;内部SwingUtilities.invokeAndWait

这可能不是它应该设计的方式,但是这段代码在仍然使用显示按钮和进度条所需的自然尺寸包的情况下解决了问题。这是通过在调用包之后,但在将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;
    }
}

这可能不是它应该设计的方式,但是这段代码修复了这个问题,同时仍然使用显示按钮和进度条所需的自然大小包。这是通过在调用包之后,但在将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;
    }
}

在您的案例中,RunnableThread中的任何事件都不会调用EventDispashThread,您必须将其包装到invokeLater中,否则,由于JProgressBar将可见,但在长时间运行后,taks结束后不应隐藏

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

2您可以从、SwingWorker的方法process和done调用EDV,并在特殊情况下使用invokeAndWait调用对GUI的更改


3 RunnableThread默认情况下不调用Swing的方法或EDT,在特殊情况下,必须将输出包装到invokeLater中的GUI invokeAndWait,更详细的是在,inc.线程安全方法中,如setText,追加等。

在您的案例中,RunnableThread中的任何事件都不会调用EventDispashThread,您必须将其包装到invokeLater中,否则,由于JProgressBar将可见,但在长时间运行后,taks结束后不应隐藏

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

2您可以从、SwingWorker的方法process和done调用EDV,并在特殊情况下使用invokeAndWait调用对GUI的更改


3 RunnableThread默认情况下不调用Swing的方法或EDT,在特殊情况下,必须将输出包装到invokeLater中的GUI invokeAndWait,更详细的是,inc.的线程安全方法,如setText、append等。

+1用于诊断,-1用于建议的解决方案。不需要设置大小,请参阅我的答案。感谢您的建议,但我觉得使用frame.pack更舒服。诊断+1,-1表示建议的解决方案。不需要设置大小,请参阅我的答案。谢谢您的建议,但我觉得使用frame.pack更舒服。谢谢您的帮助和建议!谢谢你的帮助和建议!