Changing location of a generic dialog

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

Changing location of a generic dialog

Jon Harman-3
Hi,
My plugin uses a generic dialog, but it pops up in an inconvenient
place.  Is there any way I can change the location?  Maybe somehow place
it the second time in the same place the user moved it?

Jon
Reply | Threaded
Open this post in threaded view
|

Re: Changing location of a generic dialog

ctrueden
Hi Jon,

My plugin uses a generic dialog, but it pops up in an inconvenient place.
>  Is there any way I can change the location?  Maybe somehow place it the
> second time in the same place the user moved it?
>

From what I can tell, GenericDialog.showDialog() calls GUI.center(this) and
then blocks, which doesn't leave much wiggle room for moving the dialog
around. Maybe Wayne will have a slicker solution, but one thing you can do
is react to a windowOpened event to immediately move the dialog as soon as
it pops up. The downside is that the dialog will momentarily flash in the
wrong place. See the plugin below for an example.

HTH,
Curtis

-----
// Place_Dialog.java

import ij.IJ;
import ij.gui.GenericDialog;
import ij.plugin.PlugIn;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class Place_Dialog implements PlugIn, WindowListener {
  private GenericDialog gd;

  public void run(String arg) {
    // construct generic dialog
    gd = new GenericDialog("Who Are You?");
    gd.addStringField("Name: ", "", 30);
    gd.addWindowListener(this);
    gd.showDialog();
    if (gd.wasCanceled()) return;

    // do something trivial with the input
    String name = gd.getNextString();
    if (name == null) name = "";
    name = name.trim();
    if (name.equals("")) IJ.showMessage("Hello!");
    else IJ.showMessage("Hello, " + name + "!");
  }

  public void windowActivated(WindowEvent e) { }
  public void windowClosed(WindowEvent e) { }
  public void windowClosing(WindowEvent e) { }
  public void windowDeactivated(WindowEvent e) { }
  public void windowDeiconified(WindowEvent e) { }
  public void windowIconified(WindowEvent e) { }
  public void windowOpened(WindowEvent e) {
    gd.setLocation(10, 10);
  }
}

On Tue, Jan 13, 2009 at 12:24 PM, Jon Harman <[hidden email]>wrote:

> Hi,
> My plugin uses a generic dialog, but it pops up in an inconvenient place.
>  Is there any way I can change the location?  Maybe somehow place it the
> second time in the same place the user moved it?
>
> Jon
>
Reply | Threaded
Open this post in threaded view
|

Re: Changing location of a generic dialog

Albert Cardona
In reply to this post by Jon Harman-3
Jon Harman wrote:
> Hi,
> My plugin uses a generic dialog, but it pops up in an inconvenient
> place.  Is there any way I can change the location?  Maybe somehow
> place it the second time in the same place the user moved it?


Make the class that launches the dialog store the dialog's X,Y position
in the screen. You can get such position by:

GenericDialog gd = ....
Point loc = gd.getLocation();


The ideal position to get such coordinates is in a ComponentListener:

gd.addComponent(new ComponentAdapter() {
    public void componentMoved(ComponentEvent ce) {
        Point loc = ce.getComponent().getLocation();
        // ... store loc somewhere
    }
});


Then, whenever the dialog is opened, set its position (only if any
position recorded):

GenericDialog gd = ....
if (null != loc) {
    gd.setLocation(loc.x, loc.y);
}

The risk above is that the location may be off screen (i.e. if the user
disconnected an extra monitor). You can check that too, using the
GraphicsConfiguration and GraphicsDevice methods.


If the instance of the class that launched the dialog is destroyed, you
can store the "loc" in a static field.

Albert

--
Albert Cardona
http://albert.rierol.net
Reply | Threaded
Open this post in threaded view
|

Re: Changing location of a generic dialog

Eitan Suez-2
since imagej is open source, why not just comment out the
offending call that centers the dialog when you display it?
so that code that does something like this:

  1. create dialog
  2. set its location
  3. display it

actually works?

/ eitan

On Tue, Jan 13, 2009 at 1:15 PM, Albert Cardona
<[hidden email]>wrote:

> Jon Harman wrote:
>
>> Hi,
>> My plugin uses a generic dialog, but it pops up in an inconvenient place.
>>  Is there any way I can change the location?  Maybe somehow place it the
>> second time in the same place the user moved it?
>>
>
>
> Make the class that launches the dialog store the dialog's X,Y position in
> the screen. You can get such position by:
>
> GenericDialog gd = ....
> Point loc = gd.getLocation();
>
>
> The ideal position to get such coordinates is in a ComponentListener:
>
> gd.addComponent(new ComponentAdapter() {
>   public void componentMoved(ComponentEvent ce) {
>       Point loc = ce.getComponent().getLocation();
>       // ... store loc somewhere
>   }
> });
>
>
> Then, whenever the dialog is opened, set its position (only if any position
> recorded):
>
> GenericDialog gd = ....
> if (null != loc) {
>   gd.setLocation(loc.x, loc.y);
> }
>
> The risk above is that the location may be off screen (i.e. if the user
> disconnected an extra monitor). You can check that too, using the
> GraphicsConfiguration and GraphicsDevice methods.
>
>
> If the instance of the class that launched the dialog is destroyed, you can
> store the "loc" in a static field.
>
> Albert
>
> --
> Albert Cardona
> http://albert.rierol.net
>
Reply | Threaded
Open this post in threaded view
|

Re: Changing location of a generic dialog

Wayne Rasband
In reply to this post by ctrueden
On Jan 13, 2009, at 2:06 PM, Curtis Rueden wrote:

> Hi Jon,
>
> My plugin uses a generic dialog, but it pops up in an inconvenient
> place.
>>  Is there any way I can change the location?  Maybe somehow place it
>> the
>> second time in the same place the user moved it?
>>
>
> From what I can tell, GenericDialog.showDialog() calls
> GUI.center(this) and
> then blocks, which doesn't leave much wiggle room for moving the dialog
> around. Maybe Wayne will have a slicker solution, but one thing you
> can do
> is react to a windowOpened event to immediately move the dialog as
> soon as
> it pops up. The downside is that the dialog will momentarily flash in
> the
> wrong place. See the plugin below for an example.
>
> HTH,
> Curtis

The 1.42h daily build adds a centerDialog(boolean) method to
GenericDialog that can be used to prevent the GUI.center() call, and
thus prevent the flashing that occurs when the dialog is moved. You
should also test to see which version of ImageJ your plugin is running
on to avoid NoSuchMethodError exceptions, for example:

     if (IJ.getVersion().compareTo("1.42h")>=0)
         gd.centerDialog(false);

-wayne

-----
// Place_Dialog.java

import ij.IJ;
import ij.gui.GenericDialog;
import ij.plugin.PlugIn;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class Place_Dialog implements PlugIn, WindowListener {
   private GenericDialog gd;

   public void run(String arg) {
     // construct generic dialog
     gd = new GenericDialog("Who Are You?");
     gd.addStringField("Name: ", "", 30);
     gd.addWindowListener(this);
     if (IJ.getVersion().compareTo("1.42h")>=0)
         gd.centerDialog(false);
     gd.showDialog();
     if (gd.wasCanceled()) return;

     // do something trivial with the input
     String name = gd.getNextString();
     if (name == null) name = "";
     name = name.trim();
     if (name.equals("")) IJ.showMessage("Hello!");
     else IJ.showMessage("Hello, " + name + "!");
   }

   public void windowActivated(WindowEvent e) { }
   public void windowClosed(WindowEvent e) { }
   public void windowClosing(WindowEvent e) { }
   public void windowDeactivated(WindowEvent e) { }
   public void windowDeiconified(WindowEvent e) { }
   public void windowIconified(WindowEvent e) { }
   public void windowOpened(WindowEvent e) {
     gd.setLocation(10, 10);
   }
}
Reply | Threaded
Open this post in threaded view
|

Re: Changing location of a generic dialog

ctrueden
In reply to this post by Eitan Suez-2
Hi Eitan,


> since imagej is open source, why not just comment out the
> offending call that centers the dialog when you display it?
>

We're straying off topic, but it boils down to avoiding a project fork. The
goal is to write code that works with the official distribution, so users
can freely upgrade with no maintenance from the plugin developer.
Simultaneously, ImageJ strives to maintain compatibility with older versions
as much as is practical -- hence Wayne's addition of a boolean toggle rather
than changing the default behavior.

-Curtis

On Tue, Jan 13, 2009 at 1:45 PM, Eitan Suez <[hidden email]> wrote:

> since imagej is open source, why not just comment out the
> offending call that centers the dialog when you display it?
> so that code that does something like this:
>
>  1. create dialog
>  2. set its location
>  3. display it
>
> actually works?
>
> / eitan
>
> On Tue, Jan 13, 2009 at 1:15 PM, Albert Cardona
> <[hidden email]>wrote:
>
> > Jon Harman wrote:
> >
> >> Hi,
> >> My plugin uses a generic dialog, but it pops up in an inconvenient
> place.
> >>  Is there any way I can change the location?  Maybe somehow place it the
> >> second time in the same place the user moved it?
> >>
> >
> >
> > Make the class that launches the dialog store the dialog's X,Y position
> in
> > the screen. You can get such position by:
> >
> > GenericDialog gd = ....
> > Point loc = gd.getLocation();
> >
> >
> > The ideal position to get such coordinates is in a ComponentListener:
> >
> > gd.addComponent(new ComponentAdapter() {
> >   public void componentMoved(ComponentEvent ce) {
> >       Point loc = ce.getComponent().getLocation();
> >       // ... store loc somewhere
> >   }
> > });
> >
> >
> > Then, whenever the dialog is opened, set its position (only if any
> position
> > recorded):
> >
> > GenericDialog gd = ....
> > if (null != loc) {
> >   gd.setLocation(loc.x, loc.y);
> > }
> >
> > The risk above is that the location may be off screen (i.e. if the user
> > disconnected an extra monitor). You can check that too, using the
> > GraphicsConfiguration and GraphicsDevice methods.
> >
> >
> > If the instance of the class that launched the dialog is destroyed, you
> can
> > store the "loc" in a static field.
> >
> > Albert
> >
> > --
> > Albert Cardona
> > http://albert.rierol.net
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Changing location of a generic dialog

Jon Harman-3
In reply to this post by Jon Harman-3
Hi,

Thanks for all the help.

I decided to use Curtis' idea.  My plugin puts up a dialog again and
again.  I want to place the dialog in the same place that the user moved
it before closing it.

Jon

This is what I did:  (there must be a more elegant way to initialize the
point)

        private static Point gdloc = new Point(-1234,0);

        private class PlaceGD implements WindowListener {
                  private GenericDialog gd;
                  private Point p;

                  public void init(GenericDialog gd0, Point p0) {
                          gd = gd0;
                          p = p0;
                    gd.addWindowListener(this);
                  }
                  public void windowActivated(WindowEvent e) { }
                  public void windowClosed(WindowEvent e) { }
                  public void windowClosing(WindowEvent e) { }
                  public void windowDeactivated(WindowEvent e) { }
                  public void windowDeiconified(WindowEvent e) { }
                  public void windowIconified(WindowEvent e) { }
                  public void windowOpened(WindowEvent e) {
                    gd.setLocation(p);
                  }
                }

...


GenericDialog gd = new GenericDialog("XXXX");
... setup gd
if(gdloc.x != -1234) pgd.init(gd,gdloc);
gd.showDialog();
if (gd.wasCanceled()) return false;
gdloc = gd.getLocation();
...


Curtis Rueden wrote:

> Hi Wayne & Jon,
>
> Yep, the simple way will work for ImageJ 1.42h, but the dialog will
> remain centered for earlier versions. The most comprehensive solution
> would be to call gd.centerDialog(false) and gd.setLocation(x, y) if the
> version is large enough, and use the ugly WindowListener hack otherwise.
> Not the most elegant, but will always place the dialog correctly, and
> avoid the window flash for 1.42h and above.
>
> -Curtis
>
> On Tue, Jan 13, 2009 at 2:09 PM, Wayne Rasband <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi John & Curtis,
>
>     Immediately after I posted my message to the list I realized that
>     the example could be greatly simplified.
>
>     -wayne
>
>     import ij.IJ;
>     import ij.gui.GenericDialog;
>     import ij.plugin.PlugIn;
>
>     public class Place_Dialog implements PlugIn {
>
>      public void run(String arg) {
>        // construct generic dialog
>        GenericDialog gd = new GenericDialog("Who Are You?");
>        gd.addStringField("Name: ", "", 30);
>        if (IJ.getVersion().compareTo("1.42h")>=0)
>            gd.centerDialog(false);
>        gd.setLocation(100, 100);
>        gd.showDialog();
>        if (gd.wasCanceled()) return;
>
>        // do something trivial with the input
>        String name = gd.getNextString();
>        if (name == null) name = "";
>        name = name.trim();
>        if (name.equals("")) IJ.showMessage("Hello!");
>        else IJ.showMessage("Hello, " + name + "!");
>      }
>
>     }
>      
>
>