简体   繁体   English

ScrollPane 在 Java Swing 中不滚动

[英]ScrollPane not Scrolling in Java Swing

I'm trying to adding the scrollpane in a inner panel,and the scrollbar is showing in the inner panel, but as i add the labels and textfield, the components were added but the scroll bar is not working.我正在尝试在内部面板中添加滚动窗格,并且滚动条显示在内部面板中,但是当我添加标签和文本字段时,组件已添加但滚动条不起作用。

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

Output of the above Program上述程序的输出

上述程序的输出

This is the output image of my program.这是我的程序的输出图像。

You need to revalidate the JScrollPane itself for it to re-lay out its viewport and its view for this to work.您需要重新验证 JScrollPane 本身,以便它重新布置其视口和视图以使其工作。 But you will also need to set the layout of the inner JPanel to allow a grid of things to display for this to work right, such as by giving it a new GridLayout(0, 1) // one column, variable # of rows .但是您还需要设置内部 JPanel 的布局,以允许显示事物网格以使其正常工作,例如通过给它一个new GridLayout(0, 1) // one column, variable # of rows

eg,例如,

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

The problem is your usage of null layouts everywhere.问题是你到处都使用空布局。 The scrollbars only appear when the preferred size of a component added to the viewport is greater than the size of the viewport.仅当添加到视口的组件的首选大小大于视口的大小时,滚动条才会出现。 The preferred size is only calculated dynamically when layout managers are used.首选大小仅在使用布局管理器时动态计算。 So the solution is to use layout managers.所以解决方案是使用布局管理器。

For the most basic changes to your code you are:对于您的代码最基本的更改,您是:

  1. remove all the setBounds() statements删除所有 setBounds() 语句
  2. remove all the setLayout(null) statements删除所有 setLayout(null) 语句

Then you can start using layout managers.然后你就可以开始使用布局管理器了。

Start by creating a panel for the top:首先为顶部创建一个面板:

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

Then add your scroll pane to the frame:然后将滚动窗格添加到框架中:

add(scrollPane, BorderLayout.CENTER);

Now you need to use:现在你需要使用:

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

The revalidate() invokes the layout manager so the new preferred size can be calculated. revalidate() 调用布局管理器,以便可以计算新的首选大小。

In your example the horizontal scrollbar will appear because by default a JPanel uses a FlowLayout which displays components on a single line.在您的示例中,将出现水平滚动条,因为默认情况下 JPanel 使用FlowLayout将组件显示在一行上。

If you want the components added vertically then you will need to use a different layout manager on "panel_1".如果您希望垂直添加组件,则需要在“panel_1”上使用不同的布局管理器。

Read the section from the Swing tutorial on Layout Managers for more information and examples.阅读有关布局管理器的 Swing 教程中的部分以获取更多信息和示例。

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

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