【问题标题】:ScrollPane not Scrolling in Java SwingScrollPane 在 Java Swing 中不滚动
【发布时间】:2020-09-05 15:01:29
【问题描述】:

我正在尝试在内部面板中添加滚动窗格,并且滚动条显示在内部面板中,但是当我添加标签和文本字段时,组件已添加但滚动条不起作用。

public class AddNewProject extends JFrame {
    private JButton btnNewButton;
    private JSpinner spinner;
    private JScrollPane scrollPane;
    private JPanel panel_1;
    
    public AddNewProject() {
        getContentPane().setLayout(null);
        
        JPanel panel = new JPanel();
        panel.setBackground(Color.PINK);
        panel.setBounds(134, 37, 583, 610);
        getContentPane().add(panel);
        panel.setLayout(null);
        
        spinner = new JSpinner();
        spinner.setModel(new SpinnerNumberModel(0, 0, 30, 1));
        spinner.setBounds(63, 51, 164, 31);
        panel.add(spinner);
        
        btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                int n=(int) spinner.getValue();
                JLabel jlabel[]=new JLabel[n];
                JTextField jtxt[]=new JTextField[n];
                                
                for(int i =0;i<n;i++)
                {
                    jlabel[i]=new JLabel("Label "+(i+1));
                    jtxt[i]=new JTextField(32);
                    
                    panel_1.add(jlabel[i]);
                    panel_1.add(jtxt[i]);
                }
                panel_1.validate();
                panel_1.repaint();
            }
        });
        btnNewButton.setBounds(336, 54, 149, 28);
        panel.add(btnNewButton);
        
        scrollPane = new JScrollPane();     
        scrollPane.setBounds(69, 141, 434, 298);
        panel.add(scrollPane);
        
        panel_1 = new JPanel();
        
        scrollPane.setViewportView(panel_1);
        scrollPane.setPreferredSize(new Dimension(434,300));
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        
        setSize(900,800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        
    }
    public static void main(String[] args) {
        new AddNewProject();
    }
}

上述程序的输出

这是我的程序的输出图像。

【问题讨论】:

    标签: java swing jscrollpane


    【解决方案1】:

    您需要重新验证 JScrollPane 本身,以便重新布置其视口和视图以使其正常工作。但是您还需要设置内部 JPanel 的布局,以允许显示一个网格以使其正常工作,例如给它一个 new GridLayout(0, 1) // one column, variable # of rows

    例如,

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class AddNewProject2 extends JPanel {
        private JPanel gridPanel = new JPanel(new GridLayout(0, 1)); // 1 column grid
        private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 30, 1));
        
        
        public AddNewProject2() {
            JPanel wrapperPanel = new JPanel(new BorderLayout());
            wrapperPanel.add(gridPanel, BorderLayout.PAGE_START);
            JScrollPane scrollPane = new JScrollPane(wrapperPanel);
            scrollPane.getViewport().setPreferredSize(new Dimension(450, 500));
            
            JButton newRowBtn = new JButton("New Row");
            newRowBtn.addActionListener(e -> {
                int rows = (int) spinner.getValue();
                for (int i = 0; i < rows; i++) {
                    JLabel label = new JLabel("Label " + String.format("%02d", i + 1));
                    JTextField txtFld = new JTextField(32);
                    JPanel row = new JPanel();
                    row.add(label);
                    row.add(txtFld);
                    gridPanel.add(row);
                }
                
                scrollPane.revalidate();
            });
            
            JPanel topPanel = new JPanel();
            topPanel.add(spinner);
            topPanel.add(newRowBtn);
            
            int gap = 20;
            setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
            setLayout(new BorderLayout(gap, gap));
            
            add(topPanel, BorderLayout.PAGE_START);
            add(scrollPane);
        }
        
        
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                JFrame frame = new JFrame("GUI");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                
                AddNewProject2 project2 = new AddNewProject2();
                frame.add(project2);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            });
        }
    }
    

    【讨论】:

    • 但是为什么重新绘制后网格面板中没有设置背景颜色
    【解决方案2】:

    问题是你到处使用空布局。仅当添加到视口的组件的首选大小大于视口的大小时,才会出现滚动条。首选大小仅在使用布局管理器时动态计算。所以解决方案是使用布局管理器。

    对于您的代码的最基本更改,您是:

    1. 删除所有 setBounds() 语句
    2. 删除所有 setLayout(null) 语句

    然后你就可以开始使用布局管理器了。

    首先为顶部创建一个面板:

    JPanel topPanel = new JPanel();
    topPanel.add(spinner)
    topPanel.add(btnNewButton);
    add(topPanel, BorderLayout.PAGE_START);
    

    然后将滚动窗格添加到框架中:

    add(scrollPane, BorderLayout.CENTER);
    

    现在你需要使用:

    //panel_1.validate();
    panel_1.revalidate();
    

    revalidate() 调用布局管理器,因此可以计算新的首选大小。

    在您的示例中,将出现水平滚动条,因为默认情况下,JPanel 使用 FlowLayout,它在单行上显示组件。

    如果您希望垂直添加组件,则需要在“panel_1”上使用不同的布局管理器。

    阅读 Layout Managers 上的 Swing 教程部分,了解更多信息和示例。

    【讨论】:

    • 感谢您让我理解了这个概念
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2016-11-30
    相关资源
    最近更新 更多