GListener interface

De GENIUS
Révision datée du 10 juillet 2017 à 07:54 par Admin (discussion | contributions)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigation Aller à la recherche

before() and after() methods

To manage actions on widgets, a single interface is available: GListener. Then, automatically, you must implement these both methods :

  • before()
  • after()

Indeed, the GListener interface allows to manage notion as after (something like a call-back) but also before, in a more friendly way than what is proposed by swing with an automatic download/upload management of the pile as described in the diagram just below.

GListener.jpg

We will go inside the after() method after any action with the left button of the mouse or the "Enter" key of the keyboard.

The before() action may be a bit more difficult to understand. Of course, there is now //before()// action for a button widget (even if the GListener interface implies to get it). It is more clear for a GEntryInt widget as described with the example below: we will enter in the before() method just before the value of the widget will be modified (as after() will be activated after the value will be changed).

  public void before(GEvent e) throws GException {
    System.out.println("Old value was "+real.getValue());
  }
  public void before(GEvent e) throws GException {
    System.out.println("New value is "+real.getValue());
  }

Imagine that we initialized the real value to "1.0", then enter "2.0" at the keyboard. After pushing on the "Enter" key, we will obtain on the console ...

Old value was 1.0
New value is 2.0

How to know which widget has been selected ?

Moreover, we see on the previous example that, these both methods will have as an input argument a GEvent objet that will correspond to the event occured. Thus, this objet will contain all the information linked to this event.

In order to implement correctly the before()/after() methods, we must also know how to discriminate which widget has been activated. Indeed, in case of a GPanel , containing several widgets, it is necessary to know it, as the action to do will surely depend on the selected widget. So, to do it, GENIUS gives us the contains() method associated to the GEvent object given by the before()/after() methods. This method needs as input arguments one or several widgets and will return true if one of these widgets have been activated (else false).

  private GButton but1;
  private GButton but2;

  
  ...
  
  public void after(GEvent e) {
    if ( e.contains(but1) ) { // Case of we push on the but1 button ...
      ...
    }
    if ( e.contains(but1, but2) ) { // Case of we push on the but1 button or the but2 button ...
      ...
    }
  }

But sometimes, we just want to recover the activated object itself without testing all the possibilities ! It can simply done using the getLocalSource() method : it will return the selected widget known "locally", meaning existing at the current GPanel level.

But, imagine that we are inside a [1]] level P0, that includes two other GPanel P1 and P2 with P1 including two buttons, B1 and B2 ...

P0 => P1 => B1
         => B2
   => P2

If we push on the B2 button, it is possible to get the object corresponding to B2 by using the getFinalSource() method that will return it.

So, getLocalSource() will return P1 as getFinalSource() will return B2.

With such a mechanism, it will possible, for example, to discriminate if the action on a GEntryReal widget was coming from the input area or just from the unit menu (as, in that case, the value has not been changed).

  public void after(GEvent e) {
    if ( e.getFinalSource() instanceof GNumberFieldAbstract ) {
      System.out.println("Value changed ...");
    }
    else {
      System.out.println("Only unit change ...");    }
  }

Example

In the following example, we will show:

  1. how to discriminate which widget has been activated (using the contains() method)
  2. how to use the before() and after() methods to manage the interdiction to enter negative values for an integer
public class myPanel extends GPanel implements GListener {

  private GButton but1;
  private GButton but2;
  private GEntryInt valI;

  private int oldInt; // Integer to keep in memory the old value

  public myPanel() {
    but1 = new GButton("Bouton 1");
    but2 = new GButton("Bouton 2");
    valI = new GEntryInt("Integer input:", 0);
  }
  
  public void generic() throws GException {
    put(but1);
    put(but2);
    put(valI);
  }

  public void display() throws GException {
    generic();
  }

  public void before(GEvent e) {
    if ( e.contains(valI) ) {
      // We store the value before to be modified ...
      oldInt = valI.getValue();
    }
  }

  public void after(GEvent e) {
  
    if ( e.contains(but1) ) { System.out.println("Click occured on button 1"); }
    
    if ( e.contains(valI)  )  {
      // Test to keep only positive values
      if ( valI.getValue() < 0 ) {
        System.out.println("Warning, this value may not be negative ...");
	// We recover the old value
	valI.setValue(oldInt);
      }
    }

  }


Return to the introduction ↑ Go to the next page →