I have to extend the size of JTextField on KeyPressed event as user enter the text in textfield.please give me some idea how to achieve this?
thanks in advance
Okay, jumping for it :-)
Let's assume the question is
How to adjust a JTextField's width to always fit its content width?
Usual collaborators
Quick example:
JTextField field = new JTextField("something");
JComponent parent = new JPanel(); // has FlowLayout by default
parent.add(field);
frame.add(parent);
// just to ensure it's bigger
frame.setSize(400, 400);
type ... and nothing happens: size remains at initial size. That's surprise: for some reason, the field's auto-validation simply doesnt't happen. In fact, a manual revalidate of the field on receiving a change notification (Note: the only correct listener type here is a DocumentListener) doesn't change the field as well:
final JTextField field = new JTextField("something");
DocumentListener l = new DocumentListener() {
private void updateField(JTextField field)
// has no effect
field.revalidate();
}
@Override
public void removeUpdate(DocumentEvent e) {
updateField(field);
}
@Override
public void insertUpdate(DocumentEvent e) {
updateField(field);
}
@Override
public void changedUpdate(DocumentEvent e) {
}
};
field.getDocument().addDocumentListener(l);
JComponent parent = new JPanel(); // has FlowLayout by default
parent.add(field);
frame.add(parent);
// just to ensure it's bigger
frame.setSize(400, 400);
@Gagandeep Bali found out that it's the parent that needs to be revalidated:
private void updateField(JTextField field) {
field.getParent().revalidate();
}
Unexpected, so the next question is the notorious why? Here: why doesn't the invalidate bubble up the container hierarchy until it finds a validateRoot? The answer is in the api doc:
Calls to revalidate that come from within the textfield itself will be handled by validating the textfield, unless the textfield is contained within a JViewport, in which case this returns false.
Or in other words: it's not bubbled up because the field itself is a validateRoot. Which leaves the other option to override and unconditionally return false:
JTextField field = new JTextField("something") {
@Override
public boolean isValidateRoot() {
return false;
}
};
JComponent parent = new JPanel(); // has FlowLayout by default
parent.add(field);
frame.add(parent);
// just to ensure it's bigger
frame.setSize(400, 400);
The price to pay for this, is that the scrolling doesn't work - which isn't a big deal in this context, as the text always fits into the field. Or implement slightly more intelligent, and return true if the actual width is less than the pref.