在复选框的 itemStatechanged 事件上显示文本字段
Posted
技术标签:
【中文标题】在复选框的 itemStatechanged 事件上显示文本字段【英文标题】:Make a textfield visible on itemStatechanged event of a checkbox 【发布时间】:2013-06-06 23:08:20 【问题描述】:如何在 Swing 中的复选框的itemStatechanged
事件中显示文本字段?
我正在尝试创建一个带有复选框和文本字段的框架。我希望仅在选中复选框时才显示文本字段。因此,当我初始化组件时,我将textfield.setvisible
设置为false
,并为复选框添加了addItemListener
并调用itemStateChanged
事件并且选中了复选框,我设置了setVisible
true
的方法。
我的 SSCCE 看起来像:
package ui;
public class Evaluator extends javax.swing.JFrame
public Evaluator()
initComponents();
private void initComponents()
jCheckBox1 = new javax.swing.JCheckBox();
jTextField1 = new javax.swing.JTextField();
jTextField1.setVisible(false);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new java.awt.Dimension(800, 800));
jCheckBox1.setFont(new java.awt.Font("Tahoma", 0, 14));
jCheckBox1.setText("Properties");
jCheckBox1.addItemListener(new java.awt.event.ItemListener()
public void itemStateChanged(java.awt.event.ItemEvent evt)
jCheckBox1ItemStateChanged(evt);
);
jTextField1.setFont(new java.awt.Font("Tahoma", 0, 14));
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()
.addComponent(jCheckBox1)
.addGap(41, 41, 41)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(155, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(229, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jCheckBox1)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(34, 34, 34))
);
pack();
private void jCheckBox1ItemStateChanged(java.awt.event.ItemEvent evt)
// TODO add your handling code here:
if(evt.getStateChange()== java.awt.event.ItemEvent.SELECTED)
jTextField1.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)
java.util.logging.Logger.getLogger(Evaluator.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (InstantiationException ex)
java.util.logging.Logger.getLogger(Evaluator.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (IllegalAccessException ex)
java.util.logging.Logger.getLogger(Evaluator.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (javax.swing.UnsupportedLookAndFeelException ex)
java.util.logging.Logger.getLogger(Evaluator.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
java.awt.EventQueue.invokeLater(new Runnable()
public void run()
new Evaluator().setVisible(true);
);
private javax.swing.JCheckBox jCheckBox1;
private javax.swing.JTextField jTextField1;
【问题讨论】:
触及官方错误之一:-) 1) 对于这种情况,请使用CardLayout
,如short example 中所示。在第一张卡片中放置一个没有任何内容的 JPanel
,在第二张卡片中放置 JTextField
。 2) 为了尽快获得更好的帮助,请发帖SSCCE。
我不太清楚,但您是否尝试过 validate() 和 repaint() 面板/框架?
【参考方案1】:
基本上,您需要使框架(或父容器)无效以强制重新布局
private void jCheckBox2ItemStateChanged(java.awt.event.ItemEvent evt)
jTextField1.setVisible(jCheckBox2.isSelected());
invalidate();
validate();
更新
我还建议您避免将整个 UI 添加到***容器中,而是使用 JPanel
作为基础组件并围绕它们构建您的 UI。准备就绪后,只需将基本面板添加到您需要的任何***容器中即可。
【讨论】:
【参考方案2】:对于一个空间中的多个组件,请使用CardLayout
,如short example 中所示。
这是一个更具体的例子:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class CardLayoutDemo
public static void main(String[] args)
Runnable r = new Runnable ()
public void run()
final JCheckBox show = new JCheckBox("Have Text", false);
JPanel ui = new JPanel(new
FlowLayout(FlowLayout.CENTER, 5, 5));
ui.add( show );
final CardLayout cl = new CardLayout();
final JPanel cards = new JPanel(cl);
ui.add(cards);
cards.add(new JPanel(), "notext");
cards.add(new JTextField(8), "text");
ItemListener al = new ItemListener()
public void itemStateChanged(ItemEvent ie)
if (show.isSelected())
cl.show(cards, "text");
else
cl.show(cards, "notext");
;
show.addItemListener(al);
JOptionPane.showMessageDialog(null, ui);
;
SwingUtilities.invokeLater(r);
【讨论】:
@mKorbel 嗯?在该链接上,我看到了一个经过改进的(有一段时间没有访问过 OTN)页面,其中列出了 OTN 线程。你想让我看到什么具体的东西吗?【参考方案3】:很好的一课,LayoutManager
是如何工作的,只有 GridLayout
可以毫无问题地做到这一点,但这是它的属性
在行或列中最后一个JComponent
(当时的一部分是关于)can't be invisible
,然后容器被缩小
最简单的解决方法是显示容器,然后调用 setVisible(false)
包裹到 invokeLater
... ....
import java.awt.event.ItemEvent;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Evaluator
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private JCheckBox checkBox = new JCheckBox();
private JTextField textField = new JTextField(10);
public Evaluator()
checkBox.setText("Properties");
checkBox.addItemListener(new java.awt.event.ItemListener()
@Override
public void itemStateChanged(java.awt.event.ItemEvent evt)
if (evt.getStateChange() == ItemEvent.SELECTED)
textField.setVisible(true);
else
textField.setVisible(false);
);
//panel.setLayout(new GridLayout());
//panel.setLayout(new SpringLayout());
//panel.setLayout(new BorderLayout());
//panel.setLayout(new GridBagLayout());
//panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(checkBox/*, BorderLayout.NORTH*/);
panel.add(textField/*, BorderLayout.SOUTH*/);
//panel.doLayout();
//textField.setVisible(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
java.awt.EventQueue.invokeLater(new Runnable()
@Override
public void run()
textField.setVisible(false);
);
public static void main(String[] args)
java.awt.EventQueue.invokeLater(new Runnable()
@Override
public void run()
Evaluator evaluator = new Evaluator();
);
【讨论】:
以上是关于在复选框的 itemStatechanged 事件上显示文本字段的主要内容,如果未能解决你的问题,请参考以下文章