« Update data » : différence entre les versions
(Page créée avec « TBW ... Return to the introduction ↑ Go to the next page → ») |
Aucun résumé des modifications |
||
Ligne 1 : | Ligne 1 : | ||
Sometimes, it is needed to update the content of a widget depending on the modification done on another one. If both of them are included in a higher level widget, it can be done relatively easily. But in case of these widgets are displayed in different panels (for example inside a GTabbedPane), it may be difficult to manage it. | |||
A first solution could be to use static objects but it is strongly not recommanded. | |||
Another solution is avalaible since the 1.5 version (for the 1.3 and 1.4 version, we could use same objects but only available via GENIUS_ADDONS library or given as a separated package {{:utilities:gobserver.zip|there}}). We will describe hereafter. | |||
Imagine that : | |||
- we have two widgets, <font color=#FF8C00>WidData1</font> and <font color=#FF8C00>WidData2</font>, including some specific data information | |||
- we have a widget, <font color=#FF8C00>WidScenario</font> that defines a scenario thanks to some data included in previous widgets. | |||
=== GObservable interface === | |||
First, <font color=#FF8C00>WidData1</font> and <font color=#FF8C00>WidData2</font> will have to implement the <font color=#4169E1>GObservable</font> interface because these widgets will be the ones that will be first updated and thus have to be observed (they are "observable" !) to know if something has to be done. | |||
Due to the <font color=#4169E1>GObservable</font> interface, the abstract <font color=#4169E1>registerObserver</font>, <font color=#4169E1>unregisterObserver</font> and <font color=#4169E1>notifyObservers</font> methods will have to be implemented inside the <font color=#FF8C00>WidData1</font> and <font color=#FF8C00>WidData2</font> class: | |||
<syntaxhighlight lang="java"> | |||
GObserverList obsList; | |||
... | |||
@Override | |||
public void registerObserver(GObserver observer) { | |||
obsList.registerObserver(observer); | |||
} | |||
@Override | |||
public void unregisterObserver(GObserver observer) { | |||
obsList.unregisterObserver(observer) | |||
} | |||
@Override | |||
public void notifyObservers(Object... args) { | |||
obsList.notifyObservers(this, args); | |||
} | |||
</syntaxhighlight> | |||
<font color=#FF8C00>obsList</font> is a <font color=#4169E1>GObserverList</font> object only used to store a list of "observers" widgets and proposing: | |||
* a <font color=#4169E1>registerObserver</font> method to store objects that will observe our widget | |||
* an <font color=#4169E1>unregisterObserver</font> method | |||
* a <font color=#4169E1>notifyObservers</font> method doing a loop on all "observers" components in order to call for their <font color=#4169E1>notify</font> method. | |||
''Note that we have to use this kind of object because in <font color=#FF8C00>'''Java'''</font> (below 1.8 version), a method in an interface must be abstract. So, we use it to avoid not to repeat same code.'' | |||
Moreover, we have to call for the <font color=#4169E1>notifyObservers</font> method of this object as needed. In the example just below, we will place it in the <font color=#4169E1>after</font> and <font color=#4169E1>read</font> methods: | |||
<syntaxhighlight lang="java"> | |||
@Override | |||
public void after(GEvent arg0) throws GException { | |||
// We may refine the test case by searching the specific subwidgets | |||
// which have been changed by using: | |||
// arg0.getLocalSource() or arg0.getFinalSource() | |||
notifyObservers(); | |||
} | |||
@Override | |||
public void read(GEvent arg0) throws GException { | |||
generic(); | |||
notifyObservers(); | |||
} | |||
</syntaxhighlight> | |||
=== GObserver interface === | |||
Secondly, <font color=#FF8C00>WidScenario</font> will have to implement the <font color=#4169E1>GObserver</font> interface as it will observe information coming from other widget(s) and, due to this information, an update will occur (or not). | |||
Thanks to the <font color=#4169E1>GObserver</font> interface, <font color=#FF8C00>WidScenario</font> should implement an <font color=#4169E1>notify</font> method as is: | |||
<syntaxhighlight lang="java"> | |||
@Override | |||
public void notify(Object observable, Object... args) { | |||
// "args" objects list will not be used in this example | |||
if ( observable instanceof WidData1 ) { | |||
// Update of the scenario thanks to WidData1 widget modification | |||
… | |||
} else if ( observable instanceof WidData2 ) { | |||
// Update of the scenario thanks to WidData1 widget modification | |||
… | |||
} | |||
} | |||
</syntaxhighlight> | |||
We see that the way to manage which object sent information is done by using <font color=#FF8C00>instanceof</font> syntax. | |||
=== Links between updated and updatable objects === | |||
At last, in the main code we will have just to write something like this: | |||
<syntaxhighlight lang="java"> | |||
// Updated objects | |||
widData1 = new WidData1(...); | |||
widData2 = new WidData2(...); | |||
// Updatable object | |||
widScenario = new WidScenario(...); | |||
// widScenario will be potentially updated if widData1 is changed | |||
widData1.registerObserver(widScenario); | |||
// widScenario will be potentially updated if widData2 is changed | |||
widData2.registerObserver(widScenario); | |||
</syntaxhighlight> | |||
[[WELCOME_TO_THE_GENIUS_WIKI|Return to the introduction ↑]] | [[WELCOME_TO_THE_GENIUS_WIKI|Return to the introduction ↑]] | ||
[[GTabbedPane|Go to the next page →]] | [[GTabbedPane|Go to the next page →]] |
Version du 5 mai 2017 à 12:57
Sometimes, it is needed to update the content of a widget depending on the modification done on another one. If both of them are included in a higher level widget, it can be done relatively easily. But in case of these widgets are displayed in different panels (for example inside a GTabbedPane), it may be difficult to manage it.
A first solution could be to use static objects but it is strongly not recommanded.
Another solution is avalaible since the 1.5 version (for the 1.3 and 1.4 version, we could use same objects but only available via GENIUS_ADDONS library or given as a separated package Utilities:gobserver.zip). We will describe hereafter.
Imagine that :
- we have two widgets, WidData1 and WidData2, including some specific data information - we have a widget, WidScenario that defines a scenario thanks to some data included in previous widgets.
GObservable interface
First, WidData1 and WidData2 will have to implement the GObservable interface because these widgets will be the ones that will be first updated and thus have to be observed (they are "observable" !) to know if something has to be done.
Due to the GObservable interface, the abstract registerObserver, unregisterObserver and notifyObservers methods will have to be implemented inside the WidData1 and WidData2 class:
GObserverList obsList;
...
@Override
public void registerObserver(GObserver observer) {
obsList.registerObserver(observer);
}
@Override
public void unregisterObserver(GObserver observer) {
obsList.unregisterObserver(observer)
}
@Override
public void notifyObservers(Object... args) {
obsList.notifyObservers(this, args);
}
obsList is a GObserverList object only used to store a list of "observers" widgets and proposing:
- a registerObserver method to store objects that will observe our widget
- an unregisterObserver method
- a notifyObservers method doing a loop on all "observers" components in order to call for their notify method.
Note that we have to use this kind of object because in Java (below 1.8 version), a method in an interface must be abstract. So, we use it to avoid not to repeat same code.
Moreover, we have to call for the notifyObservers method of this object as needed. In the example just below, we will place it in the after and read methods:
@Override
public void after(GEvent arg0) throws GException {
// We may refine the test case by searching the specific subwidgets
// which have been changed by using:
// arg0.getLocalSource() or arg0.getFinalSource()
notifyObservers();
}
@Override
public void read(GEvent arg0) throws GException {
generic();
notifyObservers();
}
GObserver interface
Secondly, WidScenario will have to implement the GObserver interface as it will observe information coming from other widget(s) and, due to this information, an update will occur (or not).
Thanks to the GObserver interface, WidScenario should implement an notify method as is:
@Override
public void notify(Object observable, Object... args) {
// "args" objects list will not be used in this example
if ( observable instanceof WidData1 ) {
// Update of the scenario thanks to WidData1 widget modification
…
} else if ( observable instanceof WidData2 ) {
// Update of the scenario thanks to WidData1 widget modification
…
}
}
We see that the way to manage which object sent information is done by using instanceof syntax.
Links between updated and updatable objects
At last, in the main code we will have just to write something like this:
// Updated objects
widData1 = new WidData1(...);
widData2 = new WidData2(...);
// Updatable object
widScenario = new WidScenario(...);
// widScenario will be potentially updated if widData1 is changed
widData1.registerObserver(widScenario);
// widScenario will be potentially updated if widData2 is changed
widData2.registerObserver(widScenario);