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?
Related
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 am currently having some trouble with this code:
public class ChatPlugin extends JavaPlugin implements Listener{
private static ChatPlugin instance;
private final static String CHANNEL = "chat";
private JedisPool jedisPool;
private ChatChannel chatChannel;
#Override
public void onEnable()
{
instance = this;
saveDefaultConfig();
this.jedisPool = new JedisPool(new JedisPoolConfig(), getConfig().getString("redis-host"), 6379, 0,getConfig().getString("redis-password"));
this.chatChannel = new ChatChannel();
this.jedisPool.getResource().subscribe(this.chatChannel, new String[]{"chat"});
Bukkit.getPluginManager().registerEvents(this, this);
getCommand("chat").setExecutor(this);
}
#Override
public void onDisable()
{
instance = null;
this.chatChannel.unsubscribe();
this.jedisPool.destroy();
}
#Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (command.getName().equalsIgnoreCase("chat"))
{
getJedis().publish(CHANNEL, args[0]);
sender.sendMessage(ChatColor.GREEN + "Sent!");
}
return true;
}
public Jedis getJedis(){
return jedisPool.getResource();
}
public static ChatPlugin getInstance() {
return instance;
}
public class ChatChannel extends JedisPubSub {
#Override
public void onMessage(String channel, String message) {
new BukkitRunnable(){
#Override
public void run() {
Bukkit.broadcastMessage(message);
}
}.runTask(ChatPlugin.getInstance());
}
}
}
This is my first time working with redis' PUB/SUB feature, and I don't really know what is happening. There are no stacktraces, it's just, when the plugin enables, it freezes. Yes, I know this is because I am doing it on the main thread, but even if I run it async (Which I have) it still does not work.
Hope someone can help!
Thanks
You didn't sent us your saveDefaultConfig method so first of all check out if the plugin config is created correctly. After checking that you don't made any mistakes regarding Bukkit or any logical mistake, try to google for any example or try to find examples on programcreek.com (I've found some for jedis there).
If you still get no clue: try doing what you should have done before you've asked here. Read the wiki of Jedis!
https://github.com/xetorthio/jedis/wiki
I have a Service class that I am using to make web service calls using Volley:
public class AccountService {
public static void forgotPassword(Context c, String emailAddress) {
String url = "myUrl";
JsonArrayRequest request = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
// done
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(c).add(request);
}
}
And I'm calling it from an Activity like this:
public class ForgotPasswordActivity extends AppCompatActivity implements View.OnClickListener{
private void submit() {
accountService.forgotPassword();
}
}
When the Volley request is finished, I want to update the UI in my activity. How can I do this considering it is an asynchronous request? Am I able to call a method from the AccountService class in my activity? Thanks for the help
Pass a listener object to the AccountService and then send communication success or error to the activity.
Try as per below (you should not pass the layout to the AccountService which will create some unnecessary issues)
public class ForgotPasswordActivity extends AppCompatActivity
implements View.OnClickListener,
AccountServiceCallback{
private void submit() {
AccountService.forgotPassword("email#123.com", this);
}
#Override
public void onClick(View v) {
}
#Override
public void onResponse(JSONArray response) {
// UPDATE UI as per on response requirement
}
#Override
public void onErrorResponse(VollyError error) {
// UPDATE UI as per response flow
}
}
public class AccountService {
public static void forgotPassword(Context c, String email, final
AccountServiceCallback callback) {
String url = "myUrl";
JsonArrayRequest request = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
// done
callback.onResponse(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
callback.onErrorResponse(error);
}
});
Volley.newRequestQueue(c).add(request);
}
interface AccountServiceCallback {
public void onResponse(JSONArray response);
public void onErrorResponse(VollyError error);
}
}
You will have to find a way to get the result of your background work back onto the main thread so it can make changes to the view hierarchy. There are a LOT of ways to do this, and most of them are not really good.
But before you even do that, there are problems with your code. First, if you are thinking you made an Android Service component, you didn't actually do that. You made a class with the name AccountService, which does nothing special in the Android world.
Second, your call of forgotPassword() passes no arguments, but your definition of forgotPassword() in AccountService has a completely different signature. This wouldn't compile.
You should probably start learning about Android-specific asynchronous programming patterns and develop a strategy for solving your problem before writing code, because you'll almost certainly do it wrong without understanding what you're doing first.
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.