3

How to make a text field visible on itemStatechanged event of a check box in Swing?

I am trying to create a frame with a check box and a text field. I want the text field to be displayed only when the check box is selected. So when I initialize the components, I have set the textfield.setvisible to false and for the check box added a addItemListener and call the itemStateChanged event and there is the check box is selected, I set the setVisible method to true.

My SSCCE looks like:

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;                
}
java_learner
  • 182
  • 3
  • 13
  • touched one of official bug :-) – mKorbel Jun 11 '13 at 07:12
  • 1
    1) For this case, use a [`CardLayout`](http://docs.oracle.com/javase/7/docs/api/java/awt/CardLayout.html) as see in this [short example](http://stackoverflow.com/a/5786005/418556). Put a `JPanel` with nothing in the first card, and the `JTextField` in the second card. 2) For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jun 11 '13 at 07:15
  • 1
    I don't know exactly, but have you tried to validate() and repaint() the Panel/Frame? – marc3l Jun 11 '13 at 07:16

3 Answers3

3

Basically, you need to invalidate the frame (or parent container) to force it be re-layout

private void jCheckBox2ItemStateChanged(java.awt.event.ItemEvent evt) {
    jTextField1.setVisible(jCheckBox2.isSelected());
    invalidate();
    validate();
}

Updated

I'd also suggest that you avoid adding your entire UI onto a top level container, instead use a JPanel as you base component and build you UI's around them. When you're ready, simply add the base panel to what ever top level container you need.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
3

For many components in one space, use a CardLayout as see in this short example.

Here is a more specific example:

enter image description here

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);
    }
}
Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • @mKorbel Huh? At that link I see a revamped (have not visited OTN in a while) page listing OTN threads. Was there something specific you intended me to see? – Andrew Thompson Jun 11 '13 at 08:07
3
  • great lesson, how the LayoutManager works, only GridLayout can do that without any issue, but this is its property

  • last JComponent in the row or column (part of then is about) can't be invisible, then container is shrinked

  • easiest work_around is to display container, then to call setVisible(false) wrapped into invokeLater

enter image description here ... .... enter image description here

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();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319