我正在尝试使用Java中的Swing创建一个GUI,它执行以下操作:
当"添加"按下按钮,创建JPanel并填充GUI的整个宽度。在JPanel内部将使用FlowLayout安排JLabel,它告诉具体细节(即名称,用户ID等)。每当按下Add按钮时,我想在前一个下添加一个新的JPanel,这样JScrollPane将在必要时激活其垂直滚动条。基本上,我希望JScrollPane能够在其中动态添加新的JPanel。
但是,我在尝试这样做时遇到了一些问题。我无法弄清楚哪个LayoutManager用于JScrollPane中的面板。我已经尝试过使用GridlLayout,但这似乎不起作用,因为当有足够的JPanel来掩盖整个JScrollPane时,GridLayout只会创建一个新列来压缩新的JPanel而不是将它添加到前一个JPanel之下。我该怎么做才能实现这个目标?以下是我所拥有的一些图像以及我想要发生的事例。
以下是我想要发生的事情:
任何帮助将不胜感激,谢谢你提前! :)
编辑:这是我尝试使用GridLayout的代码示例。
public Window() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 701, 400);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel buttonPanel = new JPanel();
contentPane.add(buttonPanel, BorderLayout.SOUTH);
JButton btnAdd = new JButton("Add");
buttonPanel.add(btnAdd);
JScrollPane scrollPane = new JScrollPane();
contentPane.add(scrollPane, BorderLayout.CENTER);
JPanel systemsPanel = new JPanel();
scrollPane.setViewportView(systemsPanel);
systemsPanel.setLayout(new GridLayout(8, 1, 0, 0)); //8 rows for now
for (int i = 1; i < 50; i++) {
systemsPanel.add(new JButton("test"), "cell 0 " + i);
}
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width / 2 - this.getSize().width / 2, dim.height / 2 - this.getSize().height / 2); //Center the Frame
}
答案 0 :(得分:2)
如果要将JPanels行添加到GUI中,我会将它们放在使用GridLayout(0,1)或(0,1,x,y)的JPanel中。 0表示可变数量的行,1表示1列,x和y表示垂直和水平间隙。然后我将它放入BorderLayout-使用JPanel进入NORTH位置,这样行不会扩展以填充滚动窗格的视口,因为它们原本想要这样做。我将第二个包装器JPanel放入JScrollPane的视口中。
添加任何组件后,我会在容器上调用revalidate并重新绘制,以便其布局管理器将激活并正确放置新组件,并重新绘制以清除可能悬挂的任何脏像素(在删除时更为重要)组件)。
例如,我的MCVE:
TextConn
但是,你最好使用JTable ......例如:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class AddRowA extends JPanel {
private static final int PREF_W = 650;
private static final int PREF_H = 400;
// JPanel to hold all rows. uses gridlayout that has 1 column and variable number
// of rows
private JPanel rowHolderPanel = new JPanel(new GridLayout(0, 1, 1, 1));
public AddRowA() {
// outerPanel is a wrapper or container JPanel that is
// held by JScrollPane's viewport that holds the rowHolderPanel in
// a BorderLayout.PAGE_START location, so the rows don't expand unnecessarily
JPanel outerPanel = new JPanel(new BorderLayout());
outerPanel.add(rowHolderPanel, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(outerPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel addPanel = new JPanel();
addPanel.add(new JButton(new AddAction("Add")));
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(addPanel, BorderLayout.PAGE_END);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class AddAction extends AbstractAction {
public AddAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
JPanel panel = new JPanel();
panel.add(new JLabel("Foo"));
panel.add(Box.createHorizontalStrut(25));
panel.add(new JButton("Bar"));
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
rowHolderPanel.add(panel);
rowHolderPanel.revalidate();
rowHolderPanel.repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Add Row A");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new AddRowA());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}