gpt4 book ai didi

java - 如何动态添加元素到 JScrollPane?

转载 作者:行者123 更新时间:2023-12-02 03:31:39 28 4
gpt4 key购买 nike

我正在尝试使用 Java 中的 Swing 制作一个 GUI,它执行以下操作:

当按下“添加”按钮时,将创建一个 JPanel 并填满 GUI 的整个宽度。 JPanel 内部将使用 FlowLayout 排列 JLabels,告知特定详细信息(即名称、用户 ID 等)。每当随后按下“添加”按钮时,我希望在前一个 JPanel 的正下方添加一个新的 JPanel,以便 JScrollPane 在必要时激活其垂直滚动条。基本上,我希望 JScrollPane 能够在其中动态添加新的 JPanel。

但是,我在尝试执行此操作时遇到了一些问题。我无法弄清楚 JScrollPane 中的面板应使用哪个 LayoutManager。我尝试过使用 GridlLayout,但这似乎不起作用,因为当有足够的 JPanel 来覆盖整个 JScrollPane 时,GridLayout 只是创建一个新列来挤压新的 JPanel,而不是将其添加到之前的 JPanel 下方。为了实现这个目标我应该做什么?以下是我所拥有的一些图片以及我想要发生的情况的示例。

GUI

这是我想要发生的事情:

GUI Example

任何帮助将不胜感激,提前感谢您! :)

编辑:这是我尝试使用 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

}

最佳答案

如果您想将 JPanel 行添加到 GUI 中,我会将它们放置在使用 GridLayout(0, 1) 或 (0, 1, x, y) 的 JPanel 中。 0 表示行数可变,1 表示 1 列,x 和 y 表示垂直和水平间隙。然后,我将其放入使用 JPanel 的 BorderLayout 中的北部位置,这样行就不会像它们本来想要的那样扩展以填充滚动 Pane 的视口(viewport)。我会将第二个包装器 JPanel 放入 JScrollPane 的视口(viewport)中。

添加任何组件后,我会在容器上调用重新验证和重新绘制,以便其布局管理器将激活并正确放置新组件,并重新绘制以消除可能悬卡在周围的任何脏像素(在删除时更重要)组件)。

例如,我的 MCVE:

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

但是,您最好使用 JTable...例如:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class AddRowB extends JPanel {
private MyTableModel tableModel = new MyTableModel();
private JTable table = new JTable(tableModel);

public AddRowB() {
JPanel addPanel = new JPanel();
addPanel.add(new JButton(new AddAction("Add")));

setLayout(new BorderLayout());
add(new JScrollPane(table));
add(addPanel, BorderLayout.PAGE_END);
}

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) {
RowData row = new RowData("Type", "Address", "User ID");
tableModel.addRow(row);
}
}

private static void createAndShowGui() {
JFrame frame = new JFrame("Add Row B");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new AddRowB());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

class MyTableModel extends DefaultTableModel {
private static final String[] COLUMNS = {"Type", "Address", "User ID"};

public MyTableModel() {
super(COLUMNS, 0);
}

public void addRow(RowData rowData) {
Object[] row = {
rowData.getType(),
rowData.getAddress(),
rowData.getUserID()
};
addRow(row);
}
}

class RowData {
String type;
String address;
String userID;

public RowData(String type, String address, String userID) {
this.type = type;
this.address = address;
this.userID = userID;
}

public String getType() {
return type;
}

public String getAddress() {
return address;
}

public String getUserID() {
return userID;
}

}

关于java - 如何动态添加元素到 JScrollPane?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38021262/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com