【问题标题】:jScrollPane setVisible doesn't workjScrollPane setVisible 不起作用
【发布时间】:2012-11-21 15:58:39
【问题描述】:

我有一个显示按钮,可以在点击时显示JTable,但表格不可见。 注意:当我删除JScrollPane 时,代码可以正常工作,但表格的标题没有显示,所以请帮助使此代码正常工作而不删除JScrollPane

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

        import javax.swing.JButton;
        import javax.swing.JFrame;
        import javax.swing.JScrollPane;
        import javax.swing.JTable;
        import javax.swing.table.DefaultTableModel;

        public class Training extends JFrame {

            public Training() {

                getContentPane().setLayout(new FlowLayout());
                JTable table = new JTable();
                table.setModel(new DefaultTableModel(new Object[][] { { "joe", "joe" },
                        { "mickel", "mickel" }, }, new String[] { "LastName",
                        "FirstName" }));
                final JScrollPane pane = new JScrollPane(table);
                pane.setVisible(false);
                getContentPane().add(pane);

                JButton btn = new JButton("show");
                add(btn);
                btn.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        // TODO Auto-generated method stub
                        pane.setVisible(true);
                    }
                });
            }

            public static void main(String[] args) {
                Training app = new Training();
                app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                app.setSize(600, 600);
                app.setVisible(true);
            }
        }

【问题讨论】:

    标签: java swing jtable jscrollpane


    【解决方案1】:

    pane.setVisible(true);之后添加以下内容:

    getContentPane().validate();
    getContentPane().repaint();
    

    【讨论】:

    • 这是预期的行为吗?为什么仅pane.setVisible(true); 还不够?
    【解决方案2】:

    需要注意的几点:

    • 切勿不必要地扩展 JFrame 类,否则您可能需要扩展另一个非常必要的类,但在 java 中,单个类可能不会扩展超过另一个类(没有多重继承)。

    • 始终通过 SwingUtilities.invokeLater(Runnable r) 块在 Event Dispatch Thread 上创建 Swing 组件。

    • 在设置JFrame可见之前不要使用setSize(..)调用JFrame#pack()

    • 不需要getContentPane.add(..)getContentPane().setLayout(..),只需在JFrame 实例上调用add(..)setLayout(..),因为这些调用会发送到contentPane

    • 您遇到的问题是您在设置窗格可见后没有刷新您的框架/容器。我不同意@Dan。不要使用validate()getContentPane() 也不需要),而是:

      revalidate();
      repaint();
      

    作为revalidate() 覆盖validate()。当新的JComponents 被添加到可见组件时也使用验证,而revalidate() 被用于从可见组件中删除/添加JComponent

    这里是上面实现的代码的固定版本:

    按下按钮后:

    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.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    
    public class Training {
    
        private JFrame frame;
    
        public Training() {
            frame = new JFrame();
            frame.setLayout(new FlowLayout());
            JTable table = new JTable();
            table.setModel(new DefaultTableModel(new Object[][]{{"joe", "joe"},
                        {"mickel", "mickel"},}, new String[]{"LastName",
                        "FirstName"}));
            final JScrollPane pane = new JScrollPane(table);
            pane.setVisible(false);
            frame.add(pane);
    
            JButton btn = new JButton("show");
            frame.add(btn);
    
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    pane.setVisible(true);
    
                    frame.pack();//this is so the frame will resize after adding pane
                    frame.revalidate();
                    frame.repaint();
                }
            });
    
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Training();
                }
            });
        }
    }
    

    更新:

    还有一个更可重用的Layout,为什么不将所有组件添加到JPanel,然后将JPanel 添加到JFrame,这样如果您需要添加更多内容,这很简单。

    【讨论】:

    • +1 表示few things to note: 和带有描述的图像输出
    猜你喜欢
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 2012-02-18
    • 2011-07-04
    • 1970-01-01
    • 2016-04-17
    相关资源
    最近更新 更多