[Java] ActionListeners vs Action

Pagina: 1
Acties:

  • Nephilim
  • Registratie: Augustus 2000
  • Laatst online: 15-05 00:38
Toen we begin dit jaar met swing begonnen, moesten wel aan elke knop een actie binden met setAction() .. een maand later moesten we dan overschakelen op ActionListeners.

Nu vraag ik me af wat de voor- en nadelen van beide manieren zijn, en wat de "goeie" manier van coden is.

Voorbeeldje van mijn huidige code staat op http://www.nephilimco.com/nephymail/files/NephyMail.java

Ik was net bezig alle
code:
1
2
3
4
5
6
7
forward.addActionListener(
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            forwardMessages();
        }
    }
);

te veranderen in
code:
1
forward.addActionListener(this);

en dan alle acties in een actionPerformed(..) te zetten, waar ik check via getSource()

Nu wacht ik dus even op goeie raad voor ik m'n code weer door elkaar gooi :P

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
javax.swing.Action is een 'observeerbare' aktie. GUI componeten zoals een JButton die op een Action werken, kunnen reageren op aanpassingen in de Action zoals bijvoorbeeld een verandering van label, disabling of wat dan ook.

javax.swing.Action is een uitbreiding van een java.awt.event.ActionListener. Alles wat werkt op een ActionListener kan daardoor ook werken op een Action, maar die componenten observeren de Action dan uiteraard niet.

Overigens vind ik (en velen met mij) het absoluut niet mooi om maar 1 listener te gebruiken voor vele GUI componenten en zeker niet 'this'. Je moet dan in de ActionListener met gevalsonderscheid de echte aktie gaan bepalen en dat is gewoon echt lelijk. Je kunt beter voor elke knop een eigen ActionListener, of nog beter: Action gebruiken.

Die herschrijving zou ik dus maar terugdraaien ;) . Hoe kom je daar trouwens bij dat dit beter zou zijn?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

zo werk ik altijd:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class OkAction extends AbstractAction{
    public OkAction(){
      super("Ok");
    }

    public void actionPerformed(ActionEvent ae){
      System.out.println("Ok"); 
    }
}

OkAction okAction = new OkAction();
Button okButton1 = new OkButton(okAction);
Button okButton2 = new OkButton(okAction);

Zoals je ziet gebruik ik een AbstractAction object omdat je deze ook heel eenvoudig kan disablen (zijn meteen alle buttons ook gedisabled).


Een ActionListener per button is nagenoeg hetzelfde als een AbstractAction alleen je kan die dus niet heel eenvoudig disabled. Ik zou hier niet meer mee werken.

en een addActionListener(this) met een getSource is echt not done! Dit deden ze nog onder Visual Cafe, en je krijgt echt een enorme bagger code.

  • Invalid
  • Registratie: September 2001
  • Niet online
Ik denk dat het een kwestie van smaak is. Ik gebruik zelf altijd de 'actionPerformed' methode omdat je zo alle event handling bij elkaar hebt.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op woensdag 26 juni 2002 14:40 schreef InvalidTarget het volgende:
Ik denk dat het een kwestie van smaak is. Ik gebruik zelf altijd de 'actionPerformed' methode omdat je zo alle event handling bij elkaar hebt.
Jij gebruikt een algemene actionListener? (ik neem aan dat je dit met een 'actionPerformed' methode (en kijk eens goed naar die AbstractAction)). Sorry hoor, maar dit is echt onzin en deze aanpak is totaal achterhaald. Vooral als je complexere gebruikers interfaces gaat maken dan is dit echt een waardeloze oplossingen omdat je een enorme zooi terug zoek code hebt (dat totaal niet nodig is).

  • Nephilim
  • Registratie: Augustus 2000
  • Laatst online: 15-05 00:38
Op woensdag 26 juni 2002 14:31 schreef mbravenboer het volgende:
Die herschrijving zou ik dus maar terugdraaien ;) . Hoe kom je daar trouwens bij dat dit beter zou zijn?
Allrighty, dan ga ik overal maar AbstractAction extenden. Hoe ik erbij kom? School he :)


Bedankt voor de uitleg all.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Nephilim: Hoe ik erbij kom? School he :)
Rare instellingen ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Nephilim
  • Registratie: Augustus 2000
  • Laatst online: 15-05 00:38
Op woensdag 26 juni 2002 15:52 schreef mbravenboer het volgende:
Rare instellingen ;) .
Don't blame me, I'm just a poor student :).

  • BitProcessor
  • Registratie: Februari 2001
  • Laatst online: 30-08 23:59
Nu volg ik toch effe niet. Ik ben akkoord met het feit dat je met anonieme luisterklasses geen getSource() moet doen en je een hoop if-else testen vermijd (of cases), maar dat levert, vind ik persoonlijk enorm onduidelijke en slordige code op.
Als je alles samen zet in 1 actionPerformed-methode worden al je events mooi opgevangen op een centrale plaats.

Just my 2 cents...

"I think there is a world market for maybe five computers" - Thomas Watson, chairman of IBM, 1943


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Het voordeel van deze aanpak is dat je heel eenvoudig een bepaalde functionaliteit aan een widget te plaatsen, en je totaal niet bezig te houden met die widget zelf. Ik heb vroeger ook op deze manier mijn actionListeners aangesloten, maar ik werk nu al heel lang op de 'Action' manier, en ik zou niet meer anders willen, vooral nu ik zo nu en dan best wel gecompliceerde gebruikers interfaces maak.

En het is trouwens ook een beetje een knullige manier om weer helemaal terug te zoeken naar je widget als je al lang weet welke widget je bedoelt.

  • TrendKiller
  • Registratie: Januari 2001
  • Laatst online: 02-07 13:03
Als je alles samen zet in 1 actionPerformed-methode worden al je events mooi opgevangen op een centrale plaats.
En dat heeft tot gevolg als je vele buttons hebt dat je per knop je klikt door veel if-elses moet lopen en dat neemt tijd in.
En heel OO is dat in mijn ogen ook niet .

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Bovedien is een Action eigenlijk een soort Model gebaseerd systeem: de Action beschrijft een aktie: label, tooltip, icoon enz. Het GUI component baseert zijn weergave op dit model en als het model aangepast wordt, verandert het GUI component mee. Dit is een erg handige manier van werken, waardoor je een nog grotere scheiding kunt bereiken tussen GUI code en het afhandelen van events.

Overigens verzamel ik zelf m'n Actions wel centraal: ik geef een "Controller" mee aan een GUI. De GUI haalt Actions uit deze Controller van identifiers. Omdat ik niet vanuit mijn GUI de actions bepaal, kan ik zo zelfs hele andere actions onder mijn GUI zetten, die ook nog voor een ander uiterlijk zorgen (dat zit immers in de Action).

Overigens ben ik ook tegen anonieme inner-classes als luisteraars: dat heb je al afgeleid uit de twee alinea's hierboven. Dit zorgt voor hele onduidelijk code en akties die niet gebruikt kunnen worden in andere GUIs. Vermijden dus :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Nephilim
  • Registratie: Augustus 2000
  • Laatst online: 15-05 00:38
Op woensdag 26 juni 2002 16:11 schreef mbravenboer het volgende: Een hele lap tekst waar ik niks van begrepen heb
Euh? Kan je dat van die controller eens uitleggen?

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Nephilim: Euh? Kan je dat van die controller eens uitleggen?
Een stukje code zegt maar dan 100 woorden ;)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import javax.swing.Action;

/**
 * A Controller is a collection of Actions.
 * Actions can be retrieved by an identifier.
 */
public interface Controller {

    /**
     * Returns the Action associated with this identifier.
     *
     * @param identifier identifier whose associated value is to be returned.
     * @returns the Action associated with this identifier.
     */
    public Action getAction(String identifier);
}

Dit is geen onderdeel van de Java API, dus ga niet tevergeeft zoeken ;) . Het is in feite gewoon een Map van identifiers naar Actions. Elke GUI krijgt een controller, die bepaalde afgesproken Actions moet bevatten. De GUI haalt de Actions uit de controller en gebruikt deze als basis voor de buttons en dergelijke.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Nephilim
  • Registratie: Augustus 2000
  • Laatst online: 15-05 00:38
Op woensdag 26 juni 2002 17:28 schreef mbravenboer het volgende:
code:
1
[..]

Dit is geen onderdeel van de Java API, dus ga niet tevergeeft zoeken ;) . Het is in feite gewoon een Map van identifiers naar Actions. Elke GUI krijgt een controller, die bepaalde afgesproken Actions moet bevatten. De GUI haalt de Actions uit de controller en gebruikt deze als basis voor de buttons en dergelijke.
Bedankt, ik zie wel wat ik er mee kan doen (weinig ;))
Pagina: 1