setEnabled(false) in new GenericDialog

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

setEnabled(false) in new GenericDialog

Michael Doube
Hi All,

I have a TextField and a Checkbox in a GenericDialog.  I want the TextField to be setEnabled(false) , i.e. greyed out, when the Checkbox is false.  This I can accomplish using a DialogListener when the user clicks on the Checkbox.  But I want the default setting to be that the Checkbox is false and the TextField is correspondingly greyed out - i.e. before user input changes the state of any of the Components, triggering the Listener.

I've tried getting the Vector of numeric fields, then getting the correct element using both get() and elementAt(), and setEnabled(false), directly before shwoDialog() but it doesn't seem to work.

...
gd.addCheckbox("Do it", false)
gd.addNumericField("How many times?", 1, 0); //to be greyed out initially
...
Vector<?> numbers = gd.getNumericFields();
TextField num = (TextField) numbers.get(3) // or .elementAt(3);
num.setEnabled(false);
showDialog();

Any ideas?  I'm on Ubuntu 10.04, JRE 1.6 19, IJ 1.43s

Michael
Reply | Threaded
Open this post in threaded view
|

Re: setEnabled(false) in new GenericDialog

Michael Schmid
Hi Michael,

Two remarks:

(1) Your code looks fine to me, but the Java specification does not  
say whether a disabled TextField will be somehow decorated (grayed  
out) or not. Java does not know that the label 'How many times'  
belongs to the textfield, so the label certainly won't be grayed out.  
Input into the text field should be disabled, however.

(2) SetEnabled in DialogItemChanged of a DialogListener will often  
fail on a Macintosh - at least under Java 1.5 on the Mac there is an  
annoying bug that makes such code not work properly:
Out of several nearly simultaneous changes to dialog components only  
the first change is displayed, all other changes wait for the next  
update, e.g., if the user clicks another field. So enabling the input  
field can be delayed.

On the Mac, the easiest work around would be a delay of 100 millisec  
before a setEnabled call in a DialogListener.

(By the way, this bug is also the reason why the 'preview' and  
'wait...' label of the preview checkbox is sometimes displayed  
incorrectly on Macs.)


Michael
________________________________________________________________

On 14 Apr 2010, at 02:43, Doube, Michael wrote:

> Hi All,
>
> I have a TextField and a Checkbox in a GenericDialog.  I want the  
> TextField to be setEnabled(false) , i.e. greyed out, when the  
> Checkbox is false.  This I can accomplish using a DialogListener  
> when the user clicks on the Checkbox.  But I want the default  
> setting to be that the Checkbox is false and the TextField is  
> correspondingly greyed out - i.e. before user input changes the  
> state of any of the Components, triggering the Listener.
>
> I've tried getting the Vector of numeric fields, then getting the  
> correct element using both get() and elementAt(), and setEnabled
> (false), directly before shwoDialog() but it doesn't seem to work.
>
> ...
> gd.addCheckbox("Do it", false)
> gd.addNumericField("How many times?", 1, 0); //to be greyed out  
> initially
> ...
> Vector<?> numbers = gd.getNumericFields();
> TextField num = (TextField) numbers.get(3) // or .elementAt(3);
> num.setEnabled(false);
> showDialog();
>
> Any ideas?  I'm on Ubuntu 10.04, JRE 1.6 19, IJ 1.43s
>
> Michael
Reply | Threaded
Open this post in threaded view
|

Re: setEnabled(false) in new GenericDialog

Michael Doube
Hi Michael,

Thank you for your response.

> Input into the text field should be disabled, however.

Unfortunately, it is not disabled until after any one of the dialog
fields is actively changed by the user (including the TextField in
question).  So if my code is good, then this seems to me to be a bug -
unable to set initial state of dialog fields to setEnabled(false).

> (2) SetEnabled in DialogItemChanged of a DialogListener will often
> fail on a Macintosh ...

> On the Mac, the easiest work around would be a delay of 100 millisec
> before a setEnabled call in a DialogListener.

So if an event triggers a DialogListener to make several changes to a
dialog, we should wait 100 ms between applying each change?

Michael

> ________________________________________________________________
>
> On 14 Apr 2010, at 02:43, Doube, Michael wrote:
>
>> Hi All,
>>
>> I have a TextField and a Checkbox in a GenericDialog.  I want the
>> TextField to be setEnabled(false) , i.e. greyed out, when the
>> Checkbox is false.  This I can accomplish using a DialogListener
>> when the user clicks on the Checkbox.  But I want the default
>> setting to be that the Checkbox is false and the TextField is
>> correspondingly greyed out - i.e. before user input changes the
>> state of any of the Components, triggering the Listener.
>>
>> I've tried getting the Vector of numeric fields, then getting the
>> correct element using both get() and elementAt(), and setEnabled
>> (false), directly before shwoDialog() but it doesn't seem to work.
>>
>> ...
>> gd.addCheckbox("Do it", false)
>> gd.addNumericField("How many times?", 1, 0); //to be greyed out
>> initially
>> ...
>> Vector<?>  numbers = gd.getNumericFields();
>> TextField num = (TextField) numbers.get(3) // or .elementAt(3);
>> num.setEnabled(false);
>> showDialog();
>>
>> Any ideas?  I'm on Ubuntu 10.04, JRE 1.6 19, IJ 1.43s
>>
>> Michael
Reply | Threaded
Open this post in threaded view
|

Re: setEnabled(false) in new GenericDialog

ctrueden
Hi Michael & Michael,

We ran into these same issues when coding the Bio-Formats Importer plugin.
You can see our approach at:

https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/loci-plugins/src/loci/plugins/importer/ImporterDialog.java?rev=6039#L403

The method (verifyOptions) is essentially a big bag of logic for controlling
which options get grayed out in which situations. To address the Mac OS X
glitch, we have a horrible hack at:

https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/loci-plugins/src/loci/plugins/importer/ImporterDialog.java?rev=6039#L616

The hack cycles the keyboard focus across all the components and sleeps a
bit (100ms), which seems to force the UI to update on most (all?) Mac OS X
systems.

For what it's worth, we are exploring ways to simplify some of this
complexity for ImageJ2.

HTH,
Curtis

On Wed, Apr 14, 2010 at 10:19 AM, Michael Doube <[hidden email]>wrote:

> Hi Michael,
>
> Thank you for your response.
>
>
>  Input into the text field should be disabled, however.
>>
>
> Unfortunately, it is not disabled until after any one of the dialog fields
> is actively changed by the user (including the TextField in question).  So
> if my code is good, then this seems to me to be a bug - unable to set
> initial state of dialog fields to setEnabled(false).
>
>  (2) SetEnabled in DialogItemChanged of a DialogListener will often
>> fail on a Macintosh ...
>>
>
>  On the Mac, the easiest work around would be a delay of 100 millisec
>> before a setEnabled call in a DialogListener.
>>
>
> So if an event triggers a DialogListener to make several changes to a
> dialog, we should wait 100 ms between applying each change?
>
>
> Michael
>
>  ________________________________________________________________
>>
>> On 14 Apr 2010, at 02:43, Doube, Michael wrote:
>>
>>  Hi All,
>>>
>>> I have a TextField and a Checkbox in a GenericDialog.  I want the
>>> TextField to be setEnabled(false) , i.e. greyed out, when the
>>> Checkbox is false.  This I can accomplish using a DialogListener
>>> when the user clicks on the Checkbox.  But I want the default
>>> setting to be that the Checkbox is false and the TextField is
>>> correspondingly greyed out - i.e. before user input changes the
>>> state of any of the Components, triggering the Listener.
>>>
>>> I've tried getting the Vector of numeric fields, then getting the
>>> correct element using both get() and elementAt(), and setEnabled
>>> (false), directly before shwoDialog() but it doesn't seem to work.
>>>
>>> ...
>>> gd.addCheckbox("Do it", false)
>>> gd.addNumericField("How many times?", 1, 0); //to be greyed out
>>> initially
>>> ...
>>> Vector<?>  numbers = gd.getNumericFields();
>>> TextField num = (TextField) numbers.get(3) // or .elementAt(3);
>>> num.setEnabled(false);
>>> showDialog();
>>>
>>> Any ideas?  I'm on Ubuntu 10.04, JRE 1.6 19, IJ 1.43s
>>>
>>> Michael
>>>
>>
Reply | Threaded
Open this post in threaded view
|

Re: setEnabled(false) in new GenericDialog

Michael Schmid
Hi Curtis,

here is my experience with the OS X bug:

It is enough to do some operation that forces a refresh of the screen  
some 100 ms after the last refresh. This can be either in the same  
thread or a different thread.

The operation enforcing refresh can be the last setEnabled, setText,  
etc. operation, but it only does a job if there is really a change.
It can also be an operation that is only for this purpose, e.g.,  
adding or removing a blank character at the end of a Label is enough.  
In some of my code I do it like this - it is easier if there are  
several setEnabled etc operations and one does not know which one is  
the last one that actually leads to a change.

Your method of changing the focus has the advantage that it is more  
universal, it does not rely on the presence of a Label, but I agree  
that it is rather long code for a simple and very stupid bug.

I wonder whether there is some trick with the BufferStrategy to get  
rid of the bug? Has someone tried this?

Michael
________________________________________________________________

On 14 Apr 2010, at 21:33, Curtis Rueden wrote:

> Hi Michael & Michael,
>
> We ran into these same issues when coding the Bio-Formats Importer  
> plugin.
> You can see our approach at:
>
> https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/ 
> components/loci-plugins/src/loci/plugins/importer/
> ImporterDialog.java?rev=6039#L403
>
> The method (verifyOptions) is essentially a big bag of logic for  
> controlling
> which options get grayed out in which situations. To address the  
> Mac OS X
> glitch, we have a horrible hack at:
>
> https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/ 
> components/loci-plugins/src/loci/plugins/importer/
> ImporterDialog.java?rev=6039#L616
>
> The hack cycles the keyboard focus across all the components and  
> sleeps a
> bit (100ms), which seems to force the UI to update on most (all?)  
> Mac OS X
> systems.
>
> For what it's worth, we are exploring ways to simplify some of this
> complexity for ImageJ2.
>
> HTH,
> Curtis
>
> On Wed, Apr 14, 2010 at 10:19 AM, Michael Doube  
> <[hidden email]>wrote:
>
>> Hi Michael,
>>
>> Thank you for your response.
>>
>>
>>  Input into the text field should be disabled, however.
>>>
>>
>> Unfortunately, it is not disabled until after any one of the  
>> dialog fields
>> is actively changed by the user (including the TextField in  
>> question).  So
>> if my code is good, then this seems to me to be a bug - unable to set
>> initial state of dialog fields to setEnabled(false).
>>
>>  (2) SetEnabled in DialogItemChanged of a DialogListener will often
>>> fail on a Macintosh ...
>>>
>>
>>  On the Mac, the easiest work around would be a delay of 100 millisec
>>> before a setEnabled call in a DialogListener.
>>>
>>
>> So if an event triggers a DialogListener to make several changes to a
>> dialog, we should wait 100 ms between applying each change?
>>
>>
>> Michael
>>
>>  ________________________________________________________________
>>>
>>> On 14 Apr 2010, at 02:43, Doube, Michael wrote:
>>>
>>>  Hi All,
>>>>
>>>> I have a TextField and a Checkbox in a GenericDialog.  I want the
>>>> TextField to be setEnabled(false) , i.e. greyed out, when the
>>>> Checkbox is false.  This I can accomplish using a DialogListener
>>>> when the user clicks on the Checkbox.  But I want the default
>>>> setting to be that the Checkbox is false and the TextField is
>>>> correspondingly greyed out - i.e. before user input changes the
>>>> state of any of the Components, triggering the Listener.
>>>>
>>>> I've tried getting the Vector of numeric fields, then getting the
>>>> correct element using both get() and elementAt(), and setEnabled
>>>> (false), directly before shwoDialog() but it doesn't seem to work.
>>>>
>>>> ...
>>>> gd.addCheckbox("Do it", false)
>>>> gd.addNumericField("How many times?", 1, 0); //to be greyed out
>>>> initially
>>>> ...
>>>> Vector<?>  numbers = gd.getNumericFields();
>>>> TextField num = (TextField) numbers.get(3) // or .elementAt(3);
>>>> num.setEnabled(false);
>>>> showDialog();
>>>>
>>>> Any ideas?  I'm on Ubuntu 10.04, JRE 1.6 19, IJ 1.43s
>>>>
>>>> Michael
>>>>
>>>
Reply | Threaded
Open this post in threaded view
|

Re: setEnabled(false) in new GenericDialog

Michael Schmid
In reply to this post by Michael Doube
Hi Michael,

the following code produces a disabled input field on Mac OS X. If  
the input field is enabled on your system, it is a bug in your java  
version or Ubuntu.

import java.awt.*;
import java.util.Vector;
import ij.*;
import ij.gui.*;
import ij.plugin.PlugIn;

public class TestEnabled implements PlugIn {
     public void run(String arg) {
         GenericDialog gd = new GenericDialog("test");
         gd.addNumericField("How many times?", 1, 0);
         Vector numbers = gd.getNumericFields();
         TextField num = (TextField) numbers.get(0);
         num.setEnabled(false);
         gd.showDialog();
     }
}


Michael
________________________________________________________________

On 14 Apr 2010, at 02:43, Doube, Michael wrote:

> Hi All,
>
> I have a TextField and a Checkbox in a GenericDialog.  I want the  
> TextField to be setEnabled(false) , i.e. greyed out, when the  
> Checkbox is false.  This I can accomplish using a DialogListener  
> when the user clicks on the Checkbox.  But I want the default  
> setting to be that the Checkbox is false and the TextField is  
> correspondingly greyed out - i.e. before user input changes the  
> state of any of the Components, triggering the Listener.
>
> I've tried getting the Vector of numeric fields, then getting the  
> correct element using both get() and elementAt(), and setEnabled
> (false), directly before shwoDialog() but it doesn't seem to work.
>
> ...
> gd.addCheckbox("Do it", false)
> gd.addNumericField("How many times?", 1, 0); //to be greyed out  
> initially
> ...
> Vector<?> numbers = gd.getNumericFields();
> TextField num = (TextField) numbers.get(3) // or .elementAt(3);
> num.setEnabled(false);
> showDialog();
>
> Any ideas?  I'm on Ubuntu 10.04, JRE 1.6 19, IJ 1.43s
>
> Michael
Reply | Threaded
Open this post in threaded view
|

Re: setEnabled(false) in new GenericDialog

Michael Doube
Michael,

Thank you for the example.  The result here is that the TextField will
not accept any input, but is not greyed-out.  So it is only the
greying-out that is buggy.  I will leave my code as is, and test with
some other OS/JRE combinations.

Michael

> the following code produces a disabled input field on Mac OS X. If
> the input field is enabled on your system, it is a bug in your java
> version or Ubuntu.