ScrollPane 在 Java Swing 中不滚动
ScrollPane not Scrolling in Java Swing
我正在尝试在内部面板中添加滚动窗格,并且滚动条显示在内部面板中,但是当我添加标签和文本字段时,组件已添加但滚动条不起作用。
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();
}
}
上述程序的输出
这是我程序的输出图像。
您需要重新验证 JScrollPane 本身,才能 re-lay 显示其视口和视图,才能正常工作。但是您还需要设置内部 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);
});
}
}
问题是您到处都使用空布局。只有当添加到视口的组件的首选大小大于视口大小时,滚动条才会出现。首选大小仅在使用布局管理器时动态计算。所以解决方案是使用布局管理器。
对于代码的最基本更改,您是:
- 删除所有 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 教程部分以获取更多信息和示例。
我正在尝试在内部面板中添加滚动窗格,并且滚动条显示在内部面板中,但是当我添加标签和文本字段时,组件已添加但滚动条不起作用。
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();
}
}
上述程序的输出
这是我程序的输出图像。
您需要重新验证 JScrollPane 本身,才能 re-lay 显示其视口和视图,才能正常工作。但是您还需要设置内部 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);
});
}
}
问题是您到处都使用空布局。只有当添加到视口的组件的首选大小大于视口大小时,滚动条才会出现。首选大小仅在使用布局管理器时动态计算。所以解决方案是使用布局管理器。
对于代码的最基本更改,您是:
- 删除所有 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 教程部分以获取更多信息和示例。