Disable button

F

Fencer

Hello, I have a button (JButton) in a dialog (JDialog) that should be
disabled if there's nothing entered in a particular textfield.

I solved that by creating this little class that implements the
DocumentListener interface:

class ButtonEnablerDisabler implements DocumentListener {

ButtonEnablerDisabler(JButton button) {
this.button = button;
}


public void changedUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


public void insertUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


public void removeUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


private JButton button;
}

and then I simply do:
myTextField.getDocument().addDocumentListener(new
ButtonEnablerDisabler(myButton));

it seems to work fine. Now my problem is this...I actually have four
text fields and the button shouldn't be enabled unless there's text in
all four.
My first attempt was silly: I simply repeated the line of code above for
all text fields, but that doesn't work because then you can enable the
button even if there's no text in the other fields. How should I solve
this problem?

- Fencer
 
F

Fencer

Fencer said:
Hello, I have a button (JButton) in a dialog (JDialog) that should be
disabled if there's nothing entered in a particular textfield.

I solved that by creating this little class that implements the
DocumentListener interface:

class ButtonEnablerDisabler implements DocumentListener {

ButtonEnablerDisabler(JButton button) {
this.button = button;
}


public void changedUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


public void insertUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


public void removeUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


private JButton button;
}

and then I simply do:
myTextField.getDocument().addDocumentListener(new
ButtonEnablerDisabler(myButton));

it seems to work fine. Now my problem is this...I actually have four
text fields and the button shouldn't be enabled unless there's text in
all four.
My first attempt was silly: I simply repeated the line of code above for
all text fields, but that doesn't work because then you can enable the
button even if there's no text in the other fields. How should I solve
this problem?

I wrote this solution which I'm going to go with until I find a better
one (it's not robust or elegant):

class ButtonEnablerDisabler implements DocumentListener {

ButtonEnablerDisabler(JButton button, int index, boolean initialState) {
this.index = index;
this.button = button;

ButtonEnablerDisabler.allSet[index] = initialState;
}


public void changedUpdate(DocumentEvent e) {
allSet[index] = e.getDocument().getLength() > 0;
button.setEnabled(shouldEnable());
}


public void insertUpdate(DocumentEvent e) {
allSet[index] = e.getDocument().getLength() > 0;
button.setEnabled(shouldEnable());
}


public void removeUpdate(DocumentEvent e) {
allSet[index] = e.getDocument().getLength() > 0;
button.setEnabled(shouldEnable());
}


private boolean shouldEnable() {
for (boolean b : ButtonEnablerDisabler.allSet) {
if (!b) {
return false;
}
}

return true;
}


private JButton button;
private int index;

private static boolean[] allSet = new boolean[]{false, false, false,
false};
}

Document doc = firstTextField.getDocument();
doc.addDocumentListener(new ButtonEnablerDisabler(button, 0,
doc.getLength() > 0));

doc = secondTextField.getDocument();
doc.addDocumentListener(new ButtonEnablerDisabler(button, 1,
doc.getLength() > 0));

doc = thirdTextField.getDocument();
doc.addDocumentListener(new ButtonEnablerDisabler(button, 2,
doc.getLength() > 0));

doc = fourthTextField.getDocument();
doc.addDocumentListener(new ButtonEnablerDisabler(button, 3,
doc.getLength() > 0));

- Fencer
 
J

John B. Matthews

Fencer said:
Hello, I have a button (JButton) in a dialog (JDialog) that should be
disabled if there's nothing entered in a particular textfield.

I solved that by creating this little class that implements the
DocumentListener interface:

class ButtonEnablerDisabler implements DocumentListener {

ButtonEnablerDisabler(JButton button) {
this.button = button;
}


public void changedUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


public void insertUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


public void removeUpdate(DocumentEvent e) {
button.setEnabled(e.getDocument().getLength() > 0);
}


private JButton button;
}

and then I simply do:
myTextField.getDocument().addDocumentListener(new
ButtonEnablerDisabler(myButton));

it seems to work fine. Now my problem is this...I actually have four
text fields and the button shouldn't be enabled unless there's text in
all four.
My first attempt was silly: I simply repeated the line of code above for
all text fields, but that doesn't work because then you can enable the
button even if there's no text in the other fields. How should I solve
this problem?

Perhaps something like this (untested):

// Return false if any JTextField in list is empty
public boolean allValid(List<JTextField> list) {
boolean result = true;
for (JTextField f : list) {
result &= f.getDocument().getLength() > 0;
}
return result;
}
 
F

Fencer

John said:
Perhaps something like this (untested):

// Return false if any JTextField in list is empty
public boolean allValid(List<JTextField> list) {
boolean result = true;
for (JTextField f : list) {
result &= f.getDocument().getLength() > 0;
}
return result;
}

Yes, that's a better solution than mine! I see that you're using a
bitwise operator in order to make the method have a single point of exit
in an elegant way. Interesting!

Thank you for your help!

- Fencer
 
J

John B. Matthews

private boolean shouldEnable() {
for (boolean b : ButtonEnablerDisabler.allSet) {
if (!b) {
return false;
}
}
return true;
}

Excellent. By returning from the method after the first false result,
your approach offers an efficiency similar to that of the
conditional-and operator. Using the logical compound assignment
operator, as Lew helpfully clarified, my approach must examine each
predicate. As the logical test is free of side-effects, I'd tend to
prefer your implementation.
 
R

Roedy Green

for (JTextField f : list) {
result &= f.getDocument().getLength() > 0;
}
return result;
}

If this list were long, you want to quit early rather than continuing
to compute even after you know the result. You can do that with a
break.

Or use multiple returns. Multiple returns are not that wicked in tiny
methods. see http://mindprod.com/jgloss/andoperator.html
--
Roedy Green Canadian Mind Products
http://mindprod.com

"The coolest thing to do with your data will be thought of by someone else."
~ Rufus Pollock (born: 1978 age: 31) in Talk.
 
J

John B. Matthews

Roedy Green said:
If this list were long, you want to quit early rather than continuing
to compute even after you know the result. You can do that with a
break.

Or use multiple returns. Multiple returns are not that wicked in tiny
methods. see http://mindprod.com/jgloss/andoperator.html

I agree, as I suggested in my reply to the OP and as your examples show.
Indeed, your TestAndOr example shows efficient multiple conditional
versions for both conjunction and disjunction.

One caveat is that the predicates should have no side-effects. That's
not a problem for a series of boolean parameters, but methods may be
impure.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top