how to implement a callback in runnable to update other swing class - java

I have a thread like this
public class SMS {
class Read implements Runnable {
Read(){
Thread th = new Thread(this);
th.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
while (true){
Variant SMSAPIReturnValue = SMSAPIJava.invoke("ReadSMS");
if (SMSAPIReturnValue.getBoolean()){
String InNumber = SMSAPIJava.getPropertyAsString("MN");
String InMessage = SMSAPIJava.getPropertyAsString("MSG");
}
}
}
}
}
How do I update the message to another GUI class in the same package(I understand how to put nested class to another package ....). Should I implement a callback function in SMS class? But how? Or should I pass in the Jlabel into the class?

If I read you correctly--if you want the other class to hear an event generated in this class, you should have that class add itself as a listener to this class.

Just pass the GUI components you want to update into SMS class, don't worry much about memory because it will be passed by reference, another choice is to have a singleton view class and any component you want to edit or update should have a getter function in the view class.
View.getSingleton().getJLabel1().setText(InNumber);

Related

How or why do listener interfaces work? And do interfaces have any other use rather than being a listener?

Whenever we want to create a listener, we implement a listener interface. For example, lets implement SensorEventListener.
Now we have to override the methods of this listener interface.
public void onSensorChanged(SensorEvent event);
and
public void onAccuracyChanged(Sensor sensor, int accuracy);
What I don't understand is:
Why and how these methods work when I automatically use them?
Why does onAccuracyChanged method gets called when the accuracy changes?
After all, onAccuracyChanged is just an empty method that we override because our formula (or the interface we implement) requires us to do so. If it is something magical caused by the lower levels
When and why would someone actually use an interface in his/her
self-project regardless of android?
Here is a suitable answer. Allow me to give you an example about listeners.
Listeners:
Suppose there is a class that fetches data in the background, the Worker, and another class that is interested in that data, the InterestedClass.
public class Worker extends Thread{
interface DataFetchedListener{
void onDataFetched(String data);
}
private DataFetchedListener listener;
#Override
public void run(){
String data = fetchData();
// Data fetched inform your listener so he can take action
listener.onDataFetched(data);
}
public void setDataFetchedListener(DataFetchedListener listener){
this.listener = listener;
}
private String fetchData(){
// returns the fetched data after some operations
return "Data";
}
}
public class InterestedClass implements Worker.DatafetchedListener{
#Override
public void onDataFetched(String data){
doSomethingWith(data);
}
private doSomethingWith(String data){
// just print it in the console
System.out.println("Data fetched is -> " + data);
}
}
The Worker does not care which class will manipulate its data, as long as that class follows the contract of DataFetchedListener.
Equally this means that any class is able to do something with the data (InterestedClass just prints it in the console) but Worker does not need to know which class is that, just that it implements its interface.
The main could go like this...
public class Application{
public static void main(String[] args){
InterestedClass interested = new InterestedClass();
Worker worker = new Worker();
worker.setDataFetchedListener(intereseted);
worker.start(); // Starts Worker's thread
}
}
When the Worker will fetch the data then it will notify its listener (currently the interested object) and the listener will act accordingly (interested will print the data to the console).
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.(Wikipedia)
You may wish to respond to some events either system events or user events. But for that you need to know when the event you wish to capture occurs and also what must be done at that time.
And for that you open a confidential EAR to listen to events. But that will not be sufficient since you need to be notified too so that you can reply according to the event. You set callbacks that will notify when an event occur. Those empty body methods we create inside an interface.
A Listener is that interface that hears and notify back through callbacks.
So how can all that be used? And how all these do interact?
First create an interface with empty bodies methods that you intend to call when an event occurs:
public interface MyListener{
void actionOneHappens(Object o);
void actionTwo();
void actionThree();
}
Create a class that handles something, for example counts:
public class MyCounter{
//create a member of type MyListener if you intend to exchange infos
private MyListener myListener;
//let's create a setter for our listener
public void setMyListener(MyListener listener)
{
this.myListener=listener;
}
MyCounter(){
}
//this method will help us count
public void startCounting()
{
new CountDownTimer(10000,1000)
{
#Override
public void onTick(long millisUntilFinished) {
//I want to notify at third second after counter launched
if(millisUntilFinished/1000==3)
{
// I notify if true :
//as someone can forget to set the listener let's test if it's not //null
if(myListener!=null){
myListener.actionThree();
}
}
}
#Override
public void onFinish() {
}
}.start();
}
}
You can then create an object of type MyCounter and know when it's at three:
MyCounter myCounter=new MyCounter();
myCounter.setMyListener(new MyListener()
{
//then override methods here
#override
void actionOneHappens(Object o){
}
#override
void actionTwo()
{}
#override
void actionThree()
{
//Add you code here
Toast.makeText(getApplicationContext(),"I'm at 3",Toast.LENGTH_LONG).show()
}
});
//start your counter
myCounter.startCounting();
And it's done!! That's how we proceed.
Interfaces have no implementation and for using them we have two options:
A class that implement them
An anonymous class
And consider this code:
interface TestInterface {
void doSomething();
}
class TestClass{
private TestInterface ti;
public TestClass(TestInterface ti){
this.ti = ti;
}
public void testActionMethod(){
ti.doSomething();
//some other codes
}
}
class OurOwnLauncherApp{
public static void main(String[] args) {
TestClass tc = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Hi!");
}
});
tc.testActionMethod();
TestClass tc2 = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Bye!");
}
});
tc2.testActionMethod();
}
}
In here we have:
An Interface (Just like what you asked)
A function class the uses that interface
An application somewhere that we don't know (Maybe your phone app, maybe your friends phone app, etc)
What this code does, it gives an anonymous class (which implements TestInterface) to the testActionMethod and with calling doSomething method inside testActionMethod, we invert the calling back to our own method. that's why you will see this result:
Hi!
Bye!
This is exactly a simplified version of listener interfaces and how they work
There is no magic thing. Generally, the event-listener mechanism is as follow:
For some entities, there is the possibility to listen to some events on that entity (let name this entity as event generator). So some way should exist for other entities to listen to these changes (let name these entities as listeners). Now a listener registers itself as a listener of event generator. When an event occurs on the event generator, it calls the related method of registered listeners.
As a simple example assume a button. The button may generate an event for some actions such as click. Now if a listener wants to aware when the button is clicked, it should register itself as a listener of that button. On the other hand, the button should provide a unified way of registering the listeners. This unified way is the interface. Each entity which implements the interface could register itself as a listener for click on that button:
1- Listener implements the interface
2- Listener registers itself as a listener of button (Event Generator)
3- Event Generator calls the appropriate method of all registered listeners (this method is a method of the interface).
For your case, android provides a manager which you could register a listener on some sensors by it: android.hardware.SensorManager.registerListener(). All things occurs here (which is not magic!). When you register an entity (which implemented the related interface, SensorEventListener) as a sensor listener, changes in that sensor will cause to call methods of the listener).

Android Redirection (delegates pointers)

I would like to call different code (callbacks) from within a background thread loop and use that background thread to perform the work. It would be similar to delegates in C#.
public class test {
private boolean keepRunning;
private boolean messageReady;
private MyClass myClass;
void LongBackgroundWork(){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while (keepRunning) {
if (messageReady){
myClass.callback(); // call different methods here
// to be decided at runtime and run on this worker thread
}
}
}
});
thread.start();
}
}
I want to use the background thread not the UI thread. I want to set a callback from within myClass to choose what code is called. It's easy in C# how to do it Java.
I don't have much experience in Java and don't understand what mechanism to use. Should I be using a handler? Can a handler run code on a background thread?
I'd wager you want to have a pattern where an event or some occurence happens and you need to initiate a code block somewhere.
A pattern that could help you is perhaps an Observer Wiki and firing off to the event. You can also check out this SO question here if you'd like: Delegate vs Callback in Java
In your case, I think you'd want to have someone handle the responsibility of what you have to do when a message is ready. So what you're looking for is someone to perform the action, once the event is read (message ready).
Take for example Class Foo is your container of listeners, or also called an Observer that will be notified of any events. You can have a list of callbacks here to some object that is responsible for your logic to do what you need to do next.
Then you would have an Observable object or a class that would implement some logic when notified. You could then have various class objects perform the necessary logic by implementing the callback function required.
Example:
// Observer
public class Foo {
// List of objects that implement Callbacks interface
private List<Callbacks> mList;
public Foo() {
// Initialize here
}
public void addListener(Callbacks cb) {
mList.add(cb);
}
public void notifyListeners() {
for ( Callback cb : mList) {
cb.onCallback();
}
}
// Public interface to be implemented by users
public interface Callback {
void onCallback();
}
}
Then just have a class implement this object and you can pass it along if you'd like.
// Bar implements Foo.Callback interface
public class Bar implements Foo.Callback {
public class Bar() {}
#Override
public void onCallback() {
// Perform logic here
}
}
Finally in your code, you'd just create the Foo object, add a listener, and notify them when it's time to fire your event.
if i understood you properly,you cant do this on UI thread, basically when android see Thread like this it will expect that it's a long operation however you can call it by AsyncTask or Handler
you can make something like this
private class MyAsyncTask extends AsyncTask<Void,Void,Void>{
protected Void doInBackground() {
MyClass myClass=new MyClass();
myClass.LongBackgroundWork();
}
return totalSize;
}
}
this is how yo can call your thread otherwise you have to use Handler instead
Handler handler=new Handler();
handler.post(new Runnable(){
MyClass myClass=new MyClass();
myClass.LongBackgroundWork();
})

How to run several methods in a thread? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a problem when I want to run several methods not in the main thread. I created a class extends from Runnable and put all my tasks there. There are a lot of tasks actually. Then in the main thread I created a new instance of Thread and passed my runnable class as a parameter, but what I got is that the run method is the only code which executed in the thread, and if call any method inside the runnable class it will execute in the main thread instead of the new thread.
Example:
public class ConnectionManager implements Runnable {
#Override
public void run() {
login();
}
public void login() {
//Login Logic
}
public void sendMessage() {
//Send Message Via TCP Connection
}
public void updateInfo() {
//Update Information
}
public void logOut() {
//LogOut Logic
}
}
Now I wanted to call any of these methods in another thread, so I did this:
public class Login implements SomeInterface {
private Thread thread;
private ConnectionManager connection;
public void main(String[] args) {
connection = new ConnectionManager();
thread= new Thread(connection);
thread.start(); // This will execute the run method and the login process works fine.
}
#Override
public void someCallback() {
connection.sendMessage();//this call is not executed and block the main thread !!
}
}
What am I supposed to do to run all my methods in another thread without making a new thread for each method?
You should split your logic
public class Logger implements Runnable {
#Override
public void run() {
// login logic here;
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Send Message Via TCP Connection
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Update Information
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//LogOut Logic
}
}
And then in some client:
Runnable logger = new Logger(credentials);
Executors.newSingleThreadExecutor().execute(logger);
Well this is how threads work in java. One possibility is to use Actors in java. You will have to download the Akka framework here:http://akka.io/downloads/.
Actors works by messages, they act in a separate process and are even driven messages. In other words depending on the message you send to the actor it will process a corresponding method.
Check in the following link for instances: http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html
The method run equivalent in java actors is onReceive().
And to send a message to the actor, myActor.tell(...)
Hope this helps you!!!!
Well, that is the way threads work in Java. When You call connection.sendMessage() Your method just treats ConnectionManager and runs it's code. You need to execute Your method in another threads run(), or it will not run. Perhaps You need a way to comunicate with Your thread to make it execute a method in run() or just explore the possibilities that Future objects give You?
That's how does Runnable or Multithread handling work.
You should never call the run() directly and only this function and other function calls inside this function are executed in the new thread.
Basically your Runnable class should only contains one public function: the run() and you should not call it directly...
I suggest you to put other functions in their own classes. As you can see the workflow is not continuous, sendMessage() is not called directly after login() (otherwise you can do it inside run() and don't need that someCallback()).
Otherwise what should that new thread supposed to do in the time between? block and wait for sendMessage()? That's not a good design. So you should start a new thread for sendMessage().

Passing Multiple objects To Each other

This is a little weird question, I have a GUI class that in the constructor initiates a Logic class that takes care of the processing of the Processing or Logistics in the App then their is a Handler class that contains a bunch of ActionListners KeyListeners that are attached to UI components in the GUI class
In Constructor of both the Logic and Handler class I take in as parameter the GUI class to be able to manipulate the GUI components created in the GUI class from both the Logic and Handler classes
My problem is that The Handler makes use of the Logic class and vise versa (the Logic class uses the Handler class) and thats not really possible with the method I described above, one is instance before the other, one will be null when attempting to use the other.
Example:
public class GUI()
{
this.handler = new Handler(this);
this.logic = new Logic(this);
}
If handler tries to use something in logic then null would be returned.
One way to fix this is to a setter for the handler to take the logic and vise versa but that doesn't seem like the answer to this.
simple:
public class GUI()
{
this.handler = new Handler(this);
this.logic = new Logic(this);
handler.setLogic(logic);
logic.setHandler(handler);
}
I think it is possible just to expose the Handler and Logic in GUI, and let the public access it. By doing so, as your Handler and Logic already have reference to GUI, they can indirectly get access to each other:
class Gui {
private Handler handler;
private Logic logic;
public Handler getHandler() {
return this.handler;
}
public Logic getLogic() {
return this.logic;
}
}
class Handler {
private Gui gui;
public Handler(Gui gui) {
this.gui = gui;
}
public void doSomething() {
// access logic
this.gui.getLogic().doSomeLogic();
}
}
Regarding to "elegance", I don't think the original design of (imho) messy dependencies between component is elegant at all :) So, instead of focusing making such things look "elegant", do some rethinking and possibly you will find everything become much more elegant automatically. :)
Right before your first usage of handler and logic you could put this code snippet
if(handler == null)
this.handler = new Handler(this);
if(logic == null)
this.logic = new Logic(this);

MVC - SwingWorker with a long running process that should update the view

How to obtain separation of the View from model when using a SwingWorker with a long running process that should send updates back to the controller ?
I can use the SwingWorkers doInBackground() to keep the EDT responsive by calling e.g model.doLongProcess() from in there great!
The issue I have is trying to get data back before the process is finished, to update the view with the progress..
I know that I can get data back by using by using the SwingWorkers publish() method but this I think forces me to write the code for the doLongProcess() method within doInBackground().
For reference the MVC implementation I have a looks a little like this:
http://www.leepoint.net/notes-java/GUI/structure/40mvc.html
/ structure/calc-mvc/CalcMVC.java -- Calculator in MVC pattern.
// Fred Swartz -- December 2004
import javax.swing.*;
public class CalcMVC {
//... Create model, view, and controller. They are
// created once here and passed to the parts that
// need them so there is only one copy of each.
public static void main(String[] args) {
CalcModel model = new CalcModel();
CalcView view = new CalcView(model);
CalcController controller = new CalcController(model, view);
view.setVisible(true);
}
}
I have one Model Class which wraps a number of other classes together to a form simple interface for the controller.
I really don't want to have to move all/some/any of the code from these Classes into the controller - It doesn't belong there.
Update:
Here is the approach that I am taking - Its not the cleanest solution and It could be perceived as an abuse of PropertyChangeSupport.. on a semantic level.
Basically all the low-level classes that have long running methods will have a propertyChangeSupport field. The long running methods call the firePropertyChange() periodically to update on the status of the method and not necessarily to report the change of a property - that is what I mean by semantic abuse!.
Then the Model class which wraps the low level classes catches these events and issues its own highlevel firePropertyChange .. which the controller can listen for...
Edit:
To clarify, when I call firePropertyChange(propertyName, oldValue, newValue);
propertyName ---> I abuse the propertyName to represent a topicname
oldValue =null
newValue = the message that I want to broadcast
Then the PropertyChangeListener in the model or where ever can discern the message based on the topicname.
So Iv basically bent the system to use it like a publish-subscribe ....
I guess in place of the above method I could add a progress field to the lowlevel classes that gets updated, and then firePropertyChange based on that.. this would fall into line with how its supposed to be used.
I think of the publish/process pair as pushing data from the SwingWorker into the GUI. Another way to pass information is by having the GUI or control pull the information out of the SwingWorker by using PropertyChangeSupport and PropertyChangeListeners. Consider
giving your model a PropertyChangeSupport field,
Giving it add and remove PropertyChangeListener methods
Having it notify the support object of changes in state.
Having the SwingWorker add a PropertyChangeListener to the model.
Then having the SwingWorker notifying control or view of changes in the model's state.
The SwingWorker could even use publish/process with the changed information from the model.
Edit
Regarding your update:
Basically all the low-level classes that have long running methods will have a propertyChangeSupport field. The long running methods call the firePropertyChange() periodically to update on the status of the method and not necessarily to report the change of a property - that is what I mean by semantic abuse!.
I don't recommend that you do this. Understand that if the bound property being listened to does not change, none of the PropertyChangeListeners (PCLs) will be notified even if firePC() is called. If you need to poll a property, then I wouldn't use a PCL to do this. I would simply poll it, probably from outside of the class being polled.
Personally, in my SwingWorker I'd create a public publish method, and pass the instance of my SwingWorker to the long running Model method. That way the model pushes updates to the control (SwingWorker), which then pushes to the View.
Here's an example - I threw everything into one file (for simplicity of running), but I'd imagine normally you'd have separate files/packages for these things.
EDIT
To decouple the model from the control, you'd have to have an observer of the model. I would implement a ProgressListener inheriting ActionListener. The model just notifies all registered ProgressListener that progress has been made.
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class MVCSwingWorkerExample {
public static void main(String[] args) {
CalcModel model = new CalcModel();
CalcView view = new CalcView();
CalcController controller = new CalcController(model, view);
}
//Model class - contains long running methods ;)
public static class CalcModel{
//Contains registered progress listeners
ArrayList<ActionListener> progressListeners = new ArrayList<ActionListener>();
//Contains model's current progress
public int status;
//Takes in an instance of my control's Swing Worker
public boolean longRunningProcess(MVCSwingWorkerExample.CalcController.Worker w){
for(int i = 0; i < 60; i++){
try {
//Silly calculation to publish some values
reportProgress( i==0 ? 0 : i*100/60);
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Whowsa!");
e.printStackTrace();
}
}
return true;
}
//Notify all listeners that progress was made
private void reportProgress(int i){
status = i;
ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_FIRST, null);
for(ActionListener l : progressListeners){
l.actionPerformed(e);
}
}
//Standard registering of the listeners
public void addProgressListener(ActionListener l){
progressListeners.add(l);
}
//Standard de-registering of the listeners
public void removeProgressListener(ActionListener l){
progressListeners.remove(l);
}
}
//View Class - pretty bare bones (only contains view stuff)
public static class CalcView{
Box display;
JButton actionButton;
JLabel progress;
public void buildDisplay(){
display = Box.createVerticalBox();
actionButton = new JButton("Press me!");
display.add(actionButton);
progress = new JLabel("Progress:");
display.add(progress);
}
public void start(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(display);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
public static class CalcController{
CalcModel model;
CalcView view;
public CalcController(CalcModel model, CalcView view){
this.model = model;
this.view = view;
//Build the view
view.buildDisplay();
//Create an action to add to our view's button (running the swing worker)
ActionListener buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
Worker w = new Worker();
w.execute();
}
};
view.actionButton.addActionListener(buttonAction);
//Start up the view
view.start();
}
//Notified when the Model updates it's status
public class ProgressListener implements ActionListener{
Worker w;
public ProgressListener(Worker w){
this.w = w;
}
#Override
public void actionPerformed(ActionEvent e) {
CalcModel model = (CalcModel)e.getSource();
w.publishValue(model.status);
}
}
//The worker - usually part of the control
public class Worker extends SwingWorker<Boolean, Integer>{
public Worker(){
//Register a listener to pay attention to the model's status
CalcController.this.model.addProgressListener(new ProgressListener(this));
}
#Override
protected Boolean doInBackground() throws Exception {
//Call the model, and pass in this swing worker (so the model can publish updates)
return model.longRunningProcess(this);
}
//Expose a method to publish results
public void publishValue(int i){
publish(i);
}
#Override
protected void process(java.util.List<Integer> chunks){
view.progress.setText("Progress:" + chunks.get(chunks.size()-1) + "%");
}
#Override
protected void done() {
try {
view.progress.setText("Done");
} catch (Exception ignore) {
}
}
}
}
}
For a long running process under Swing you must create a new Thread for that purpose, so when this process is complete, then you must update you MVC inside the "Swing thread", remember there is only one for each application.
Try find a way to let know the user that you application is processing, and do not allow him to "multiply" again, until done.
public class CalcController {
////////////////////////////////////////// inner class MultiplyListener
/**
* When a mulitplication is requested. 1. Get the user input number from the
* View. 2. Call the model to mulitply by this number. 3. Get the result
* from the Model. 4. Tell the View to display the result. If there was an
* error, tell the View to display it.
*/
class MultiplyListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
final String userInput = m_view.getUserInput();
new Thread(new Runnable() {
#Override
public void run() {
try {
m_model.multiplyBy(userInput);
} catch (NumberFormatException nfex) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
m_view.showError("Bad input: '" + userInput + "'");
}
});
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
m_view.setTotal(m_model.getValue());
}
});
}
}).start();
}
}//end inner class MultiplyListener
}

Categories