javaswingjpaneljtabbedpanedynamically-generated

JPanel dynamically generate outside from its original location


I'm dynamically generating some text boxes and labels inside a JPanel but when I place that panel inside a JTabbedPane it's not generate inside its original location. it always go to somewhere else.

Code inside JFrame class constructor:

    panel = jPanel1;
    panel.setLayout(new FlowLayout());
    add(panel, BorderLayout.LINE_START);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

Code inside a JButton:

    JLabel lbl = new JLabel();
    lbl.setText("Label");
    panel.add(lbl);

    JTextField txt = new JTextField(12);
    txt.setText("Text field");
    panel.add(txt);
    panel.revalidate();
    validate();

The button is use to generate text boxes and labels dynamically. jPanel1 is a panel placed inside a frame. its works perfectly with directly placed inside a frame but after it is placed inside a tabbed pane it's messing around.

Is there a method to refresh panel and remove components inside it after generating components inside it?

here is the complete Jframe class:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author sajithru
 */
public class DynamicTextboxes extends javax.swing.JFrame {

    /**
     * Creates new form DynamicTextboxes
     */
    private JPanel panel;

    public DynamicTextboxes() {
        initComponents();
        panel = jPanel1;
        panel.setLayout(new FlowLayout());
        add(panel, BorderLayout.LINE_START);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 206, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 258, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("tab1", jPanel1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(190, 190, 190)
                .addComponent(jButton1)
                .addContainerGap(216, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 211, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(16, 16, 16)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 286, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addContainerGap(40, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        JLabel lbl = new JLabel();
        lbl.setText("Label");
        panel.add(lbl);

        JTextField txt = new JTextField(12);
        txt.setText("Text field");
        panel.add(txt);
        panel.revalidate();
        validate();
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        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(DynamicTextboxes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(DynamicTextboxes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(DynamicTextboxes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(DynamicTextboxes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DynamicTextboxes().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JTabbedPane jTabbedPane1;
    // End of variables declaration
}

Solution

  • I suspect that you are using setBounds(), or something similar, to position components in a Container that has some (default) layout lying in wait for your call to revalidate(). Instead, invoke pack() on the enclosing Window before calling setVisible().

    Addendum: I tried using pack() … but result is still the same.

    Your layout is cutting off the new rows. The example below uses pack() to resize the enclosing Window. This related example illustrates revalidate() and repaint(). Also consider using a JScrollPane, seen here.

    image

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    /**
     * @see https://stackoverflow.com/a/17165034/230513
     */
    public class DynamicTextboxes extends javax.swing.JFrame {
    
        /**
         * Creates new form DynamicTextboxes
         */
        public DynamicTextboxes() {
            initComponents();
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setVisible(true);
        }
    
        private void initComponents() {
    
            jButton1 = new javax.swing.JButton();
            jTabbedPane1 = new javax.swing.JTabbedPane();
            jPanel1 = new javax.swing.JPanel(new GridLayout(0, 1));
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            jButton1.setText("jButton1");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });
            jPanel1.add(createPanel());
            jTabbedPane1.addTab("tab1", jPanel1);
            add(jTabbedPane1);
            JPanel p = new JPanel();
            p.add(jButton1);
            add(p, BorderLayout.SOUTH);
            pack();
            setLocationByPlatform(true);
        }
    
        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
            jPanel1.add(createPanel());
            pack();
        }
    
        private JPanel createPanel() {
            JPanel p = new JPanel();
            JLabel lbl = new JLabel();
            lbl.setText("Label");
            p.add(lbl);
            JTextField txt = new JTextField(12);
            txt.setText("Text field");
            p.add(txt);
            return p;
        }
    
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new DynamicTextboxes().setVisible(true);
                }
            });
        }
        // Variables declaration - do not modify
        private javax.swing.JButton jButton1;
        private javax.swing.JPanel jPanel1;
        private javax.swing.JTabbedPane jTabbedPane1;
        // End of variables declaration
    }