I need a Event-Dispatch-Thread in my programm.
I want go from this:
public Controller {
this.login= new Login(this);
}
to this:
public Controller {
Runnable guiCreator = new Runnable() {
public void run() {
this.login= new Login(this);
}
};
SwingUtilities.invokeLater(guiCreator);
}
I know where the mistake in the second version is. But the Login(Controller controller) constructor needs the controller reference...
How i do this?
Try using Controller.this to refer to the outer/top level instance of the class
public Controller() {
Runnable guiCreator = new Runnable() {
public void run() {
login= new Login(Controller.this);
}
};
SwingUtilities.invokeLater(guiCreator);
}
Related
I am trying to write a Utility class that helps to execute a task on a Separate Thread, providing the ability to do something before the task starts, and something after the task ends.
Something similar to android's AsyncTask
Here is such a class.
class MySync
{
public void preExecute() {}
public void executeInBackground() {}
public void postExecute() {}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
#Override
public void run()
{
try
{
MySync.this.preExecute();
MySync.this.executeInBackground();
MySync.this.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Here is how this class is supposed to be used. Consumer of the class will override the methods as per the requirement.
class RegisterStudent extends MySync
{
#Override
public void preExecute()
{
System.out.println("Validating Student details. Please wait...");
try
{
Thread.sleep(2000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void executeInBackground()
{
System.out.println("Storing student details into Database on Server. Please wait...");
try
{
Thread.sleep(4000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void postExecute()
{
System.out.println("Student details saved Successfully.");
}
}
And finally starting the task:
public class AsyncDemo
{
public static void main(String... args)
{
new RegisterStudent().execute();
}
}
It seems to work fine. My question is, is this the correct way of achieving the Objective as mentioned in the Title? Any suggestions on how best this can be implemented?
What I don't like with your approach is the fact that you create a new thread each time you create a new instance of MySync which is not scalable if you intend to create a lot of instances of your Object moreover it is costly to create a Thread, if I were you I would use an executor in order to limit the total amount of threads allocated to execute your tasks asynchronously, here is how you can do it if you want to use only one thread:
ExecutorService executor = Executors.newFixedThreadPool(1);
I would also re-write your code for something like this:
public abstract class MySync implements Runnable {
#Override
public final void run() {
try {
preExecute();
executeInBackground();
} finally {
postExecute();
}
}
protected abstract void preExecute();
protected abstract void executeInBackground();
protected abstract void postExecute();
}
This way you define the whole logic for all the implementations.
Then you can submit your task like this:
executor.submit(new RegisterStudent());
What's bad about this is that you're forcing users to extend your class. In java you can only extend 1 class. So a framework should not take that away.
Rather use an interface:
public interface AsyncTask {
public default void preExecute() {}
public default void executeInBackground() {}
public default void postExecute() {}
}
And have users pass that to your utility class:
class MySync
{
private AsyncTask task;
public MySync(AsyncTask task) {
this.task = task;
}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
#Override
public void run()
{
try
{
MySync.this.task.preExecute();
MySync.this.task.executeInBackground();
MySync.this.task.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Loader is exactly what you are looking for.
Here is introduction for loader
https://developer.android.com/guide/components/loaders.html
https://developer.android.com/reference/android/content/Loader.html
In Java we can do like this..
interface Inter {
public void run()
}
class Test {
public Test(Inter inter){
inter.run();
}
}
new Test(new Inter() {
#Override
public void run() {
//Some Task;
}
}
But in php I got error while doing like this. Isn't it possible to do this in php?
A little late, but you can do this in php:
new Test(new class implements Inter {
public function run()
{
// Some Task;
}
});
I have method like this:
public void rentBook(ArrayList<book> list, Book book)
{
if(!list.isEmpty())
{
list.remove(book);
book.setAvailable(false);
Biblioteka.listOfRented.add(book);
}
else
System.out.println("No any books left");
}
and I want to invoke this method in run() method of Thread. I'm making library system and I want to make the reade ( thread) can rent book (method rentBook ) I have no idea how can I correctly pass parameters. Any tips :/?
As discussed in the comments, here's two (compiling, running) ways you can do it:
public void methodUsingFinals() {
final ArrayList<book> list = new ArrayList<>();
final Book currentBook = new Book();
new Thread(new Runnable() {
#Override
public void run() {
rentBook(list, currentBook);
}
});
}
public void methodAcceptingValues(ArrayList<book> list, Book currentBook) {
new Thread(new Runnable() {
#Override
public void run() {
rentBook(list, currentBook);
}
});
}
I had to declare a static handler because of some Java nonsense with leaks.
static class ParsingCompleteHandler extends Handler {
private final WeakReference<BackupActivity> mTargetActivity;
ParsingCompleteHandler(BackupActivity targetActivity) {
mTargetActivity = new WeakReference<BackupActivity>(targetActivity);
}
#Override
public void handleMessage(Message msg) {
BackupActivity targetActivity = mTargetActivity.get();
targetActivity.updateDialog();
}
};
Elsewhere in the code (inside a runnable) I was trying to sendEmptyMessage() to this handler
Runnable runnable = new Runnable() {
#Override
public void run() {
lastBackupDataObject = getBackupDataObjectFromFile(file);
parsingCompleteHandler.sendEmptyMessage(0);
}
};
Thread parsingThread = new Thread(runnable);
parsingThread.start();
but since the sendEmptyMessage() method is not static (and the handler now is), obviously I can't do it. And I need to send a message to the handler because that's what it's there for. How do I do it?
You can do this by making your handler object as class global object and than call this message this should work
eg.
public class SomeClass{
ParsingCompleteHandler parsingCompleteHandler;
static class ParsingCompleteHandler extends Handler {
private final WeakReference<BackupActivity> mTargetActivity;
ParsingCompleteHandler(BackupActivity targetActivity) {
mTargetActivity = new WeakReference<BackupActivity>(targetActivity);
}
#Override
public void handleMessage(Message msg) {
BackupActivity targetActivity = mTargetActivity.get();
targetActivity.updateDialog();
}
};
than do
Runnable runnable = new Runnable() {
#Override
public void run() {
lastBackupDataObject = getBackupDataObjectFromFile(file);
parsingCompleteHandler.sendEmptyMessage(0);
}
};
Thread parsingThread = new Thread(runnable);
parsingThread.start();
Is there a way to access an anonymous outer class? A normal class can be accessed by ClassName.this. This doesn't work, as an anonymous class obviously doesn't have a name. I also tried using the extended class/interface (like Runnable.this) but it doesn't seem like it would work this way.
I'm sure this may be not the best coding style, I'm just curious if it's possible without storing this of the outer in a variable.
Example, watch out for outer.this:
public class A
{
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
synchronized (outher.this) {
outher.this.notify();
}
}
}).start();
try {
synchronized (this) {
wait();
}
} catch (final InterruptedException ex) {}
}
}).start();
}
}
No, there is no way to access anonymous classes from anywhere, except from inside them (i.e. otherwise than by this reference). Or by an explicitly declared variable.
final Runnable r1 = new Runnable() {...};
Runnable r2 = new Runnable() {
public void run() {
synchronized(r1) {...}
}
};
You could add a method to return this middle this. It would be in scope but not hidden (is that the right term? Shadowed? I forget.).
public static void main(String[] args) {
new Thread(new Runnable() {
Runnable middleThis() { return this; } // <-- this
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
synchronized (middleThis()) {
middleThis().notify();
Note, although anonymous inner classes have no name, they still are types. So adding members is visible to the immediate expression (new X() { Y z; }.z) and inside. You can't do middleThis().middleThis().