将 JScrollPane 添加到 JFrame
Adding JScrollPane to a JFrame
我想将 JPanel
个容器添加到 JScrollPane
并将此滚动窗格添加到 JFrame
。但是当我将多个面板添加到滚动窗格时,就会发生这种情况。滚动窗格和顶部栏之间的间隙增加。我使用 BoxLayout
作为我使用的所有组件的布局管理器。
这是我对这个 GUI 布局的看法。一些注意事项:
- 它不是在
JScrollPane
中使用 BoxLayout
,而是在 BorderLayout
的 PAGE_START
中放置 GridLayout
。当可以将滚动窗格中的元素拉伸到 GUI 的整个宽度时,这很好。如果有必要将元素保持在首选大小,请坚持使用 BoxLayout
(我很少使用)或 GridBagLayout
。
- 这种布局策略基本上是 'divide and conquer',因为它从最小的 sub-divisions GUI(例如按钮的
FlowLayout
)开始,然后将这些容器添加到更大的具有不同布局和约束的容器(例如,将按钮面板添加到 BorderLayout
的 LINE_END
- 以将 I 推到 GUI 的右侧)以实现整体效果。
- 我还会考虑在滚动窗格中使用
JList
(使用渲染器面板)。有没有意义就看用途了。
- 请注意,此代码 是 MRE。 MRE 应该拥有其他人编译和 运行 代码所需的一切(包括导入、class 结构和主要方法)。
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;
// ref:
public class ScrollPaneTestGUI {
int elementCount = 1;
JPanel elementsPanel = new JPanel(new GridLayout(0,1,2,2));
public ScrollPaneTestGUI() {
initGUI();
}
private void initGUI() {
// this will become the content pane of the frame
JPanel gui = new JPanel(new BorderLayout(4,4));
gui.setBorder(new EmptyBorder(4,4,4,4));
JPanel pageStartPanel = new JPanel(new BorderLayout(2,2));
gui.add(pageStartPanel, BorderLayout.PAGE_START);
pageStartPanel.add(new JLabel("LINE START label"), BorderLayout.LINE_START);
// default flow layout is good for this one
JPanel buttonPanel = new JPanel();
pageStartPanel.add(buttonPanel, BorderLayout.LINE_END);
buttonPanel.add(new JButton("Does Nothing"));
Action addToScrollAction = new AbstractAction("Add to scrollPane") {
@Override
public void actionPerformed(ActionEvent e) {
elementsPanel.add(getPanelForScroll());
elementsPanel.revalidate();
}
};
JButton addToScrollButton = new JButton(addToScrollAction);
buttonPanel.add(addToScrollButton);
JPanel scrollPanel = new JPanel(new BorderLayout());
scrollPanel.add(elementsPanel, BorderLayout.PAGE_START);
gui.add(new JScrollPane(scrollPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
);
for (int ii=0; ii<2; ii++) {
elementsPanel.add(getPanelForScroll());
}
JFrame frame = new JFrame("ScrollPane GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(gui);
frame.pack(); // sets the GUI to the exact size needed
frame.setMinimumSize(frame.getSize());
frame.setVisible(true);
}
private JPanel getPanelForScroll() {
JPanel p = new JPanel();
p.add(new JLabel("Panel " + elementCount++));
p.setBorder(new EmptyBorder(10,200,10,200));
p.setBackground(Color.GREEN);
return p;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
new ScrollPaneTestGUI();
}
};
SwingUtilities.invokeLater(r);
}
}
我想将 JPanel
个容器添加到 JScrollPane
并将此滚动窗格添加到 JFrame
。但是当我将多个面板添加到滚动窗格时,就会发生这种情况。滚动窗格和顶部栏之间的间隙增加。我使用 BoxLayout
作为我使用的所有组件的布局管理器。
这是我对这个 GUI 布局的看法。一些注意事项:
- 它不是在
JScrollPane
中使用BoxLayout
,而是在BorderLayout
的PAGE_START
中放置GridLayout
。当可以将滚动窗格中的元素拉伸到 GUI 的整个宽度时,这很好。如果有必要将元素保持在首选大小,请坚持使用BoxLayout
(我很少使用)或GridBagLayout
。 - 这种布局策略基本上是 'divide and conquer',因为它从最小的 sub-divisions GUI(例如按钮的
FlowLayout
)开始,然后将这些容器添加到更大的具有不同布局和约束的容器(例如,将按钮面板添加到BorderLayout
的LINE_END
- 以将 I 推到 GUI 的右侧)以实现整体效果。 - 我还会考虑在滚动窗格中使用
JList
(使用渲染器面板)。有没有意义就看用途了。 - 请注意,此代码 是 MRE。 MRE 应该拥有其他人编译和 运行 代码所需的一切(包括导入、class 结构和主要方法)。
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;
// ref:
public class ScrollPaneTestGUI {
int elementCount = 1;
JPanel elementsPanel = new JPanel(new GridLayout(0,1,2,2));
public ScrollPaneTestGUI() {
initGUI();
}
private void initGUI() {
// this will become the content pane of the frame
JPanel gui = new JPanel(new BorderLayout(4,4));
gui.setBorder(new EmptyBorder(4,4,4,4));
JPanel pageStartPanel = new JPanel(new BorderLayout(2,2));
gui.add(pageStartPanel, BorderLayout.PAGE_START);
pageStartPanel.add(new JLabel("LINE START label"), BorderLayout.LINE_START);
// default flow layout is good for this one
JPanel buttonPanel = new JPanel();
pageStartPanel.add(buttonPanel, BorderLayout.LINE_END);
buttonPanel.add(new JButton("Does Nothing"));
Action addToScrollAction = new AbstractAction("Add to scrollPane") {
@Override
public void actionPerformed(ActionEvent e) {
elementsPanel.add(getPanelForScroll());
elementsPanel.revalidate();
}
};
JButton addToScrollButton = new JButton(addToScrollAction);
buttonPanel.add(addToScrollButton);
JPanel scrollPanel = new JPanel(new BorderLayout());
scrollPanel.add(elementsPanel, BorderLayout.PAGE_START);
gui.add(new JScrollPane(scrollPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
);
for (int ii=0; ii<2; ii++) {
elementsPanel.add(getPanelForScroll());
}
JFrame frame = new JFrame("ScrollPane GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(gui);
frame.pack(); // sets the GUI to the exact size needed
frame.setMinimumSize(frame.getSize());
frame.setVisible(true);
}
private JPanel getPanelForScroll() {
JPanel p = new JPanel();
p.add(new JLabel("Panel " + elementCount++));
p.setBorder(new EmptyBorder(10,200,10,200));
p.setBackground(Color.GREEN);
return p;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
new ScrollPaneTestGUI();
}
};
SwingUtilities.invokeLater(r);
}
}