I have used listeners with Android and never had any problems, however today when it tried to create a simple listener in Java I am getting NullPointerException, what is the cause of this and how can I fix it?
this includes 3 classes, ListenerMainStart.java, SendMessageClass.java, and ReceiveMessageClass.java
ListenerMainStart.java
public class ListenerMainStart {
public static void main(String[] args) {
new SendMessageClass();
}
}
SendMessageClass.java
public class SendMessageClass {
public OnStringRequestedListener onStringListener;
public Timer timer;
public SendMessageClass() {
timer = new Timer();
timer.schedule(new TimerAction(), 3000);
}
public void SetOnStringRequestedListener(OnStringRequestedListener listener) {
System.out.println("value of onStringListener " + onStringListener.toString());
onStringListener = listener;
}
public interface OnStringRequestedListener {
public void passString(String sendString);
}
public class TimerAction extends TimerTask {
#Override
public void run() {
if (onStringListener!=null){
// pass string to other class, ONSTRINGLISTENER IS ALWASY NULL
onStringListener.passString("string sent from SendMessageclass");
} else {
System.out.println("onStringListener is null");
}
}
}
}
ReceiveMessageClass.java
public class ReceiveMessageClass implements SendMessageClass.OnStringRequestedListener {
SendMessageClass senderClass;
public ReceiveMessageClass() {
// instantiate class
senderClass = new SendMessageClass();
// set the listener to the class
senderClass.SetOnStringRequestedListener(this);
}
#Override
public void passString(String sendString) {
// do action when string is sent from other class
System.out.println("message recevied from other class is " + sendString);
}
}
It looks like you need to call "SetOnStringRequestedListener" before you turn on your timers. As it is, that method never gets called and onStringListener never gets set. You do call that line of code in the receiver, but of course its far too late there. Your main should instantantiate both the receiver and the sender, SetOnStringRequestedListener, and then set off the timers.
SendMessageClass send = new SendMessageClass();
ReceiveMessageClass recv = new ReceiveMessageClass()
send.SetOnStringRequestedListener(recv)
EDIT: Then take out any code in the receiver that references the sender. The idea behind using the listener is that the two classes don't know directly about each other.
Related
So I'm using the Observer pattern in my app in order to get notified of changes in another class without having to look for them.
I have a Singleton class which extends Observable. Inside this class I have two CountDownTimer type variables. Eachs of these contains two methods: onTick() and onFinished().
Let's call those Timers A and B for the sake of simplicity.
Every time A.onTick(), A.onFinished(), B.onTick(), B.onFinished() are called, I must call notifyObservers() to notify my Observer that something has changed.
Until here everything works fine. The problem is that I know something has changed, but I don't know what exactly has changed. Depending on which one notified me, I must execute some code on the Observer side.
How do I know which of these methods notified me?
Use LiveData instead of Observable. LiveData is quite useful because not only it's observable but also it binds to your activity's lifecycle so you don't have to worry about handling it yourself.
Maybe this example will help you:
public class MyTimerWrapper {
public static MyTimerWrapper getInstance() {
// Your singleton logic
createTimers();
return instance;
}
private CountDownTimer timerA;
private CountDownTimer timerB;
private MutableLiveData<TimerEvent> timerALiveData = new MutableLiveData<TimerEvent>();
private MutableLiveData<TimerEvent> timerBLiveData = new MutableLiveData<TimerEvent>();
public LiveData<TimerEvent> startTimerA() {
timerA.start();
return timerALiveData;
}
public LiveData<TimerEvent> startTimerB() {
timerB.start();
return timerBLiveData;
}
private void createTimers() {
createTimerA();
createTimerB();
}
private void createTimerA() {
timerA = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
// If you're running on another thread
timerALiveData.postValue(TimerEvent.TICK);
// Otherwise
timerALiveData.setValue(TimerEvent.TICK);
}
#Override
public void onFinish() {
// If you're running on another thread
timerALiveData.postValue(TimerEvent.FINISH);
// Otherwise
timerALiveData.setValue(TimerEvent.FINISH);
}
}
}
private void createTimerB() {
// Same as createTimerA, but with timerB
}
}
public enum TimerEvent {
TICK,
FINISH
}
Now to observe that data in your activity:
MyTimerWrapper timerWrapper = MyTimerWrapper.getInstance();
timerWrapper.startTimerA().observe(this, new Observer {
#Override
public void onChanged(TimerEvent timerEvent) {
// Here you'll be able to see whether timerA is ticking or finished
}
})
You can create a custom EventType class and pass it to Observable.notifyObservers(Object arg):
public class EventType {
String eventType; //"onTick" or "onFinish"
TimerType timerType;
EventType(String eventType, TimerType timerType){
this.eventType = eventType;
this.timerType = timerType;
}
}
TimerType is an enum type:
public enum TimerType {
A,
B;
}
and create TimerA and TimerB classes extending CountDownTimer:
private class TimerA extends CountDownTimer {
final EventType onTickEvent = new EventType("onTick", TimerType.A);
final EventType onFinishEvent = new EventType("onFinish", TimerType.A);
#Override
public void onTick(long millisUntilFinished) {
notifyObservers(onTickEvent);
}
#Override
public void onFinish() {
notifyObservers(onFinishEvent)
}
}
The Observerwill receive the EventType instance via its update(Observable o, Object arg); in the arg argument
This question already has answers here:
Create a custom event in Java
(6 answers)
Closed 5 years ago.
I want to write a simple event handling solution in Java with custom events. I've only find GUI based examples, using ActionListeners so far. I've included a code, that I wrote in C#.
I want to create something like this in Java:
using System;
using System.Threading;
namespace EventHandlingPractice
{
class Program
{
static void Main(string[] args)
{
MusicServer mServer = new MusicServer();
Sub subber = new Sub();
mServer.SongPlayed += subber.SubHandlerMethod;
mServer.PlaySong();
Console.ReadKey();
}
}
// this class will notify any subscribers if the song was played
public class MusicServer
{
public event EventHandler SongPlayed;
public void PlaySong()
{
Console.WriteLine("The song is playing");
Thread.Sleep(5000);
OnSongPlayed();
}
protected virtual void OnSongPlayed()
{
if (SongPlayed != null)
SongPlayed(this, EventArgs.Empty);
}
}
// this class is class is the subscriber
public class Sub
{
public void SubHandlerMethod(object sender, EventArgs e)
{
Console.WriteLine("Notification from: " + sender.ToString() + " the song was played");
}
}
}
In Java you generally create an class for the event itself, extending from EventObject. The events of interest are defined in an interface ending with the name Listener, extending the interface EventListener.
The class which is able to broadcast events has a add/remove listener methods, where the interested party can register themselves.
Your code will work without following these conventions though, but they are (were?) meant for tools to understand names of the classes and methods.
Here a sample pseudo implementation for your domain:
public class Song {
}
public class SongEvent extends EventObject {
private final Song song;
public SongEvent(Object source, Song song) {
super(source);
this.song = Objects.requireNonNull(song);
}
public Song getSong() {
return song;
}
}
public interface SongListener extends EventListener {
default void songStarted(SongEvent event) { }
default void songPaused(SongEvent event) { }
}
public class SongServer {
private List<SongListener> listeners = new ArrayList<>();
public void addSongListener(SongListener listener) {
listeners.add(listener);
}
public void removeSongListener(SongListener listener) {
listeners.remove(listener);
}
public void playSong(Song song) {
// ....
SongEvent event = new SongEvent(this, song);
listeners.forEach(l -> l.songStarted(event));
}
}
public class MyEventHandler implements SongListener {
#Override
public void songStarted(SongEvent e) {
System.out.printf("Now listening to %s%n", e.getSong().getName());
}
}
In previous versions of Java it was standard to include an Adapter (SongAdapter) which would implement the listener interface as no-op operations. The reason for that was that if you would add events classes that extended from the adapter didn't need to add code. With Java 8 you can include default methods, so the Event Adapter pattern is not needed anymore.
I currently have a web soap service method that works fine, but I would like to know how I can convert it to return a confirmation that the message has been received and that the client does not wait until I finish the process.
#Service
#WebService(serviceName =
"getStudents",wsdlLocation="/wsdl/Students.wsdl")
public class StudentsImpl implements Students {
public StudentResponse getStudents(StudentRequest
request) {
**********************
}
}
public class StudentResponse
{
private String status;
private Date timeStamp;
....................
}
I would like to know how I can respond with an "OK" status and also the time.
#WebService
public abstract interface Students
{
#WebResult(name="response")
#XmlElement(required=true, name="request")
public abstract StudentResponse
getStudents(#WebParam(name="request") StudentRequest
request);
}
Hm interestingly enough this seems to the be inverse of the last question I answered, Howto Convert an async call to blocking.
So the steps are:
Execute the blocking call in a new thread.
Introduce a listener interface
Invoke the listener from the thread when the blocking call completed
Introduce a new async wrapper which can be invoked from the caller.
Assuming your blocking call is fooBlocking(), do:
public class MyKoolClass {
// .. kool functionalities here ...
public interface Listener {
void onTaskCompleted(String message);
}
public void fooAsyncWrapper() {
new FooTask(new Listener() {
#Override
public void onTaskCompleted(final String message) {
System.out.println("So complete, bruh" + message);
}
}).start();
}
public static class FooTask extends Thread {
Listener listener;
public FooTask(final Listener listener) {
this.listener = listener;
}
#Override
public void run() {
fooBlocking();
listener.onTaskCompleted("Sup baws.");
}
}
I've looked at the java tutorials online and they all seem concerned with catching ActionEvents given out by other components that are already written. Is it possible to write your own objects that have there own set of criteria that trigger actionEvents that can then be caught by other classes that have registered as listeners?
So for example: If I wanted an object that was counting sheep to send out an actionEvent when 100 sheep had been counted to all the sleeper objects that had registered as listeners.
Is there a way to do this are there any tutorials online?
Any help is greatly appreciated.
Yes, it's pretty straightforward, once someone shows you how to create your own listeners.
First, you create your own EventObject. Here's an example from one of my projects.
import gov.bop.rabid.datahandler.bean.InmateDataBean;
import java.util.EventObject;
public class InmatePhotoEventObject extends EventObject {
private static final long serialVersionUID = 1L;
protected InmateDataBean inmate;
public InmatePhotoEventObject(Object source) {
super(source);
}
public InmateDataBean getInmate() {
return inmate;
}
public void setInmate(InmateDataBean inmate) {
this.inmate = inmate;
}
}
There's nothing special about this class, other than it extends EventObject. Your constructor is defined by EventObject, but you can create any methods you want.
Second, you define an EventListener interface.
public interface EventListener {
public void handleEvent(InmatePhotoEventObject eo);
}
You would use the EventObject you created. You can use any method name or names that you want. This is the interface for the code that will be written as a response to the listener.
Third, you write a ListenerHandler. Here's mine from the same project.
import gov.bop.rabid.datahandler.bean.InmateDataBean;
import gov.bop.rabid.datahandler.main.EventListener;
import gov.bop.rabid.datahandler.main.InmatePhotoEventListener;
import gov.bop.rabid.datahandler.main.InmatePhotoEventObject;
import java.util.ArrayList;
import java.util.List;
public class InmatePhotoListenerHandler {
protected List<EventListener> listeners;
public InmatePhotoListenerHandler() {
listeners = new ArrayList<EventListener>();
}
public void addListener(EventListener listener) {
listeners.add(listener);
}
public void removeListener(EventListener listener) {
for (int i = listeners.size() - 1; i >= 0; i--) {
EventListener instance = listeners.get(i);
if (instance.equals(listener)) {
listeners.remove(i);
}
}
}
public void fireEvent(final InmatePhotoEventObject eo,
final InmateDataBean inmate) {
for (int i = 0; i < listeners.size(); i++) {
final EventListener instance = listeners.get(i);
Runnable runnable = new Runnable() {
public void run() {
eo.setInmate(inmate);
instance.handleEvent(eo);
}
};
new Thread(runnable).start();
}
}
public static void main(String[] args) {
System.out.println("This line goes in your DataHandlerMain class "
+ "constructor.");
InmatePhotoListenerHandler handler = new InmatePhotoListenerHandler();
System.out.println("I need you to put the commented method in "
+ "DataHandlerMain so I can use the handler instance.");
// public InmatePhotoListenerHandler getInmatePhotoListenerHandler() {
// return handler;
// }
System.out.println("This line goes in the GUI code.");
handler.addListener(new InmatePhotoEventListener());
System.out.println("Later, when you've received the response from "
+ "the web service...");
InmateDataBean inmate = new InmateDataBean();
inmate.setIntKey(23);
handler.fireEvent(new InmatePhotoEventObject(handler), inmate);
}
}
The main method in this class shows you how you use a ListenerHandler. The rest of the methods in the class are standard. You would use your own EventObject and EventListener.
Yes.
I suggest you look at the java API documentation for ActionEvent and EventListenerList.
I also suggest that you read about the Listener (also called Observer) pattern.
I'm already working on this for weeks to get it working but without success. I'm using Javafx and java for implementing a small chat programm using the smack API (xmpp). The problem is how to get the received messages from java to javafx. The code below is actualy working when I have variable with a static string like "test message" and calling postMessage in java to send it to javafx. But how do I get another object (MessageListener) from java calling postMessage?
public class Java_callback implements RunnableFuture {
FXListener listener;
public String testmsg;
public Java_callback(FXListener listener) {
this.listener = listener;
}
#Override
public void run() throws Exception {
postMessage(testmsg);
}
public void postMessage(final String msg) {
Entry.deferAction(new Runnable() {
#Override
public void run() {
listener.callback(msg);
}
});
}
}
Here the code for processing the message. This part somehow need to call postMessage from the code above.
public void xmpp_create_chat(String msg) {
ChatManager chatmanager = connection.getChatManager();
Chat newChat = chatmanager.createChat("admin#unfc", new MessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
//msgArray.add( new String("Received message: " + message.getBody()) );
//msg_return = "blabla";
//java_callback.postMessage(msg_return);
//test.postMessage(message.getBody());
//System.out.println("Received message: " + message);
}
});
If you make postMessage() static, as in:
public static void postMessage(final String msg);
... then you can make a static method call to it from processMessage(), as in:
Java_callback.postMessage(msg_return);
UPDATE: Change your initializion of listener as well.
private static FXListener listener;
Hopefully this doesn't break something outside of the provided code :)
The class containing your second function has to have a reference to the first object, so that it can make the call.
What needs here is so basic that it's hard to figure out what an example might be.
something like this for your second class:
class MessageReceiver {
private Java_callback callback;
public void setJava_callback(Java_callback callback) {
this.callback = callback;
}
....
void process_message(...) { // inside your inner class
calllback.postMessage(msg);
}
}
Is the magic recipe that inner classes can refer to fields of their containing class?