Hur fungerar event hantering i Java?

Permalänk
Medlem

Hur fungerar event hantering i Java?

Jag har försökt läsa på om detta men är inte säker på att jag förstått. Här är min kod:

public void addListeners(){ ButtonListener listener = new ButtonListener(); btnStone.addActionListener(listener); btnScissor.addActionListener(listener); btnBag.addActionListener(listener); btnNew.addActionListener(listener); btnQuit.addActionListener(listener); } private class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent event){ if(event.getSource() == btnStone){ controller.newChoice(0); } else if(event.getSource() == btnScissor){ controller.newChoice(1); } else if(event.getSource() == btnBag){ controller.newChoice(2); } else if(event.getSource() == btnNew){ controller.newGame(); } else if(event.getSource() == btnQuit){ controller.finish(); } }

Jag kallar på addListener metoden i min konstruktor.

Så jag gör en ny klass som heter ButtonListener vilken ärver ActionListener. Den har en metod som tar ett actionEvent e som parameter. Sedan har jag min selektion, den vet jag hur fungerar. Min addListener metod gör ett nytt ButtonListener objekt och sedan kallar jag på mina knappars (JButtons då egentligen) funktion som heter addActionListener som tar parametern listener. Vad innebär det? Jag kallar ju heller aldrig på ButtonListener i addListener metoden, så förstår inte hur den kommer in i bilden.

Permalänk
Medlem

Hej!

ButtonListener listener = new ButtonListener();

skapar en instans av din klass ButtonListener. Eftersom den implementerar ActionListener vet man om att den har en metod actionPerformed. När du gör addListener på en knapp får den en referens till listener. Det betyder att dina knappar kan anropa actionPerformed hos det lyssnar objektet vilket kallar på din kod. Detta är vad som händer i bakgrunden när du trycker på knappar.

Permalänk
Medlem
Skrivet av smurfzg:

Hej!

ButtonListener listener = new ButtonListener();

skapar en instans av din klass ButtonListener. Eftersom den implementerar ActionListener vet man om att den har en metod actionPerformed. När du gör addListener på en knapp får den en referens till listener. Det betyder att dina knappar kan anropa actionPerformed hos det lyssnar objektet vilket kallar på din kod. Detta är vad som händer i bakgrunden när du trycker på knappar.

Aha, då förstår jag! Gar även sett en implementation där man inte gör en inre klass utan enbart actionPerformed metoden. Är någon av dessa sätt rekommenderade att göra eller spelar det ingen roll?

Permalänk
Medlem

@Baxtex:

Det finns ett annat sätt, att du inte namnger klassen utan låter den vara anonym. Detta är dock olämpligt i de fall då du kan använda en och samma listener till alla olika knappar (vilket du inte kan göra med en anonym klass). I ditt fall skulle jag nog använda anonyma listeners eftersom alla ska göra helt olika saker.

Följande kodsnutt instansierar och lägger till en anonym ActionListener med actionPerformed överskuggad.

btnStone.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // do stuff } });

Permalänk
Medlem

Kan inte säga att det ena är bättre än det andra, de påverkar egentligen bara hur din kod ser ut.

Från och med Java 8 finns det ett nytt sätt att skriva de anonyma klasserna på, nämligen lambda-uttryck:

bnStone.addActionListener(e -> System.out.println("Hej!"));

Alternativ

btnStone.addActionListener(e -> { System.out.println("Hej 1"); System.out.println("Hej 2"); });