Custom JavaFX events - java

I have a custom event listener:
public interface IMyCustomListener {
public void onEvent1(int param0);
public void onEvent2(String param0);
}
now I would fire events with javafx events pattern (Event, EventTarget, EventHandler...), how can I do this?

You cannot. JavaFX uses javafx.event.Events or subtypes, so String or even primitive int can't be passed.
You could however create a custom subtype of Event and add the parameters to this class.
Similarly only classes implementing javafx.event.EventHandler can be registered as event handlers.
You could create a event handler class that delegates to your methods though:
public abstract class CustomEvent extends Event {
public static final EventType<CustomEvent> CUSTOM_EVENT_TYPE = new EventType(ANY);
public CustomEvent(EventType<? extends Event> eventType) {
super(eventType);
}
public abstract void invokeHandler(MyCustomEventHandler handler);
}
public class CustomEvent1 extends CustomEvent {
public static final EventType<CustomEvent> CUSTOM_EVENT_TYPE_1 = new EventType(CUSTOM_EVENT_TYPE, "CustomEvent1");
private final int param;
public CustomEvent1(int param) {
super(CUSTOM_EVENT_TYPE_1);
this.param = param;
}
#Override
public void invokeHandler(MyCustomEventHandler handler) {
handler.onEvent1(param);
}
}
public class CustomEvent2 extends CustomEvent {
public static final EventType<CustomEvent> CUSTOM_EVENT_TYPE_2 = new EventType(CUSTOM_EVENT_TYPE, "CustomEvent2");
private final String param;
public CustomEvent2(String param) {
super(CUSTOM_EVENT_TYPE_2);
this.param = param;
}
#Override
public void invokeHandler(MyCustomEventHandler handler) {
handler.onEvent2(param);
}
}
public abstract class MyCustomEventHandler implements EventHandler<CustomEvent> {
public abstract void onEvent1(int param0);
public abstract void onEvent2(String param0);
#Override
public void handle(CustomEvent event) {
event.invokeHandler(this);
}
}
Usage Example
Button btn = new Button("Say 'Hello World'");
btn.setOnAction((ActionEvent event) -> {
btn.fireEvent(new CustomEvent1(42));
btn.fireEvent(new CustomEvent2("Hello World"));
});
btn.addEventHandler(CustomEvent.CUSTOM_EVENT_TYPE, new MyCustomEventHandler() {
#Override
public void onEvent1(int param0) {
System.out.println("integer parameter: " + param0);
}
#Override
public void onEvent2(String param0) {
System.out.println("string parameter: "+param0);
}
});

Related

void with Generics in Java

I have a function that returns void
public interface IProductService {
void delete(String id);
}
Generic method
public interface IRequestHandler<C , R> {
R handler(C c);
Class<C> commandType();
}
Implementation of generic interface
#Singleton
public record DeleteProductCommandHandler(IProductService iProductService)
implements IRequestHandler<DeleteProductCommand, Void> {
#Override
public Void handler(DeleteProductCommand deleteProductCommand) {
return iProductService.delete(deleteProductCommand.id);
}
#Override
public Class<DeleteProductCommand> commandType() {
return DeleteProductCommand.class;
}
}
How can I use void in IRequestHandler<DeleteProductCommand, Void> so that I can map void from iProductService.delete(deleteProductCommand.id);
Option 1:
Just return null:
#Override
public Void handler(DeleteProductCommand deleteProductCommand) {
iProductService.delete(deleteProductCommand.id);
return null;
}
Option 2:
Update the IProductService::delete method to return something meaningful, e.g. a boolean value like Collection::remove does:
public interface IProductService {
boolean delete(String id);
}
#Singleton
public record DeleteProductCommandHandler(IProductService iProductService)
implements IRequestHandler<DeleteProductCommand, Boolean> {
#Override
public Boolean handler(DeleteProductCommand deleteProductCommand) {
return iProductService.delete(deleteProductCommand.id);
}
#Override
public Class<DeleteProductCommand> commandType() {
return DeleteProductCommand.class;
}
}

Making Generic Class Using Lambda Expression

I have the below Service class which implement retry mechanism :
#RequiredArgsConstructor(onConstructor_ = {#Autowired})
#Service
public class RetryService {
private final RetryTemplate vcRetry;
private final Order1dao order1;
private final Order2dao order2;
public void saveOrder1(OrderRecord1 record) {
vcRetry.execute(
context -> {
order1.save(record);
});
}
public OrderRecord2 UpdateOrder2(OrderRecord2 record) {
return vcRetry.execute(
context -> {
return order2.Update(record);
});
}
public void saveOrder2(OrderRecord2 record) {
vcRetry.execute(
context -> {
order2.save(record);
});
}
There can be many daoBean which may uses the same RetryService class so i need to write the separate function for the individual bean.
Main Class:
public class OrderProcessor {
private final RetryService retryService;
public void SaveOrder(Order1 x, Order2 y,....) {
retryService.saveOrder1(x);
retryService.saveOrder2(y);
retryService.Update(y);
}
}
How can I make my RetryService class generic ?
You can create a GenericDao and use it in RetryService as below,
class GenericDao<T>{
//dao operations
}
class RetryService<T1 , T2> {
private final RetryTemplate vcRetry;
private final GenericDao<T1> order1;
private final GenericDao<T2> order2;
public void saveOrder1(T1 record) {
vcRetry.execute(
context -> {
order1.save(record);
});
}
public T2 UpdateOrder2(T2 record) {
return vcRetry.execute(
context -> {
return order2.Update(record);
});
}
public void saveOrder2(T2 record) {
vcRetry.execute(
context -> {
order2.save(record);
});
}
}
I hope it helps!

Create Enum with list of the same object

I would like to create an enum containing one attribut, a list of objects extending the same interface or the same abstract class.
The objective is to have a loop on each list of my enum to call methods dynamically.
public interface Regles {
void verifier();
}
public class Regle01 implements Regles {
#Override
public void verifier() {
}
}
public class Regle02 implements Regles {
#Override
public void verifier() {
}
}
public enum ListRegles {
ENUM1(Arrays.asList(new Regle01(), new Regle02())),
ENUM2(Arrays.asList(new Regle01()))
private List<Regles> regles = new ArrayList<Regles>();
ListRegles(List<Regles> r) {
regles = r;
}
}
how can i do this please ?
enum:
public enum ListRegles {
ENUM1(new Regle01(),new Regle02()),
ENUM2(new Regle01());
private List<Regles> regles ;
ListRegles(Regles... regles) {
this.regles = new ArrayList<>(Arrays.asList(regles));
}
public void verify() {
for (Regles regle : regles) {
regle.verifier();
}
}
}
Will call verifier for Regle01 and Regle02
ListRegles.ENUM1.verify();

Java generics software engineering design

I have a class RabbitQueue which basically acts like a queue and implements my Pollable interface.
I also have a class SaveToDatabaseStrategy which implements my DataProcessingStrategy interface. This is designed following the strategy-pattern.
Now, my class InputHandler which implements my interface InputListener, contains an instance of the Pollable interface and one of the DataProcessingStrategy interface.
However, I don't want to set the Generic type (String) when I declare these two fields, since the Generic type depends on the implementation of this interface which is given later on.
How would you design this?
public interface Pollable<T> {
T poll();
}
public class RabbitQueue implements Pollable<String> {
// code..
}
public interface DataProcessingStrategy<T> {
void processData(T t);
}
public class SaveToDatabaseStrategy<T> implements DataProcessingStrategy<T> {
private Repository<T, ?> repo;
public SaveToDatabaseStrategy(Repository<T, ?> repo) {
this.repo = repo;
}
#Override
public void processData(T data) {
repo.create(data);
System.out.printf("Received data of type %s: %s\n", data.getClass().getSimpleName(), data);
}
}
public interface InputListener<T> {
void inputReceived();
void inputReceived(T t);
}
public class InputHandler implements InputListener<String> {
private Pollable<String> queue;
private DataProcessingStrategy<String> strategy;
public InputHandler(String host, String queueName) throws IOException, TimeoutException {
queue = new RabbitQueue(host, queueName, this);
}
public void setStrategy(DataProcessingStrategy strategy) {
this.strategy = strategy;
}
#Override
public void inputReceived() {
System.out.println("Input received!");
strategy.processData(queue.poll());
}
#Override
public void inputReceived(String s) {
System.out.println("Input received: " + s + "!");
System.out.println("> " + queue.poll());
}
}
You could add a type parameter to the InputHandler class.
public class InputHandler<T> implements InputListener<T> {
private Pollable<T> queue;
private DataProcessingStrategy<T> strategy;
public InputHandler(String host, String queueName) throws IOException, TimeoutException {
queue = new RabbitQueue(host, queueName, this);
}
public void setStrategy(DataProcessingStrategy strategy) {
this.strategy = strategy;
}
#Override
public void inputReceived() {
System.out.println("Input received!");
strategy.processData(queue.poll());
}
#Override
public void inputReceived(String s) {
System.out.println("Input received: " + s + "!");
System.out.println("> " + queue.poll().toString());
}
}
Then create a new object like
new InputHandler<String>(host, queueName)

Java - force implementation of a method for each child of an abstract class

I have an abstract class Action with children like SendMessageAction.
I would like to run these actions in a service but how could I force implementation of each child ?
For example I would like to implement an abstract method : void run(Action action)
and methods "run" for each possible Action with an error if some methods are missing.
Any idea ?
Something like below should help you to get started. Happy coding!
Action.java
public abstract class Action {
protected abstract void runAction();
}
MessageSenderAction.java
public class MessageSenderAction extends Action {
public void runAction() {
//send message
}
}
SomeOtherAction.java
public class SomeOtherAction extends Action {
public void runAction() {
//do something else
}
}
ActionHandler.java
public class ActionHandler {
private final static ActionHandler INSTANCE = new ActionHandler();
private ActionHandler() {}
public static ActionHandler getInstance() {
return INSTANCE;
}
private List<Action> allActions = new ArrayList<Action>();
public void addAction(Action action) {
allActions.add(action);
}
public void runAllActions() {
for(Action action: allActions) {
//just to handle exception if there is any. Not to hamper other actions in case of any failures
try {
action.runAction();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
ActionDemo.java
public class ActionDemo {
public static void main(String... args) {
ActionHandler actionHandler = ActionHandler.getInstance();
Action msgSenderAction = new MessageSenderAction();
Action someOtherAction = new SomeOtherAction();
actionHandler.addAction(msgSenderAction);
actionHandler.addAction(someOtherAction);
actionHandler.runAllActions();
}
}

Categories