javaswingjtextfieldcardlayout

JTextField doesn't appear after switching panel using CardLayout


i have 4 panels associated to a content panel which uses a card layout. If i try to switch between the cards by using the buttons, i can see the JLabels but no JTextFields. I assume they are there because there is space between the JLabels, so i tried to revalidate and repaint the panels after switching to them but that wasn't working. Do i have to repaint them somewhere else? Or am i missing something?

package data;

import javax.swing.\*;
import java.awt.\*;

public class Frame {

    JFrame frame;
    JPanel panelCont, panelStart, panelAns, panelGT, panelSyn;
    JButton buttonAns, buttonGT, buttonSyn, buttonSendAns, buttonSendGT, buttonSendSyn;

    JTextField jtfAnsCaseID, jtfAnsKeywords, jtfAnsAnswer;
    JLabel jlAnsCaseID, jlAnsKeywords, jlAnsAnswer;
    JTextField jtfGTID, jtfGTGenericTerm;
    JLabel jlGTID, jlGTGenericTerm;
    JTextField jtfSynSynonym, jtfSynID;
    JLabel jlSynSynonym, jlSynID;

    CardLayout cl;

    Frame() {
        frame = new JFrame("naoImporter");
        panelCont = new JPanel();
        cl = new CardLayout();
        panelCont.setLayout(cl);

        //Initialize components for start
        panelStart = new JPanel();
        buttonAns = new JButton("Answer");
        buttonGT = new JButton("Generic terms");
        buttonSyn = new JButton("Synonyms");

        //Initialize components for answers
        panelAns = new JPanel();
        jlAnsCaseID = new JLabel("CaseID:");
        jtfAnsCaseID = new JTextField();
        jlAnsKeywords = new JLabel("Keywords:");
        jtfAnsKeywords = new JTextField();
        jlAnsAnswer = new JLabel("Answer:");
        jtfAnsAnswer = new JTextField();
        buttonSendAns = new JButton("Send Data!");

        //Initialize components for generic terms
        panelGT = new JPanel();
        jlGTID = new JLabel("ID");
        jtfGTID = new JTextField();
        jlGTGenericTerm = new JLabel("Generic term:");
        jtfGTGenericTerm = new JTextField();
        buttonSendGT = new JButton("Send Data!");

        //Initialize components for synonyms
        panelSyn = new JPanel();
        jlSynSynonym = new JLabel("Synonym:");
        jtfSynSynonym = new JTextField();
        jlSynID = new JLabel("ID:");
        jtfSynID = new JTextField();
        buttonSendSyn = new JButton("Send Data!");

        //Configuring each component
        panelStart.setLayout(new FlowLayout());
        panelAns.setLayout(new FlowLayout());
        panelGT.setLayout(new FlowLayout());
        panelSyn.setLayout(new FlowLayout());

        jtfAnsCaseID.setPreferredSize(new Dimension(30, jtfAnsCaseID.getHeight()));
        jtfAnsKeywords.setPreferredSize(new Dimension(200, jtfAnsKeywords.getHeight()));
        jtfAnsAnswer.setPreferredSize(new Dimension(200, jlAnsAnswer.getHeight()));

        jtfGTID.setPreferredSize(new Dimension(30, jtfGTID.getHeight()));
        jtfGTGenericTerm.setPreferredSize(new Dimension(100, jtfGTGenericTerm.getHeight()));

        jtfSynSynonym.setPreferredSize(new Dimension(100, jtfSynSynonym.getHeight()));
        jtfSynID.setPreferredSize(new Dimension(30, jtfSynID.getHeight()));


        //Button listener logic
        buttonAns.addActionListener(e -> cl.show(panelCont, "2"));

        buttonGT.addActionListener(e -> cl.show(panelCont, "3"));

        buttonSyn.addActionListener(e -> cl.show(panelCont, "4"));

        buttonSendAns.addActionListener(e -> {
            cl.show(panelCont, "1");
        });

        buttonSendGT.addActionListener(e -> {
            cl.show(panelCont, "1");
        });

        buttonSendSyn.addActionListener(e -> {
            cl.show(panelCont, "1");
        });

        //Adding component ot each panel
        panelStart.add(buttonAns);
        panelStart.add(buttonGT);
        panelStart.add(buttonSyn);

        panelAns.add(jlAnsCaseID);
        panelAns.add(jtfAnsCaseID);
        panelAns.add(jlAnsKeywords);
        panelAns.add(jtfAnsKeywords);
        panelAns.add(jlAnsAnswer);
        panelAns.add(jtfAnsAnswer);
        panelAns.add(buttonSendAns);

        panelGT.add(jlGTID);
        panelGT.add(jtfGTID);
        panelGT.add(jlGTGenericTerm);
        panelGT.add(jtfGTGenericTerm);
        panelGT.add(buttonSendGT);

        panelSyn.add(jlSynSynonym);
        panelSyn.add(jtfSynSynonym);
        panelSyn.add(jlSynID);
        panelSyn.add(jtfSynID);
        panelSyn.add(buttonSendSyn);

        panelCont.add(panelStart, "1");
        panelCont.add(panelAns, "2");
        panelCont.add(panelGT, "3");
        panelCont.add(panelSyn, "4");


        cl.show(panelCont, "1");

        frame.add(panelCont);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

Picture of start panel

Picture of answer panel after switching to it


Solution

  • i can see the JLabels but no JTextFields

    tfAnsCaseID.setPreferredSize(new Dimension(30, jtfAnsCaseID.getHeight()));
    

    A Swing component does NOT have a size until the frame has been packed or made visible.

    The default height is 0, so you are giving your components a preferred height of 0. The FlowLayout will respect the preferred size, so there is nothing to paint.

    All Swing components are responsible for determining their own preferred size, so don't attempt to manage the preferred size on your own with some random value.

    Instead use:

    jtfAnsCaseID = new JTextField(5);
    

    The number specified in the constructor will allow the text field to calculated its preferred size to display 5 "W" characters based on the Font and Borders used.