Swing Timer on main(String[]) exits the program after the time specified - java

I need to generate a new Thread every 2 seconds. So I tried to use the Timer class in the main(String[]) method but my program just exists after the milliseconds I specified in the Timer constructor.
Program.java:
public class Program
{
private static int panelWidth;
private static int panelHeight;
private static MyPanel panel = new MyPanel();
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
frame.add(Program.panel);
Program.panelWidth = frame.getWidth();
Program.panelHeight = frame.getHeight();
Timer generateBallTimer = new Timer(2000, new GenerateBalls());
while (true)
{
generateBallTimer.start();
}
} // End of main method
/**
* Generate a new ball every 2 seconds.
*
*/
public static class GenerateBalls implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
Program.generateBalls();
}
}
public static void generateBalls()
{
// Generate a ball each 2 seconds
while (true)
{
Program.panel.balls.add(new Ball(Program.panel));
}
}
} // End of program class
If in the Timer constructor I will specify 3000ms my program will be closed after 3 seconds and so on.
What am I doing wrong here?

Can you give me example of that "display list"?
You talk about "balls". What does your program need to know about a ball? Probably its position, maybe its speed, maybe its mass. Size? color? other stuff? It's up to you. The simplest implementation of a Ball object would just be a class with public fields to hold all of that information. Then, if Ball is the only kind of moving object in your animation, then your display list could just be a List<Ball>.
In a more complicated program, your Ball class might be an extension of some more general class, maybe VisibleObject, and then your display list would be a List<VisibleObject>.
As far as I know,for all the objects in a game to work concurrently they need to be Threads.
In a sense, you are right because there is only one class in all of Java that can do any work at all, and that class is Thread. No other class actually ever does anything. Other classes merely define methods that can be called by threads.
The trick is, to decouple the threads in the program from the work that they do. That's the motivation for the Runnable interface. Instead of having one object that both is a thread and also, describes the work to be done by the thread, you can have two classes; One takes care of all the thread-y stuff (.start(), .interrupt(), .join(), ...), and the other describes the work to be done (.run()).
Some say, it's hard to write a program that has too many classes/objects, but it's easy to write one that has too few.
As long as your Ball objects or your VisibleObject objects cleanly describe the things that you want to see on the screen and the ways in which you want to see those things move, there's no reason why each one's methods must be called by its own dedicated thread. There's no reason why you can't have just one thread that does the calculations for each one in its turn.

Related

How to use a thread to run another JFrame while the main is still running

I have a jframe i want to display while my main frame is running. i want to pause my main code, until the user does the necessary actions on the other frame. I've read a lot of solutions but i need to see it done for my code to understand and grasp it fully. i do not want to use jdialog like I've seen listed as an answer before. My main goal is to understand better threading so that i can use what i learn in different cases.
With the code I've created, when running the thread, only just the frame loads, none of the other features are there on the frame. (the frame is simple it has a label, a list the user selects from, and a button to basically return the chosen list value.) its like the thread is cut off from completing or something.
here is my class calling the screen:
public class myThread implements Runnable {
String result = null;
public void run() {
MessageScreen ms = new MessageScreen();
ms.setVisible(true);
}
public String getResult() {
return result;
}
public void setResult(String AS) {
result = AS;
}
}
in my main code, a method is called that is returning a String[] value, with this method at some point i have the following code calling the new thread to get the value necessary to return in the original main method:
myThread mt = new myThread();
Thread t = new Thread(mt);
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
myreturn = new String[] {"true", mt.getResult()};
without listing the whole code for the second frame, when the user presses the button, and at the end of the listener tied to the button press the i want to close the frame and return a string that was selected from the list:
jf.dispose();
myt.setResult(AdminSelection);
in the frame class, i have the following instance variables declared:
String AdminSelection = null;
myThread myt;
i hope this is enough information for someone to help me out and understand whats gone wrong here.
The function join() waits until the end of the run() method, when you do t.join(), your thread is already or almost ended. This is because in your run() method there is nothing that blocks the thread until the user has clicked the confirm button. And is better like this!
There is no sense to create a thread here, you should use a callback, or more generally in Java, a listener. You can take a look at Creating Custom Listeners.
But, especially if you want to pause your main code, you should use a (modal) JDialog which is made for this! Don't try to block the UI by yourself, you could block the UI thread (handled by Swing/AWT) by mistake. Creating a JDialog is better because everything is already made for this usage on the UI thread.
Also, you must know that create a Thread is really long, use a Thread when you really need it.

Which statement in my main method is calling all my other methods in my other classes and my main class?

Question: Ok, so this is going to sound slightly confusing due to my lack of total understanding on the subject. Currently, I am creating a game following a youtube tutorial (to understand the basics of game development in java).
After following some of the tutorials, I am confused as to what is the real purpose of the main method and the class that contains it. I thought that the main method's job was to call all the methods of its own class and the desired methods in other classes. However in my main method in my main "Game" class, here is all I have:
public static void main (String[] args) {
JFrame frame = new JFrame(title);
frame.add(game);
frame.setSize(WIDTH,HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.pack();
game.start();
}
Does frame.add(game) (game is an instance of Game) "call" all the other methods in other classes? Whatl the exactly does frame.add() do? Also, I am still trying to understand threads despite reading a lot of explanations. When I write game.start(); to "start" the thread, what exactly does this imply? Does it call all the methods in the game class only?
Here is my thread code if its needed:
private synchronized void start() {
if(running) {
return;
} else {
running = true;
}
thread = new Thread(this);
thread.start();
}
public synchronized void stop(){
if(!running) {
return;
} else {
running = false;
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit((0));
}
Here are the variables I initialized:
private static final long serialVersionUID = -8921419424614180143L;
public static final int WIDTH = 640;
public static final int HEIGHT = WIDTH / 4*3;
public static String title = "Game";
public static Game game = new Game();
public static GameState state = GameState.MENU;
private boolean running = false;
private Thread thread;
private Renderer gfx;
public static Game getInstance(){
I am just unsure of how all other methods in the game class and my other classes are being called if this is all I have in my main method. Any help would be GREATLY appreciated. I am really struggling here as you can probably tell.
The purpose of the main() method is to give an entry point for stand alone execution.
In your case (you did not show how game is initialized but I guess it was a static Game game = new Game(); initialized field) what happens is that first the static fields are initialized (which will call the Game() constructor).
Then the main method is started. It will set the initialized game as the content of the frame (which means the Frame will call various UI related methods like paint() from that moment on. Threading in Gui is a quite complicated topic, but for the sake of your question you can ignore it).
The rest of the methods in main are used to set up the containing frame. That's unusual for bigger applications but quite common for such small examples. (It does cause methods on game being called, for example for layout or drawing).
So finally main calls game.start() (which is the start() method on Game you have shown). It does create a new thread, which executes (by definition) the run() method on the Runable given to the new Thread(this) constructor (this, which is at this point the same instance as game).
The main() method is like any other method with respect to what it executes. Only what you explicitly execute (call) will be executed.
There is no method to automatically call all the other methods, because there is no purpose for such method. If, for some weird reason, you want such a method, just write it and from within it, do call the other methods.
A thread is a separate execution path in your program. When you call start() it begins and practically it goes to its special run() method, which is executed in parallel.
Any good introductory Java book should have detailed explanations to your questions.
The shortest answers that get at your bolded questions are:
frame.add(...) adds a component (like a button or label) to a frame or panel.
game.start() creates a new thread and calls the run() method of the game class in that thread.
So other methods you've written are called from game.run(). If they aren't in there (and they aren't in main(...)), they aren't being called.
I have to agree with the comment from PM77 though. It sounds like you're beginning in java, and Threading and GUIs are both pretty complex topics. There are basic games you can design (ie tic-tac-toe) that don't require either of them. Try those out before you tackle something as challenging as this.

Anonymous functions in java

I have a class called LinkGroup which holds some game objects. I call Rotate to set some rotation variables for these objects. Whenever my game hits its update loop, I rotate the objects according to the rotation variables. If they've rotated enough, I fire an onComplete callback.
The following code works...
public void Rotate(){
_currentRotation = _0;
_targetRotation = 180; //degrees
_rotationSpeed = 50;
try{
_onComplete = LinkGroup.class.getDeclaredMethod("rotateComplete", null);
}
catch(Exception ex){
}
}
...but this is ugly.
I don't like having to declare the method rotateComplete and manually link it to Rotate via a string. Is there something similar to anonymous functions in C# so I can just declared the rotateComplete method inside the Rotate method?
For bonus points, is there a better way to implement the required exception handling for "getDeclaredMethod"? Terseness is a preference.
From my understanding, I believe you are trying to call onRotateComplete() method in the LinkGroup class whenever some game object is been rotated. You can use the pattern that Java Swing uses for handling button clicks or other events: This could be done this way:
Define an interface
interface IRotateHandler {
public void onRotateComplete();
}
Change the Rotate() to Rotate(IRotateHandler handler) and then in LinkGroup class you can call your game object like this.
gameObject.Rotate(new IRotateHandler() {
public void onRotateComplete() {
/* do your stuff!
}
}
You don't need to use getDeclaredMethod. Just make _onComplete be a Runnable (or something similar), and create an anonymous class:
public void Rotate(){
_currentRotation = _0;
_targetRotation = 180; //degrees
_rotationSpeed = 50;
_onComplete = new Runnable() {
public void run() {
rotateComplete();
}
};
}
Java 7 doesn't yet have closures. Java 8 will. So, for the time being, there's no way to write that function anonymously in Java.
As for the error handling, a quick glance at the API shows me that you throw two RuntimeExceptions and a ReflectiveOperationException. Catching Exception may be your best bet, unless you wanted to catch all three of these possible exceptions differently, and take different action based on each.

Abstract class with Swing Timer

I have an abstract class as follows:
abstract class Grapher implements Runnable{
... member variables...
Timer timer;
boolean Done;
public void run(){
Done = false;
timer.start();
while(!Done){}
}
public void Grapher(){ //create graph}
...
}
The idea is that I want to have this abstract thread that creates a graph. I then want to extend this class to provide the implementation of what data that should be plotted on the graph. For example:
class RandomGraph extends Grapher{
ActionListener taskPerformer;
public RandomGraph(){
timer = new Timer(1000, taskPerformer);
taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// generate random data and add it to the graph data;
// if ... Done = true
}
};
}}
This should then plot random data to the graph. The problem I'm having is that I'm getting completely stuck in the while(!done) loop. Putting System.out.printlns inside the actionListener tell me the timer does not seem to be working as nothing appears on the console.
Am I being stupid for using threads at all? I thought it might be a good idea If I want the graph to plot data every few milliseconds.
You're passing null to the Timer constructor — you need to initialize taskPerformer first :-)
To address your bigger question: No, you're not stupid for using threads. However, I question your use of an abstract class at all here. What you really want is an interface Grapher describing an object that draws graphs, then a concrete subclass of Runnable (say, GrapherRunner) that sets up the timer, then delegates to a grapher to do the work.
(In OO-speak, this means using composition rather than inheritance.)

Threads; Creating a separate thread to periodically do something

As an addition to my current application, I need to create a separate thread which will periodically do some processing
I've create a new class to do all this, and this class will be loaded on startup of my application.
This is what I have so far :
public class PeriodicChecker extends Thread
{
static
{
Thread t = new Thread(new PeriodicChecker());
while(true)
{
t.run();
try
{
Thread.sleep(5000l);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* Private constructor to prevent instantiation
*/
private PeriodicChecker()
{
}
#Override
public void run()
{
System.out.println("Thread is doing something");
// Actual business logic here, that is repeated
}
}
I want to make constructor private to prevent other people from attempting to instantiate this class accidentally. How can I achieve this?
Also, is there anything bad about my implementation of such requirements? I'm only creating one thread which will run then sleep, have I missed anything obvious? I haven't worked with threads before
Java offers ScheduledExecutorService to schedule and run periodic tasks or tasks with delay. It should provide all the features you need. Timer is another class that offers similar functionalities, but I would recommend the ScheduledExecutorService over Timer for its flexibility of configuration and better error management.
You have some conceptual erros in your code... for example:
You should call start() and not run(), because you are running the method sequentially and not simultaneously.
You can call start() only once, not once in each loop iteration. After that, the thread is in state TERMINATED, you should create a new thread to run it again
You should not create the thread in the static block, it is a bad practice, and maybe the Thread is running before you want it to run.
You should read some examples about thread, it is a little difficult to unserstand at the beginning, and you can have undesired effects very easily.
Here is a little example, that may do something similar to that you want:
public class PeriodicChecker extends Thread
{
#Override
public void run()
{
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}
public OtherClass {
public static void main(String args[]) {
Thread t = new PeriodicChecker();
t.start();
}
}
If you want that none can create a new Thread, you could create a singleton, so you will be sure that none is creating more threads.
I'd recommend you to consider Timer class - it provides functionality for periodic tasks execution.
Also you may take a look at "Timer & TimerTask versus Thread + sleep in Java" question discussion - there you can find some arguments and examples.
First of all to answer your specific question, you have already achieved your objective. You have declared your constructor to be private meaning no external class can call it like new PeriodicChecker().
Looking at your code however, there are a number of other problems:
Firstly, you are creating an instance of your class within its own static constructor. The purpose of a static constructor is to initialise any static state that your class may have, which instances of your class may then depend on. By creating an instance of the class within the static constructor, all of these guarantees go out the window.
Secondly, I don't think your thread is going to behave in the way you expect it to behave, primarily because you don't actually start another thread :). If you intend to start a new thread, you need to call the start() method on that thread object. Calling run() as you do does not actually create a new thread, but simply runs the run() method in the current thread.
Nowadays when you want to create a new thread to do something, the reccomended way of achieving this is to not extend Thread, but instead implement the Runnable interface. This allows you to decouple the mechanism of the thread, from the behaviour you intend to run.
Based on your requirements, I would suggest doing away with a top-level class like this, and instead create either a private inner class within your application start-up code, or even go for an anonymous inner class:
public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}).start();
}
}
It is almost never right to extend Thread. If you ever find yourself doing this, step back, take a look and ask yourself if you really need to change the way the Thread class works.
Almost all occurances where I see extends Thread the job would be better done implementing the Runnable interface or using some form of Timer.

Categories