我正在尝试使用Java中的Swing制作一个GUI,它可以执行以下操作:
当按下“添加”按钮时,会创建一个JPanel,并填满图形用户界面的整个宽度。在JPanel中,JLabels将使用FlowLayout来排列,该FlowLayout告诉特定的细节(例如名称、用户ID等)。每当随后按下添加按钮时,我都希望在前面的按钮下添加一个新的JPanel,以便JScrollPane在必要时激活其垂直滚动条。基本上,我希望JScrollPane能够在其中动态添加新的JPanels。
然而,我在尝试这样做时遇到了一些问题。在JScrollPane中,我无法确定要为面板使用哪个LayoutManager。我尝试过使用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
}
如果您想将行JPanel添加到GUI中,我会将它们放在使用GridLayout(0,1)或(0,1,x,y)的JPanel中。0表示行数可变,1表示1列,x和y表示垂直和水平间隙。然后,我将使用JPanel将其放置到BorderLayout中的NORTH位置,这样行就不会像它们希望的那样展开以填充scrollpane的视口。我将第二个包装器JPanel放入JScrollPane的视口中。
添加任何组件后,我将调用容器上的revalidate和repait,以便其布局管理器能够激活并正确放置新组件,并重新绘制以去除可能挂起的任何脏像素(在移除组件时更为重要)。
例如,我的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;
}
}
问题内容: 我想将通过JSOn格式的URL接收的数据动态附加到我的列表视图中。但是我不知道它是如何工作的。 移动网站以以下格式检索对象: 在.html中,我有一个listview和一个函数,在其中尝试附加接收到的数据。我只展示身体。 也许这很容易,但是我是Web编程的新手,我不知道该如何附加检索到的数据。 有人可以帮我吗? 问题答案: 这是上述解决方案的jsfiddle(还有一个使用 代替的示例
问题内容: 我有以下代码: Angular2中 有什么方法可以将HTML添加到中吗?因为上述内容仅添加到组件HTML的末尾。 我也尝试过: 但这是行不通的,因为@ViewChild指令必须在函数之外,我再也无法控制它了 我也这样尝试过: 我不能做的事情是因为我的内容是动态的并且使用唯一的ID,并且我不能动态使用[innerHtml](它仅适用于我第一次放入它们的面板,然后其他任何更改都不能再使用i
问题内容: 我使用jquery fancybox 1.3.4作为弹出表单。 但是我发现fancybox无法绑定到动态添加的元素。例如,当我向当前文档中添加html元素时。 像这样:首先我使用jquery将一个元素附加到主体, 我叫fancybox, 但fancybox不适用于动态添加的元素。 我不能从此元素调用fancybox吗? 问题答案: 将fancybox(v1.3.x)绑定到动态添加的元素
我读过许多关于动态添加字段集的博客和帖子,但它们都给出了非常复杂的答案。我要求的不是那么复杂。 我的HTML代码: 因此,用户将在字段中输入一个整数值(我正在使用javascript检查验证)。点击链接,会出现相应数量的输入字段供他输入。我想用javascript实现这一点。 我不是javascript方面的专家。我在想如何通过链接检索用户在字段中填写的整数,并显示相应数量的输入字段。
我对JavaFX相对较新,我很困惑为什么我下面的代码没有产生预期的结果,即添加到网格中的标签。 我想做的是运行一个测试,将JavaFX标签添加到我的FXML GridPane,因为我想在不久的将来构建一个方法,允许用户选择一个文件,然后在用户选择文件时生成一个标签并将该标签添加到GridPane。 提前感谢, 代码: FXML代码是一个标准文件,其中定义了一个网格窗格,上面列出了fx:id。
问题内容: 我已经有了一个状态: 现在,我想用新信息对其进行更新。因此,向其添加另一个div。 像这样: 我该怎么做?或者我需要从零开始设置新状态 问题答案: 我认为以组件状态存储jsx组件不是一个好主意。我认为您应该仅以呈现组件所需的状态保存数据。 如果您真的想在状态中存储jsx,为什么不将“对话”属性定义为数组?然后,您可以向其中添加新组件。 但是最好只存储数据,例如“ first”和“ ne