3

How to remove components from jpanel. In the below code, textfields are created depending on the val. This is working fine for creating. But when the value is lowered in the spinner, the textfield should also get reduced.

i tried to remove all the components from array txtField and did not work.

int val = (int) textFieldGen.getModel().getValue(); //getting the value from JSpinner

JTextField[] txtField = new JTextField[val]; 

//tried panel.revalidate(); panel.repaint();

//removing elements if exists.  gives null pointer exception.  

try {
     for (JTextField txtComp : txtField) {
       panel.remove(txtComp);
    }
} catch (Exception ex) {
        System.out.println(ex);
}

panel.revalidate();
panel.repaint();


//creating    
int row = 1;
for (int i = 0; i < txtField.length; i++) {
    row++;           
    layout.appendRow(RowSpec.decode("30px"));
    txtField[i] = new JTextField(10);
    panel.add(txt[i], cc.xy(4, row));
}
panel.revalidate();
panel.repaint();
FirmView
  • 3,130
  • 8
  • 34
  • 50

3 Answers3

5

I don't see where you call remove(...) on your "panel" JPanel, and so I don't know how you remove JTextFields. Some suggestions:

  • If you must go the current route that you're proposing, use a single dedicated container JPanel that holds the JTextFields in a GridLayout and holds no other components.
  • Remove all components before adding new ones (if that is what you need to do)
  • Call both revalidate() and 'repaint()` on the container JPanel after removals and additions.
  • Consider instead using a JTable for this where you simply add or remove rows. This in my mind would be the simplest and cleanest solution for a problem like this.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
2

JTextField[] txtField = new JTextField[val];

This line does NOT init the array, just creates one with a count of val. The elements are null by default, hence throwing the NullPointerException when you iterate the array with the for-each loop.

You need to initialize the array with valid JTextField objects.

asgs
  • 3,928
  • 6
  • 39
  • 54
  • it's done in the last part of the code, the lines commented by //creating. Not entirely clear from the snippet, but optimistic me hopes that they are called before trying to remove anything :-) – kleopatra Sep 18 '12 at 07:28
  • @kleopatra No that doesn't solve this issue, does it? When the `remove()` method is called on the `JPanel` instance, it expects a non-null `Component` to be removed. This method is called way before the `JTextField` instances are created. – asgs Sep 18 '12 at 07:33
  • 2
    as I said, to me the sequence isn't entirely clear from the snippets. If it's the _real_ sequence (remove before instantiate) you indeed spotted the reason :). If it's just snippets in random order, there is something else wrong (my bet, but only guessing) - @FirmView please clarify, best with an SSCCE – kleopatra Sep 18 '12 at 09:32
2

Why not simply have a method accepting the number of JTextFields you want and let it return a JPanel with the correct number of needed JTextFields already added to the JPanel with appropriate layout and all:

public JPanel createPanel(int numberOfTextFields) {
    JPanel panel=new JPanel(new ...);//create new panel

    JTextField tfs[]=new JTextField[numberOfTextFields];//create array of textFields

    for(int i=0;i<numberOfTextFields;i++) {
        tfs[i]=new JTextField();//create the textfield
        panel.add(tfs[i]...);//add it to the panel
    }

    return panel;
}

and simply remove the last JPanel from the JFrames contentPane.

Or empty the JFrame again using: getContentPane().removeAll(); and add the new JPanel to it and the JPanel which contains the user controls, though the user controls panel wont have to be re-created each time.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138