Search code examples
javaswingjframejtextfield

Appear automatically JTextField


Please, how can I appear automatically some JTextField from what user choose in JComboBox ? My example is simple. I have a JComboBox in my box with some operation. And depending on what the user choose from this JComboBox, I appear one or more JTextField.

I have this code:

public static void main(String[] args) {

    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            CalculatriceFenetre fenetre = new CalculatriceFenetre();
            fenetre.setVisible(true);
        }
    });
}

.

public class CalculatriceFenetre extends JFrame {

    private JTextField field1, field2;
    private JComboBox liste;

    public CalculatriceFenetre() {
        super();

        build();
    }

    private void build() {
        setTitle("Calculatrice");
        setSize(400, 200);
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setContentPane(buildContentPane());
    }

    private JPanel buildContentPane() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());
        panel.setBackground(Color.white);

        field1 = new JTextField();
        field1.setColumns(10);

        field2 = new JTextField();
        field2.setColumns(10);
        field2.setVisible(false);

        panel.add(field1);
        panel.add(field2);

        liste = new JComboBox(new OperateursModel());
        liste.addActionListener(new CustomActionListener());
        panel.add(liste);

        return panel;
    }

    class CustomActionListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            if (liste.getSelectedItem().equals("op1")) {
                 field2.setVisible(true);
            }
        }
    }

.

public class OperateursModel extends DefaultComboBoxModel {
private ArrayList<String> operateurs;

public OperateursModel(){
    super();
    operateurs = new ArrayList<String>();
    operateurs.add("op1");

}

public String getSelectedOperateur(){
    return (String)getSelectedItem();
}

@Override
public Object getElementAt(int index) {
    return operateurs.get(index);
}

@Override
public int getSize() {
    return operateurs.size();
}

@Override
public int getIndexOf(Object element) {
    return operateurs.indexOf(element);
    }
}

Solution

  • Like I mentioned, this is an easy approach for your question. Create all the JTextFields you need first and toggle its visibility instead of removing and adding it on run time.

    enter image description here

    import java.util.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    class DynamicTextFieldsApp
    {
        public static void main(String[] args){
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame("JTextField Toggler");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
                f.add(new DisplayPanel());
                f.pack();
                f.setLocationRelativeTo(null);
            }});
        }
    }
    

    A simple JPanel with comboBox and several JTextFields.

    class DisplayPanel extends JPanel
    {
        public static final int PLAYERS = 5;
        private JComboBox cmbPlayerNumber;
        private JTextField[] txtPlayerName;
        private JLabel lblPlayerNumber;
    
        public DisplayPanel(){
            setPreferredSize(new Dimension(170, 240));
            createComponents();
            initComponents();
            loadComponents();
            setBoundsForComponents();       
        }
    
        private void createComponents(){
            cmbPlayerNumber = new JComboBox(new String[]{"1", "2", "3", "4", "5"});
            txtPlayerName = new JTextField[PLAYERS];
            lblPlayerNumber = new JLabel("Num of Players");     
        }
    
        private void initComponents(){
            for(int x=0; x<PLAYERS; x++){
                txtPlayerName[x] = new JTextField("No Name " + (x+1));
                txtPlayerName[x].setVisible(false);     
            }
            cmbPlayerNumber.setSelectedIndex(-1);
            cmbPlayerNumber.addActionListener(new CmbListener());       
        }
    
        private void loadComponents(){
            add(cmbPlayerNumber);
            add(lblPlayerNumber);
            for(int x=0; x<PLAYERS; x++)
                add(txtPlayerName[x]);          
        }
    
        private void setBoundsForComponents(){
            setLayout(null);
            lblPlayerNumber.setBounds(10, 0, 150, 30);          
            cmbPlayerNumber.setBounds(10, 30, 150, 30);
            for(int x=0; x<PLAYERS; x++)
                txtPlayerName[x].setBounds(10, (30*x)+70, 150, 30);
        }
    
        private class CmbListener implements ActionListener
        {
            public void actionPerformed(ActionEvent e)
            {
                int numOfPlayers = cmbPlayerNumber.getSelectedIndex() + 1;
                for(int x=0; x<numOfPlayers; x++)
                    txtPlayerName[x].setVisible(true);
                for(int x=numOfPlayers; x<PLAYERS; x++){
                    txtPlayerName[x].setVisible(false);             
                    txtPlayerName[x].setText("No name " + (x+1));                   
                }               
            }
        }                   
    }
    

    And of course, you can work with some layout manager instead of null layout.