Java 向JDialog动态添加组件
当用户单击JDialog上的按钮时,我在向JDialog添加JComponents时遇到问题。基本上我希望它看起来像这样: 然后,当用户单击“添加新字段”时,我希望它如下所示: 我似乎无法让对话框添加新的JLabel或JTextField。谁能给我指出正确的方向吗 编辑:这是“添加新字段”按钮的操作(现在只需尝试标签) 解决方案: 我使用了mre的解决方案并使其发挥作用。这是我的最后一个功能:Java 向JDialog动态添加组件,java,swing,jdialog,Java,Swing,Jdialog,当用户单击JDialog上的按钮时,我在向JDialog添加JComponents时遇到问题。基本上我希望它看起来像这样: 然后,当用户单击“添加新字段”时,我希望它如下所示: 我似乎无法让对话框添加新的JLabel或JTextField。谁能给我指出正确的方向吗 编辑:这是“添加新字段”按钮的操作(现在只需尝试标签) 解决方案: 我使用了mre的解决方案并使其发挥作用。这是我的最后一个功能: @Action public void addNewField() { System.ou
@Action
public void addNewField()
{
System.out.println("New Field...");
Container contentPane = getContentPane();
JLabel label = new JLabel ("welcome");
label.setBounds(10,10,100,10); //some random value that I know is in my dialog
contentPane.add(label);
contentPane.validate();
contentPane.repaint();
this.pack();
}
我的另一个问题是,我在NetBeans中使用了“自由设计”布局,这意味着我的标签可能处于某种奇怪的位置,而不是在对话框的边界内(只是猜测)。我用label.setBounds()解决了这个问题,这样它就准确地显示了我想要它的位置。当从容器中动态添加/删除组件时,需要调用/和之后调用。前者将强制容器重新布局其组件,后者将删除任何可视的“工件”。我同意mre(他的答案是1+),但我还想补充一点,您可能需要调用
pack()
在添加或删除组件后,尤其是当对话框需要调整大小以适应您的图像显示可能发生的组件时,在JDialog上
编辑1例如,使用JFrame(但它与JDialog的工作原理相同):
为了避免进一步讨论所需/非所需的任何方法 注意:对于添加/删除
JComponents
(一行/一列结构简单,屏幕上的大小相同)仅需操作JFrame.pack()
但是对于一些标准的Swing布局管理器所部署的大多数完整GUI来说,需要使用
revalidate();
repaint(); // required in most of cases
一列的示例
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
需要明确的是,我如何在上调用revalidate()?JDialog没有重新验证方法吗?我想您的意思是我需要重新验证我正在添加的组件。@NeilMonday,revalidate()
是在包含其他组件的JComponent
上发出的(如果是这样的话),否则只需在JDialog()
上调用validate()
“当属性值更改,以致此组件的大小、位置或内部布局受到影响时,将对此组件自动调用此方法。”。这种自动更新与AWT不同,因为程序通常不再需要调用validate来更新GUI的内容…”-JdocsTry强制调用revalidate(),否则请尝试先在JDialog上调用repack(),然后再调用revalidate()和/或repaint()@Vort3x:是否有方法“repack())"? 我相信它被称为“包”(请看我的答案)。请看我答案中的编辑1。只有一个组件可以进入BorderLayout.CENTER
(或者BorderLayout.ANYTHING
)。顺便说一句,出于可用性的目的,addnewfield
按钮应该位于新字段出现的上方。这样,用户可以通过单击按钮5次(无需在单击过程中移动鼠标)添加5个新字段代码>当我选择添加一个新项目时,如果一个对话框跳到屏幕中间(向后-因为我经常将它们拖到屏幕的一侧),我会感到不安!谢谢,这也帮了我的忙。如果我可以投票支持两个答案,我会的。为什么我们需要使用repaint()?它将重新绘制以前创建的组件again@Raj默认情况下,Trivedi对于未接触的JComponet(包括从defualts到defualts的所有内容)不是必需的,最好也与repaint()一起使用(这里的一些线程中有bug和滞后)
revalidate();
repaint(); // required in most of cases
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}