动态创建 jCheckBox 并添加到 jScrollPane
Posted
技术标签:
【中文标题】动态创建 jCheckBox 并添加到 jScrollPane【英文标题】:Dynamically create jCheckBox and add to a jScrollPane 【发布时间】:2012-05-01 08:36:38 【问题描述】:编辑:使用下面介绍的解决方案,我已将代码更改为在 JScrollPane 中包含 JPanel。使用 JButton 我将 JCheckBoxes 添加到 JScrollPane 内的 JPanel。这是解决了一个问题,因为 JScrollPane 只能使用一个 JComponent。其余问题已解决,为 JScrollPane 内的 JPanel 设置了一个网格布局。为了后代,我将最初的问题保留在这里:
原始问题:我正在尝试动态创建 JCheckBox 并将它们添加到 JScrollPane,但可惜我收效甚微。我已将其简化为单一的概念验证实现。
我在 JFrame 中有一个 JScrollPaneon 和一个 JPanel。同样在 JPanel 上,我添加了一个按钮,该按钮应该在单击时将 JCheckBox 添加到 JScrollPane。应该足够简单。按钮内部代码如下:
private void addCheckBoxActionPerformed(java.awt.event.ActionEvent evt)
JCheckBox cb = new JCheckBox("New CheckBox");
jScrollPaneCheckBoxes.add(cb);
jScrollPaneCheckBoxes.revalidate();
代码运行似乎没有错误。我没有例外,使用调试器表明 JCheckBox 实际上已添加到 JScrollPane 中。不幸的是,应用程序中没有显示任何内容。我需要关于在哪里寻找问题的方向。
这是一段您可以直接运行的快速代码。不幸的是,我使用 Netbeans 和它的 GUI 设计器将它放在一起,因此它比它需要的要长一点,尤其是生成的代码。关注jButton1ActionPerformed方法,上面的代码就是从那里得到的。
编辑:此代码现在可以满足我的需要。 :-)
package dynamiccheckboxsscce;
import javax.swing.JCheckBox;
public class Main extends javax.swing.JFrame
/**
* Creates new form Main
*/
public Main()
initComponents();
@SuppressWarnings("unchecked")
private void initComponents()
jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setPreferredSize(new java.awt.Dimension(250, 250));
jPanel1.setPreferredSize(new java.awt.Dimension(300, 250));
jPanel1.setLayout(new java.awt.GridLayout(0, 2, 10, 10));
jScrollPane1.setViewportView(jPanel1);
jButton1.setText("Add Checkbox");
jButton1.addActionListener(new java.awt.event.ActionListener()
public void actionPerformed(java.awt.event.ActionEvent evt)
jButton1ActionPerformed(evt);
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(112, 112, 112)))));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap()));
pack();
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
JCheckBox cb = new JCheckBox("New CheckBox");
jPanel1.add(cb);
jPanel1.revalidate();
jPanel1.repaint();
/**
* @param args the command line arguments
*/
public static void main(String args[])
/*
* Set the Nimbus look and feel
*/
try
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
if ("Nimbus".equals(info.getName()))
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
catch (ClassNotFoundException ex)
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (InstantiationException ex)
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (IllegalAccessException ex)
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (javax.swing.UnsupportedLookAndFeelException ex)
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable()
public void run()
new Main().setVisible(true);
);
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
提前致谢。
【问题讨论】:
不发布SSCCE,您可以等待与下面相同的答案 sscce 传入 - 请稍等。 This answer of mine 包含我动态添加项目的滚动窗格 我已经将上面的代码更新为一个工作示例,它结合了 mKorbel 提出的观点和他提供的代码。上面的代码只是使用了稍微不同的方法和不同的布局管理器,但结果或多或少是相同的。 【参考方案1】:如果不发布SSCCE,您必须接受JScrollPane 被指定为仅嵌套一个JComponent
,
如果您想在JScrollPane
中添加更多JComponent
,请将JPanel 放在那里,然后将新的JComponent
添加到JPanel
而不是JScrollPane
查看how dynamically add / remove JComponents
编辑
您必须为 JPanel 设置适当的 LayoutManager
您应该将 JPanel 添加到 JScrollPane
例如(不使用内置设计器,即使是安全的时间...,也需要对使用过的 SwingFramework 和 Swing 有最好的了解,我对普通的 Swing 很满意)
代码
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class AddJCheckBoxToJScrollPane
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame();
private JButton jButton1;
private JPanel jPanel1;
private JScrollPane jScrollPane1;
public AddJCheckBoxToJScrollPane()
jPanel1 = new JPanel();
jPanel1.setLayout(new GridLayout(0, 2, 10, 10));
jScrollPane1 = new JScrollPane(jPanel1);
jButton1 = new JButton("Add Checkbox");
jButton1.addActionListener(new java.awt.event.ActionListener()
public void actionPerformed(java.awt.event.ActionEvent evt)
JCheckBox cb = new JCheckBox("New CheckBox");
jPanel1.add(cb);
jPanel1.revalidate();
jPanel1.repaint();
);
frame.add(jScrollPane1);
frame.add(jButton1, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
//frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
public static void main(String args[])
try
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
if ("Nimbus".equals(info.getName()))
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
catch (ClassNotFoundException ex)
catch (InstantiationException ex)
catch (IllegalAccessException ex)
catch (javax.swing.UnsupportedLookAndFeelException ex)
java.awt.EventQueue.invokeLater(new Runnable()
public void run()
new AddJCheckBoxToJScrollPane();
);
【讨论】:
sscce 传入 - 请稍等。 感谢您的解决方案。我从这次经历中学到了两件事。 1. 显示的内容与布局有关,而不是与组件有关 2. 我对布局了解不够。 :-)【参考方案2】:你应该调用 repaint() 而不是 revalidate()。
见Revalidate vs. Repaint
【讨论】:
用重绘替换了重新验证 - 没有区别。甚至两者都加了。谢谢你的建议。从您提供的链接中引用:“一旦添加新组件或删除旧组件,就会在容器上调用 revalidate。” 嗯。我的想法是,孩子们的重绘不会捕捉到添加的对象,但顶层面板上的重绘会。如果这不是问题,您需要向我们提供更多信息。 @Charles 请just try once,顺便说一句,我建议删除这个答案,因为它太敏感了 如果有的话,它会阻止更多人发布相同的内容。我不介意它是否被否决,因为这是错误的答案。 @mKorbel - 语气在网上非常困难,所以我要给你怀疑的好处,如果我的问题让你烦恼,你可以跳过它 -我不想激怒你或浪费你的时间;我只是想尝试解决我的问题而没有任何麻烦。您提供的链接包括这种语言,我无法将其识别为英语:“避免进一步讨论任何必需/非必需的方法......注意:用于添加/删除 JComponents(仅在一行/列中的简单结构并且在屏幕上具有相同的大小)就足够了,只需操作 JFrame.pack()"以上是关于动态创建 jCheckBox 并添加到 jScrollPane的主要内容,如果未能解决你的问题,请参考以下文章
如何通过SQL将一列JCheckBox添加到JTable? [重复]