Ich versuche, eine einfachere Version von EventHandler<ActionEvent>
in Java 8 mit JavaFX bereitzustellen.Simplify Ereignis mit einer Lambda-Methode funktioniert nicht in Java
Die endgültige Version aussehen
package dialogutil;
import org.controlsfx.dialog.Dialog;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
@FunctionalInterface
public interface Clickable extends EventHandler<ActionEvent> {
public static Clickable EMPTY =() -> {};
public void onClick();
@Override
public default void handle(ActionEvent event) {
this.onClick();
if (event != null && event.getSource() != null) {
((Dialog)event.getSource()).hide();
}
}
}
Damit soll, ich versuche, Event-Handler auf einfachere Art und Weise zu schaffen: sie das Ereignis als Parameter nicht nehmen, und sie kümmern sich um Versteck sich.
Aus Gründen der Demonstration, ich eine Testsuite erstellt das Problem, das ich mit, dass haben zu reproduzieren:
package test;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import org.junit.Test;
public class BastelTest {
/**
* Interface Complicated is called with a value.
*/
@FunctionalInterface
interface Complicated {
void complicated(int value);
}
/**
* Interface Simple is called without a value.
*/
@FunctionalInterface
interface Simple extends Complicated {
void simple();
/**
* The value given is printed and then the call is deflected to the simple method given.
*/
@Override
default void complicated(int value) {
System.out.println("Swallowing the " + value);
simple();
}
}
/**
* This is in order to try the Complicated/Simple interface.
* The given {@link Complicated} is called with a 42.
* It can be a {@link Simple} as well; in this case the call is deflected.
* @param x
*/
private void callIt(Complicated x) {
x.complicated(42);
}
/**
* This is the interface I am indeed working on.
* Here the deflection doesn't work; instead, I get an AbstractMethodError.
*/
@FunctionalInterface
public interface Clickable extends EventHandler<ActionEvent> {
public static Clickable EMPTY =() -> {};
public void onClick();
@Override
public default void handle(ActionEvent event) {
System.out.println("Simplifying the call:");
this.onClick();
System.out.println("Call simplified.");
}
}
private void handle(EventHandler<ActionEvent> x) {
System.out.println("Handling null event via " + x);
x.handle(null);
System.out.println("Handling nonnull event via " + x);
x.handle(new ActionEvent());
}
@Test
public void testFunc() {
callIt(x -> System.out.println("Complicated with " + x));
callIt((Simple)() -> System.out.println("Called simple."));
Clickable c =() -> System.out.println("Hdl3");
c.handle(null);
handle(x -> System.out.println("Hdl1 " + x));
handle((Clickable)() -> System.out.println("Hdl2"));
handle(Clickable.EMPTY);
}
}
Hier folgendes passieren Ich erwarte, dass:
- Wenn ich
callIt()
anrufen oderhandle()
mit der Basisversion des Handlers, wird es wie üblich aufgerufen. - Wenn ich sie mit der "spezialisierten", vereinfachten Version der Handler-Klasse anrufe, erwarte ich, dass sie diesen Aufruf auf die vereinfachte Version umlenkt, die ich gebe.
Dies funktioniert nur teilweise:
- mit der Kombination
Simple
/Complicated
, es funktioniert: das gegebene Argument dercomplicated(int)
Verfahren zur Herstellung einesSimple
druckt ruft und ruft dann diesimple()
Methode, die wiederum ausgedrückt als ein Lambda. - Die Kombination ich nach bin, ist jedoch eine
EventHandler<ActionEvent>
als Lambda-exprimierenden (möglicherweise sogar leer), die dieseonClick()
einClickable
derenhandle()
Anrufe bildet. (Bitte seien Sie nicht verwirrt über die Namen; es ist eine ziemlich historische Schnittstelle, die ich nur verbessern werde, aber nicht vollständig ändern.) In diesem Fall funktioniert es nicht.
Hier wird der Stack-Trace ich:
java.lang.AbstractMethodError: Method test/BastelTest$$Lambda$7.handle(Ljavafx/event/Event;)V is abstract
at test.BastelTest$$Lambda$7/25282035.handle(Unknown Source)
at test.BastelTest.handle(BastelTest.java:38)
at test.BastelTest.testFunc(BastelTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at [usual test case stuff...]
Warum es nicht funktioniert?
(Wenn ich nicht klar genug über die Lage bin, mir bitte sagen.)
Ich kann Ihren Fehler mit JDK 1.8.0_74 nicht reproduzieren. Welche Version hast du? Auch das ist nicht verwandt, aber 'Interface Simple extends Complicated' sieht wirklich komisch aus (wenn etwas einfach ist, dann ist es kompliziert?) – Tunaki
Unrelated. 'public static Clickable.EMPTY' - Variablen in' interface's sind nicht erlaubt, 'EMPTY' ist implizit' public static final'. 'public void onClick()' hier 'public' ist überflüssig. –
Ich habe 1.8.0_20. Gute Idee - Ich sollte aktualisieren, um zu sehen, ob es dann funktioniert ... – glglgl