【问题标题】:Adding JFileChooser with no action causes panels to not render添加没有操作的 JFileChooser 会导致面板不呈现
【发布时间】:2012-04-07 07:26:25
【问题描述】:

这是一个奇怪的问题。我有一个解决方案,但我不知道为什么会首先出现问题。观察下面的代码:

// VERSION 1

public class test {

    public static void main(String[] args) {
        JFrame mainFrame = new JFrame("Test");
        JPanel inputPanel = new JPanel();

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel);
        mainFrame.setBounds(100, 50, 200, 100);
        mainFrame.setVisible(true);

        JButton inputFileButton = new JButton("BROWSE");
        inputPanel.add(inputFileButton);
    }
}

它按预期工作。该按钮不执行任何操作,但可以正确呈现。现在,我添加了一个 JFileChooser(我计划稍后使用它,但现在我要做的只是实例化它)。

// VERSION 2

public class test {

    public static void main(String[] args) {
        JFrame mainFrame = new JFrame("Test");
        JPanel inputPanel = new JPanel();

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel);
        mainFrame.setBounds(100, 50, 200, 100);
        mainFrame.setVisible(true);

        JFileChooser inputFileChooser = new JFileChooser(); // NEW LINE

        JButton inputFileButton = new JButton("BROWSE");
        inputPanel.add(inputFileButton);
    }
}

突然间我的按钮不再呈现。为什么?我知道两种让它再次工作的方法,但对我来说都没有 100% 的意义。一种解决方法:

// VERSION 3

public class test {

    public static void main(String[] args) {
        JFrame mainFrame = new JFrame("Test");
        JPanel inputPanel = new JPanel();

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel);
        mainFrame.setBounds(100, 50, 200, 100);
        mainFrame.setVisible(true);

        JButton inputFileButton = new JButton("BROWSE");
        inputPanel.add(inputFileButton);

        JFileChooser inputFileChooser = new JFileChooser(); // MOVE LINE TO END
    }
}

因此,将该行移到末尾允许按钮再次呈现,但这对我来说仍然没有意义,实例化的 JFileChooser 与未连接的按钮有什么关系。我可以解决此问题的另一种方法:

// VERSION 4

public class test {

    public static void main(String[] args) {
        JFrame mainFrame = new JFrame("Test");
        JPanel inputPanel = new JPanel();

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel);
        mainFrame.setBounds(100, 50, 200, 100);

        JFileChooser inputFileChooser = new JFileChooser();

        JButton inputFileButton = new JButton("BROWSE");
        inputPanel.add(inputFileButton);

        mainFrame.setVisible(true); // MOVE *THIS* LINE TO THE END            
    }
}

为什么上面的版本解决了这个问题是有道理的……显然,JFileChoose 实例化的某些东西使我的按钮不可见,但是这个 setVisible() 方法随后将它带回了光明。但这仍然不能告诉我为什么它一开始就看不见了。

有人可以帮我弄清楚我缺少什么吗?谢谢!

【问题讨论】:

  • 1) 始终在 EDT 上创建和更新 GUI。 2) 不要拨打setBounds()setSize(),而是拨打pack()。 3) 顺序很重要。 a) 添加组件 b) pack() c) setLocationRelativeTo()(如果需要) d) setVisible(true)

标签: java swing jfilechooser


【解决方案1】:

您正在使您的mainFrame 可见并随后添加按钮。查看this SO question,了解您需要采取哪些步骤来确保您的按钮可见。

它在您的第一个示例中起作用的原因可能是纯粹的运气。您添加按钮的调用将在 EDT 显示您的组件之前执行。

注意:请在 EDT 上执行 Swing 操作

【讨论】:

  • 谢谢。我是 EDT 概念的新手,但从我所做的一些快速研究来看,如果我在不同的线程中,听起来我只需要明确引用 EDT。我上面的任何示例都不是“在 EDT 上执行 Swing 操作”吗?我现在更好地理解了我应该遵循的顺序,感谢您和 Andrew 的回答,只是确保我没有忽略有关 EDT 的其他内容。
  • 您的 main 方法在不同的线程上运行,因此在 EDT 上不会执行任何 Swing 操作。您应该在 main 方法中使用 SwingUtilities.invokeLater 调用来构建您的 UI。必读教程是this one
猜你喜欢
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多