问题描述
我试图在内部面板中添加滚动窗格,并且内部面板中显示滚动条,但是当我添加标签和文本字段时,添加了组件,但是滚动条不起作用。
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,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();
}
}
上述程序的输出
这是我程序的输出图像。
解决方法
您需要重新验证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,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));
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);
});
}
}
,
问题是您到处都使用null布局。仅当添加到视口的组件的首选大小大于视口的大小时,才会显示滚动条。首选大小仅在使用布局管理器时动态计算。因此解决方案是使用布局管理器。
对于代码的最基本更改,您是:
- 删除所有setBounds()语句
- 删除所有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教程中的部分,以获取更多信息和示例。