I'm trying to create a traffic simulation with a few cars, and an ambulance and traffic lights at an intersection. I trying to measure the time it takes for the ambulance to move through traffic. I However I'm seeing the cars (about 3) but I'm not sure how to get the traffic lights to show up.
I used a canvas to draw on and to specify parameters for each object such as cars, ambulance, stop line, etc. When I tried to do the same for a traffic light object it doesn't show up- then i tried specifying the parameters (color, x & y coordinates, and diameter) from my drawlight method but still nothing shows up.
Can anyone help me at least get the traffics lights showing up? Thanks
Here's the code:
/**
* Author: Jean-Paul Fernandes
* ******TRAFFIC SIMULATION******
*
* *****************TrafficCanvas Class******************
*
*/
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class TrafficCanvas extends Canvas {
/**
*
*/
public static final long serialVersionUID = 1L;
VehicleObject car, car_b, ambulance, ambulance_b;
String message, mode = "hi";
String str_seconds = "";
Boolean end;
StopLine stopline1, stopline2, stopline3, stopline4;
// TrafficLight2 wrson_dock_rd_tl_east_facing;
TrafficLight t1;
int count, seconds;
// TrafficFixtureForward westBound, eastBound, northBound;
// TrafficFixtureTurn turn;
// drawLine(20, 100, 120, 100);
public TrafficCanvas() {
super();
// TODO Auto-generated constructor stub
car = new Car(195,240,20,15,Color.BLUE,Color.GREEN);
// creates a blue car with specified dimension & location
car_b = new Car(215,280,20,15,Color.ORANGE,Color.GREEN);
ambulance = new Ambulance(300,240,30,17,Color.RED,Color.BLACK,false);
// creates a red ambulance in emergency mode
// if (count == 10)
{
ambulance_b = new Ambulance(350,280,30,17,Color.BLUE,Color.BLACK,true);
// creates another ambulance
}
stopline1 = new StopLine (250,240,5,25,Color.GRAY,Color.BLACK);
stopline2 = new StopLine (320,280,5,25,Color.GRAY,Color.BLACK);
stopline3 = new StopLine (260,300,25,5,Color.GRAY,Color.BLACK);
stopline4 = new StopLine (290,235,25,5,Color.GRAY,Color.BLACK);
// t1 = new TrafficLight (Color.RED, Color.YELLOW, Color.GREEN,
// 200,100,100,200,100,100,200,100,100);
// wrson_dock_rd_tl_east_facing = new TrafficLight2 ();
Thread movetraffic = new Traffic();
movetraffic.start();// moves traffic along
Thread starttimer = new Timer();
starttimer.start();
Thread operatetraf_lights = new TrafficController();
operatetraf_lights.start();
/*Thread operatetraf_lights1 = new TrafficFixtureForward(message, count);
operatetraf_lights1.start();*/
} // end TrafficCanvas
public void paint(Graphics g){
Graphics2D g2=(Graphics2D)g;
car.draw(g2);
car_b.draw(g2);
ambulance.draw(g2);
if (count>=10)
ambulance_b.draw(g2);
stopline1.draw(g2);
stopline2.draw(g2);
stopline3.draw(g2);
stopline4.draw(g2);
This next line is where I'm trying to create the red light of the traffic light:
t1.drawLight(g2, Color.RED, 500,500,75,75); // draw red light
{
g2.drawString(mode,600,300);
}
g2.drawString (str_seconds, 200, 200);
try {
// if (end)
{
g2.drawString("End!",400,300);
}
} catch (NullPointerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}// end paint
public class TrafficController extends Thread {
public void run() {
t1 = new TrafficLight ();
}
}
public class Timer extends Thread {
public void run() {
for (seconds = 0; seconds < 101; seconds++) {
str_seconds = Integer.toString(seconds)+ " seconds";
repaint();
try{
sleep(1000);
}
catch(InterruptedException e){}//end of try catch block
} // end for
repaint();
} // end run()
} // end class Timer
public class Traffic extends Thread {
public void run(){
Car c1 =(Car) car; // creates a car object c1
Car d1 =(Car) car_b;
Ambulance a1 =(Ambulance) ambulance;
// creates an ambulance object a1
Ambulance b1 =(Ambulance) ambulance_b;
if (count >=10) {
if (ambulance_b.EmergencyMode()) {
mode = "Emergency!";
} else {
mode = "Normal";
}
}
for (int count = 0; count < 50; count++) {
if (!(c1.shape().intersects(stopline1.shape()
.getBounds2D()))){
c1.moveEast();
}
a1.moveEast();
if (count>=10) {
if (!(b1.shape().intersects(stopline2.shape()
.getBounds2D()))) {
b1.moveWest();
}
}
d1.moveWest();
repaint();
try{
sleep(500);
}
catch(InterruptedException e){}//end of try catch block
if(c1.shape().intersects(stopline1.shape().getBounds2D())){
}
c1.setXcord(c1.getXcord());
c1.setYcord(c1.getYcord());
a1.setXcord(a1.getXcord()+ 1);
a1.setYcord(a1.getYcord());
if (count>10) {
b1.setXcord(b1.getXcord()+ 1);
b1.setYcord(b1.getYcord());
}
}
end = true;
message = "End!";
repaint();
}// end run
}// end class Traffic
}// end class TrafficCanvas
TrafficLight.java
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.awt.*;
import javax.swing.JPanel;
public class TrafficLight
/**
*
*/
private static final long serialVersionUID = 1L;
Color RedColor, YellowColor, GreenColor;
int RedxLCord, RedyLCord, RedLDiam, YellowxLCord, YellowyLCord, YellowLDiam, GreenxLCord, GreenyLCord, GreenLDiam;
public Shape shape(){
return new Rectangle2D.Double(500,500,200,600);
}
/*public TrafficLight(Color RedColor, Color YellowColor, Color GreenColor,
int RedxLCord, int RedyLCord, int RedLDiam,
int YellowxLCord, int YellowyLCord, int YellowLDiam,
int GreenxLCord, int GreenyLCord, int GreenLDiam)
{
}*/
public TrafficLight() {
}
/*public void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawRect(10,20,10,10);
g.fillRect(10,20,10,10);
}*/
public void drawLight(Graphics2D g2, Color Colour, int RedxLCord, int RedyLCord, int RedLDiam, int RedLDiam1 ) {
g2.setColor( Colour );
g2.fillOval(RedxLCord,RedyLCord,RedLDiam1,RedLDiam1);
}
}
SimulationFrame.java
import java.awt.*;
import java.awt.Canvas;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class SimulationFrame extends JFrame{
/**
* #param args
*/
Canvas c;
public SimulationFrame() {
c = new TrafficCanvas();
add(c,BorderLayout.CENTER);
setSize(1000,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
// This is the Main class which runs the program & creates a window on screen
public static void main(String[] args) {
SimulationFrame frame = new SimulationFrame();
}// end main method
} // end class SimulationFrame
EDIT:
The lights are showing but I can't get them to change- I have a TrafficController thread here:
public void run(Graphics2D g) {
// Graphics2D g = null;
// g3.drawString("TrafficController",400,300);
// Graphics2D g3=(Graphics2D)g;
TrafficLight tr1 = (TrafficLight)t1;
t1.drawLight(g,3);// show green
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.drawLight(g,2);// show yellow
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.drawLight(g,1);// show red
try {
Thread.sleep(150);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
Without trying to understand the huge amount of code posted, there is one thing you should certainly change. AWT/Swing requires all GUI operations to happen on the AWT Event Queue thread. As long as you have your own threads directly calling AWT/Swing methods you are bound to see all sorts of random update/paint issues, if not worse.
For a very simple throwaway piece of code, you might get away with running everything on the Event Queue thread entirely (at the cost of having an unresponsive GUI while it's simulating something). Otherwise you'll probably want to have two threads, one (in practice, your application's main thread) performing simulations, and the other being the Event Queue where you do all your GUI updates.
Useful reading to get you started with design: http://en.wikipedia.org/wiki/Event_dispatching_thread
Related
Mouse.java
package game.input;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
// holds information about mouse events.
// eg, presses of buttons.
public class Mouse extends MouseAdapter {
// the position of the mouse.
public static int x, y;
// Is the mouse pressed.
public static boolean pressed;
// Is the mouse held.
public static boolean held;
// Is the mouse hovered over the window.
public static boolean focused;
// Is the mouse being dragged.
public static boolean dragging;
// no mouse wheel support.
#Override
public void mouseWheelMoved(MouseWheelEvent event) {}
#Override
public void mouseDragged(MouseEvent event) {
x = event.getX();
y = event.getY();
dragging = true;
}
#Override
public void mouseMoved(MouseEvent event) {
x = event.getX();
y = event.getY();
}
#Override
public void mouseEntered(MouseEvent event) {
focused = true;
}
#Override
public void mouseExited(MouseEvent event) {
focused = false;
}
#Override
public void mousePressed(MouseEvent event) {
held = true;
}
#Override
public void mouseReleased(MouseEvent event) {
held = false;
dragging = false;
pressed = true;
}
}
Keyboard.java
package game.input;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
// holds information about key events.
public class Keyboard extends KeyAdapter {
// which keys are being held down.
private static boolean[] heldKeys;
// which keys are being clicked
private static boolean[] clickedKeys;
// size of arrays.
private final int size;
public Keyboard() {
// there are 255 valid key codes.
// plus one for the array size.
size = 256;
clickedKeys = new boolean[size];
heldKeys = new boolean[size];
}
// when the key is pressed.
#Override
public void keyPressed(KeyEvent event) {
// catches out of bounds error.
if(event.getKeyCode() > size)
return;
// key is being held.
heldKeys[event.getKeyCode()] = true;
}
#Override
public void keyReleased(KeyEvent event) {
// catches out of bounds error.
if(event.getKeyCode() > size)
return;
// key is let go.
heldKeys[event.getKeyCode()] = false;
// when key is let go, it gets interpreted as it being pressed.
clickedKeys[event.getKeyCode()] = true;
}
// returns whether or not the key is held.
public static boolean keyHeld(Key key) {
if(heldKeys != null)
return heldKeys[key.keyCode];
return false;
}
// returns whether or not the key is clicked.
public static boolean keyClicked(Key key) {
if(clickedKeys != null)
return clickedKeys[key.keyCode];
return false;
}
// resets key input.
public static void resetKeys() {
if(clickedKeys != null)
for(int i = 0; i < clickedKeys.length; i++)
clickedKeys[i] = false;
}
public enum Key {
// movement keys.
LEFT(37), UP(38), RIGHT(39), DOWN(40),
// x key.
A(88),
// z key.
B(90),
// enter key.
START(10);
private int keyCode;
private Key(int keyCode) {
this.keyCode = keyCode;
}
};
}
Game.java
package game;
import java.awt.Graphics2D;
import game.input.Keyboard;
import game.input.Mouse;
import game.room.Room;
import userInterface.containers.BB_Window;
// creates a new game
public final class Game {
// the window that the game resides in.
private static BB_Window window;
// the current room that is drawn to the window.
private static Room room;
private static GameLoop gameLoop;
// game constructor cannot be called.
private Game() {}
// inits the game.
// ie, adds input to the game (key and mouse).
public static void init(BB_Window window) {
if(gameLoop != null)
return;
// creates mouse and keyboard listeners.
Mouse mouse = new Mouse();
Keyboard keyboard = new Keyboard();
// adds input listeners to the window.
window.getJFrame().addKeyListener(keyboard);
window.getCanvas().addMouseListener(mouse);
window.getCanvas().addMouseMotionListener(mouse);
// init game loop
gameLoop = new GameLoop();
// init window
Game.window = window;
gameLoop.start();
}
// updates the current room and resets input.
protected static void update() {
// if room doesn't exist, don't update it.
if(room == null)
return;
// updates current room.
Game.room.update();
// resets mouse input.
Mouse.pressed = false;
// resets key input.
Keyboard.resetKeys();
// if a mouse or key button is clicked,
// then it would have to be reset to false here.
}
// renders the current room.
protected static void render() {
// if room doesn't exist, don't render it.
if(room == null)
return;
// creates graphics object from the window canvas.
Graphics2D graphics = (Graphics2D) window.getCanvas().getBufferStrategy().getDrawGraphics();
// creates the screen for next drawing.
graphics.clearRect(0, 0, window.getWidth(), window.getHeight());
// renders the current room.
Game.room.render(graphics);
// shows the buffer.
window.getCanvas().getBufferStrategy().show();
// removes graphics object.
graphics.dispose();
}
// sets the current room to a new one.
public static void setRoom(Room newRoom) {
newRoom.init();
Game.room = newRoom;
}
// returns the current room.
public static Room getRoom() {
return Game.room;
}
// returns width of window.
public static int getWindowWidth() {
return window.getWidth();
}
// returns height of window.
public static int getWindowHeight() {
return window.getHeight();
}
// stops the game loop.
public static void stop() {
gameLoop.stop();
}
}
GameLoop.java
package game;
public class GameLoop implements Runnable {
// the thread that the game runs on.
private Thread thread;
// is the game running.
private boolean running;
// starts the game loop.
// inits the thread and calls its start method.
public void start() {
// you can't start the game if it is started.
if(running)
return;
// starts the game.
running = true;
// creates thread.
thread = new Thread(this);
// starts the game.
// ie, calls thread.run();
thread.start();
}
// stops the game loop.
// interrupts the thread and terminates the currently running JVM.
public void stop() {
// you can't end the game if it is ended.
if(!running)
return;
// ends the game.
running = false;
// interrupts the thread.
// ie, ends the thread.
// this will always end the thread,
// because running is set to false.
thread.interrupt();
// ends the program.
System.exit(0);
}
// this is the game loop.
#Override
public void run() {
// holds information about each frames elapsed time.
double start, previous = System.nanoTime() / 1_000_000_000.0;
// time.
double actualFrameTime, realTime = 0;
// should the game be rendered.
boolean render;
// fps
final int FPS = 60;
final double DESIRED_FRAME_TIME = 1.0 / FPS;
// while the game is running
while(running) {
// calculates the elapsed time of the frame.
// converts from nano seconds to seconds
// by dividing by one billion.
start = System.nanoTime() / 1_000_000_000.0;
actualFrameTime = start - previous;
previous = start;
// the game time is updated by the elapsed frame time.
realTime += actualFrameTime;
// resets it to back to false.
render = false;
// if time surpasses desired frame time, game should update.
while(realTime >= DESIRED_FRAME_TIME && realTime != 0) {
realTime -= DESIRED_FRAME_TIME;
Game.update();
// if the game is updated, the game should render.
// if the game is not updated, the game doesn't render.
render = true;
}
if(render)
Game.render();
// sleep if game should not render.
// reduces cpu usage by a lot.
else
try {
// sleep for one millisecond.
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
BB_Window.java
package userInterface.containers;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
// the JFrame that the game will reside in.
public final class BB_Window {
private JFrame window;
private Canvas canvas;
private Dimension windowDimension;
// constructs the canvas, window, and buffer.
public BB_Window(String title, int width, int height) {
// creates dimension.
windowDimension = new Dimension(width, height);
// creates a canvas with a bunch of defaults.
canvas = new Canvas();
// sets a non-changeable size.
canvas.setPreferredSize(windowDimension);
canvas.setMinimumSize(windowDimension);
canvas.setMaximumSize(windowDimension);
// cannot be focused for event listeners.
canvas.setFocusable(false);
// creates window with a bunch of defaults.
window = new JFrame();
window.getContentPane().add(canvas);
window.setTitle(title);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.pack();
window.setVisible(true);
// center of screen.
window.setLocationRelativeTo(null);
BufferStrategy bufferStrategy = canvas.getBufferStrategy();
if(bufferStrategy == null)
canvas.createBufferStrategy(3);
}
// returns the frame.
public JFrame getJFrame() {
return window;
}
// returns the window width.
public int getWidth() {
return windowDimension.width;
}
// returns the window height.
public int getHeight() {
return windowDimension.height;
}
// returns the canvas.
public Canvas getCanvas() {
return canvas;
}
}
Room.java
package game.room;
import java.awt.Graphics2D;
// future functionality might be added,
// which is why this class is abstract and not interface.
// represents a room/location in your Game
// eg, a town, a house, a forest, and a cave are all examples of rooms.
public abstract class Room {
public abstract void init();
public abstract void update();
public abstract void render(Graphics2D graphics);
}
I feel that these files are the only ones needed to understand how my game library functions.
However, I notice that whenever I test out my game library, there is a very noticeable stutter that occurs every few seconds, and lasts for a few seconds. This is very annoying. However, what is more annoying is that this blocky/laggy movement is more noticeable on my computer than on other computers. What is going on with my computer for this to be occurring? How do I fix this? Here is an example of how my game library works.
Game.setRoom(new Room() {
private int x, y;
#Override
public void init() {
x = 0;
y = 0;
}
#Override
public void update() {
x++;
y++;
}
#Override
public void render(Graphics2D graphics) {
graphics.fillRect(x, y, 100, 100);
}});
Game.init(new BB_Window("Test", 640, 640));
This example program draws a rectangle that moves diagonally down the screen.
However, sometimes, the rectangle seems to "skip" pixels and moves more than it should.
I tried recording my screen to show exactly what is going on, but for some reason the stutter is not showing up in the video.
I tried enabling hardware acceleration by doing
System.setProperty("sun.java2d.opengl", "true");
but that didn't do anything.
My computer isn't bad at all, so why is the game running more smoother on other computers than on mine?
And what can I do to fix this in my game library?
Thank you in advance.
Background:
A well-known Swing best-practice requirement is that code that
interacts with the Swing framework must also execute in EDT (Event
Dispatch Thread).
I thus changed my code to have my JFreeChart-based updates to run in EDT.
However, a complete chart display task that usually took about 7 minutes to finish on a “normal” thread, become a several hours task when running in EDT!
What am I doing wrong? Did I misunderstood the Swing Concurrency lesson? Do I really have to run org.jfree.data.time.TimeSeries.addOrUpdate(date, double) inside EDT?
Please advise!
Details:
Clicking a Swing GUI button, my program triggers a time-consuming task.
Basically, it reads a (large) file with pair-values (date, double) and then shows them by using the JFreeChart framework.
Because this is a time-consuming task, while reading and displaying data, a JProgreessBar shows user the progress status in foreground, while the chart is updated in background (user is still able to visually see every chart update, behind the progress bar).
This worked fine, until I decided to review the code to have my chart data being updated and displayed inside Swing EDT. Then, a complete task that usually took about 7 minutes to finish, started to take several hours to complete!
Here’s the list of threads I’m using:
1) Since the task is triggered by a Swing Button Listener, it is running in EDT. The JProgressBar is also running in this same thread;
2) While showing the JProgressBar, a second (“normal”) thread is created and executed in the background. This is where the heavy work is done.
It includes the update of the JProgressBar status on the other thread (by calling JProgressBar.setvalue()) and the update of my JFreeChart chart (by calling TimeSeries.addOrUpdate(date, double), which automatically updates a org.jfree.chart.ChartPanel).
Updating the chart in my second (“normal”) thread usually took about 7 minutes to finish. Without any noticeable issue.
However, knowing that most Swing object methods are not "thread safe" and ChartPanel is just a Swing GUI component for displaying a JFreeChart object, I decided to run my chart update code TimeSeries.addOrUpdate(date, double) inside EDT.
Still running in my second “normal” thread, I tested with the following asynchronous code:
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
TimeSeries.addOrUpdate(date, double);
}
});
but I realized my JProgressBar would reach 100% much before the chart was updated.
I guess this was expected as displaying chart data is much slower than getting and processing the data.
I then tried following synchronous code:
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
TimeSeries.addOrUpdate(date, double);
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
And this is where I found the performance issue: now a complete task that used to take about 7 minutes to finish, started to take hours to complete!
So, my question is:
What am I doing wrong? Did I misunderstood the Swing Concurrency lesson? Do I really have to run TimeSeries.addOrUpdate(date, double) inside EDT?
Please advise!
UPDATE:
The complete code would be too large to show here, but you can find a code snapshot below.
Perhaps, the only thing noticeable about the code is that I use Reflection. This is because I use a generic ProgressBar Class that invokes in background whatever class I send it as an argument (though this is not clearly shown in the snapshot below).
//BUTTON LISTENER (EDT)
public void actionPerformed(ActionEvent arg0) {
new Process_offline_data();
}
public Process_offline_data() {
//GET DATA
String[][] data = get_data_from_file();
//CREATE PROGRESS BAR
int maximum_progressBar = data.length;
JProgressBar jpb = init_jpb(maximum_progressBar);
//JDIALOG MODAL WINDOW
JDialog jdialog = create_jdialog_window(jpb);
Object class_to_invoke_obj = (Object) new Show_data_on_chart();
String main_method_str = "do_heavy_staff";
Runnable r = new Runnable() {
public void run() {
//REFLECTION
Method method = null;
try {
method = class_to_invoke_obj.getClass().getDeclaredMethod(main_method_str, JProgressBar.class, String[][].class);
} catch (NoSuchMethodException | SecurityException e1) {
e1.printStackTrace();
jdialog.dispose(); //UNBLOCKS MAIN THREAD
return;
}
try {
method.invoke(class_to_invoke_obj, jpb, data);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
e1.printStackTrace();
jdialog.dispose(); //UNBLOCKS MAIN THREAD
return;
}
//----------------
jdialog.dispose(); //UNBLOCKS MAIN THREAD
}
};
new Thread(r).start();
//----------------
//THIS IS STILL EDT
jdialog.setVisible(true); //BLOCKS HERE UNTIL THE THREAD CALLS jdialog.dispose();
}
public class Show_data_on_chart {
public void do_heavy_staff(JProgressBar jpb, String[][] data) {
TimeSeries time_series = get_TimeSeries(); //JFreeChart datamodel
int len = data.length;
for (int i=0; i<len; i++) {
jpb.setValue(i+1);
Millisecond x_axys_millisecond = convert_str2date(data[i][0]);
Double y_axys_double = convert_str2double(data[i][1]);
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
//AUTOMATICALLY UPDATES org.jfree.chart.ChartPanel
time_series.addOrUpdate(x_axys_millisecond, y_axys_double);
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is how i solved the problem of updating the chart.
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.xy.XYSeries;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.chart.plot.XYPlot;
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
public class App extends ApplicationFrame {
XYSeries sin = new XYSeries("Sin");
public App(String applicationTitle, String chartTitle) {
super(applicationTitle);
JFreeChart xylineChart = ChartFactory.createXYLineChart(chartTitle, "X", "Y", new XYSeriesCollection(sin),
PlotOrientation.VERTICAL, false, true, false);
ChartPanel chartPanel = new ChartPanel(xylineChart);
chartPanel.setPreferredSize(new java.awt.Dimension(560, 367));
final XYPlot plot = xylineChart.getXYPlot();
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);
plot.setRenderer(renderer);
setContentPane(chartPanel);
}
public Runnable r = new Runnable() {
double x, y;
int i;
public void run() {
int steps = 69999;
for (i = 0; i < steps; i++) {
//sample plot data
x = Math.PI * 2.0 * 10.0 / ((double) steps) * ((double) i);
y = Math.sin(x);
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
if ((i % 1000) == 0) {
//adding data and redrawing chart
sin.addOrUpdate(x, y);
} else {
//adding point without redrawing of the chart
sin.add(x, y, false);
}
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//redrawing chart if all data loaded
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
sin.fireSeriesChanged();
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
public Runnable rupdate = new Runnable() {
public void run() {
while (true) {
//redrawing chart
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
sin.fireSeriesChanged();
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
//waiting for next update
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
public static void main(String[] args) {
final App chart [] = new App[1];
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
chart[0] = new App(null, null);
chart[0].pack();
RefineryUtilities.centerFrameOnScreen(chart[0]);
chart[0].setVisible(true);
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread job = new Thread(chart[0].r);
job.start();
Thread job2 = new Thread(chart[0].rupdate);
job2.start();
}
}
The above code includes two solutions. You can use either of them or both. Chart can be updated during data feeding. For example every 100th point and after last poit. Eventually you can make external thread that updates chart after some time. I have used updateAndWait every time instead of updateLater.
In your code do not use reflections like that. You should make interface. For example:
public interface IHardWork {
public void do_heavy_staff(JProgressBar jpb, String[][] data);
}
and implement it on every object that do the work:
public class Show_data_on_chart implements IHardWork {
public void do_heavy_staff(JProgressBar jpb, String[][] data) {
// TODO Auto-generated method stub
}
}
then use it:
IHardWork hwObj = new Show_data_on_chart();
hwObj.do_heavy_staff(jpb, data);
hwObj = new OtherHWObj();
hwObj.do_heavy_staff(jpb, data);
Eventualy You can make a base class for it and use polymorphism.
I've been working on this for awhile and can't figure out why this applet is not working properly:
I instantiated two threads in my applet.
I created two buttons- start, and stop, which are supposed to change the flag values to end the while() loops in my threads. The applet is not responding to either button. Any suggestions, anyone? Thanks for your time!
This is the applet...
package prodcons;
import java.applet.Applet;
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyTableSetting extends Applet {
Soup s; // we will show the soup bowl with the soup's alphabet pieces
int bowlLength = 150; // bowl's dimensions as variables in case we want to change it
int bowlWidth = 220;
int bowlX = 60;
int bowlY = 10;
Producer p1;
Consumer c1;
public void init(){
setSize(400,200); // make the applet size big enough for our soup bowl
s = new Soup(); // instantiate the Soup
p1 = new Producer(this, s); // declare and instantiate one producer thread - state of NEW
c1 = new Consumer(this, s); // declare and instantiate one consumer thread - state of NEW
p1.start(); // start the producer thread
c1.start(); // start the consumer thread
Button stop = new Button("Stop");
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Producer.producerRunning = false;
Consumer.consumerRunning = false;
Soup.clearBuffer();
}
});
add(stop);
Button start = new Button("Start");
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Producer.producerRunning = true;
Consumer.consumerRunning = true;
p1.run();
System.out.println("heyyy");
c1.run();
}
});
add(start);
}
public void paint(Graphics g){ // first we make the bowl and spoon
int x;
int y;
g.setColor(Color.orange);
g.fillOval(bowlX, bowlY, bowlWidth, bowlLength); // the bowl
g.setColor(Color.cyan);
g.fillOval(10, 25, 40, 55); // the spoon
g.fillOval(25, 80, 8, 75);
g.setColor(Color.black); // black outlines for the dinnerware
g.drawOval(10, 25, 40, 55);
g.drawOval(25, 80, 8, 75);
g.drawOval(bowlX,bowlY, bowlWidth, bowlLength);
ArrayList <String> contents = s.getContents(); // get contents of the soup
for (String each: contents){ // individually add each alphabet piece in the soup
x = bowlX + bowlWidth/4 +(int)(Math.random()* (bowlWidth/2)); // put them at random places to mimic stirring
y = bowlY + bowlLength/4 + (int)(Math.random()* (bowlLength/2));
Font bigFont = new Font("Helvetica", Font.BOLD, 20);
g.setFont(bigFont);
g.drawString(each, x, y);
}
}
}
and these are the threads:
package prodcons;
class Consumer extends Thread {
private Soup soup;
private MyTableSetting bowlView;
static boolean consumerRunning = true;
public Consumer(MyTableSetting bowl, Soup s) {
bowlView = bowl; // the consumer is given the GUI that will show what is happening
soup = s; // the consumer is given the soup--the monitor
}
public void run() {
System.out.println("consuming: "+consumerRunning);
String c;
try {
while(consumerRunning) { // stop thread when know there are no more coming; here we know there will only be 10
c = soup.eat(); // eat it from the soup
System.out.println("Ate a letter: " + c); // show what happened in Console
bowlView.repaint(); // show it in the bowl
sleep((int)(Math.random() * 3000)); // have consumer sleep a little longer or sometimes we never see the alphabets!
}
} catch (InterruptedException e) {
this.interrupt();
}
}
}
and this:
package prodcons;
class Producer extends Thread {
private Soup soup;
private String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private MyTableSetting bowlView;
static boolean producerRunning = true;
public Producer(MyTableSetting bowl, Soup s) {
bowlView = bowl; // the producer is given the GUI that will show what is happening
soup = s; // the producer is given the soup--the monitor
}
public void run() {
String c;
try {
while (producerRunning) { // only put in 10 things so it will stop
System.out.println("thikns producer != null");
c = String.valueOf(alphabet.charAt((int)(Math.random() * 26))); // randomly pick a number to associate with an alphabet letter
soup.add(c); // add it to the soup
System.out.println("Added " + c + " to the soup."); // show what happened in Console
bowlView.repaint(); // show it in the bowl
sleep((int)(Math.random() * 2000)); // sleep for a while so it is not too fast to see
}
} catch (InterruptedException e) {
this.interrupt();
}
}
}
and here is the "Soup" Class:
package prodcons;
import java.util.*;
public class Soup {
private static ArrayList <String> buffer = new ArrayList<String>(); // buffer holds what is in the soup
private int capacity = 6;
public synchronized String eat() { //this method can only be accessed by one thing at a time
while(buffer.isEmpty()){ // cannot eat if nothing is there, so check to see if it is empty
try {
wait(); // if so, we WAIT until someone puts something there
} catch (InterruptedException e) {} // doing so temporarily allows other synchronized methods to run (specifically - add)
} // we will not get out of this while until something is there to eat
String toReturn = buffer.get((int)(Math.random() * buffer.size())); // get a random alphabet in the soup
buffer.remove(toReturn); // remove it so no one else can eat it
buffer.trimToSize(); // reduce the size of the buffer to fit how many pieces are there
notifyAll(); // tell anyone WAITing that we have eaten something and are done
return(toReturn);
}
public synchronized void add(String c) {
while (buffer.size() == capacity) {
try {
wait();
}
catch (InterruptedException e) {}
}
buffer.add(c);
notifyAll();
}
public ArrayList <String> getContents() {
return buffer;
}
public static void clearBuffer() {
buffer.clear();
}
}
Thank you so much!
You call the Producer and Consumer directly on the main UI thread from the event handler for the start button. The only effect that this will have is to freeze your entire application. That's because the main UI thread does everything: event handling, repainting, etc. As long as you hold on to it, there is going to be no event handling, repainting, etc.
You should never call anything that takes long on the main UI thread.
But since you've already started the threads in your init method, you don't need to call run in your action listener. You remove those calls:
Button start = new Button("Start");
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Producer.producerRunning = true;
Consumer.consumerRunning = true;
}
});
Also, you should make the flags volatile, otherwise the change to them from one thread may not be visible in the other thread:
volatile static boolean producerRunning = true;
(etc.)
It seems like this applet will only draw and update DRAWS when the window is resized or minimized. So the applet will not repaint all the time, but only when manipulating the window.
Am I doing something wrong here?
I am following the gameloop presented here: http://www3.ntu.edu.sg/home/ehchua/programming/java/J8d_Game_Framework.html
The code is here:
package newapplet;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameApplet extends JApplet { // main class for the game as a Swing application
// Define constants for the game
static final int CANVAS_WIDTH = 493; // width and height of the game screen
static final int CANVAS_HEIGHT = 411;
static final int UPDATE_RATE = 4; // number of game update per second
static final long UPDATE_PERIOD = 1000000000L / UPDATE_RATE; // nanoseconds
static int DRAWS = 0;
// ......
// Enumeration for the states of the game.
public enum gameState {
INITIALIZED, CONNECTING, PLAYING, DISCONNECTED
}
private gameState state;
// Define instance variables for the game objects
// ......
// ......
// Handle for the custom drawing panel
private GameCanvas canvas;
// Constructor to initialize the UI components and game objects
public GameApplet() {
// Initialize the game objects
gameInit();
// UI components
canvas = new GameCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
this.setContentPane(canvas);
// Other UI components such as button, score board, if any.
// ......
this.setVisible(true);
}
// All the game related codes here
// Initialize all the game objects, run only once in the constructor of the main class.
public void gameInit() {
// ......
state = gameState.INITIALIZED;
}
// Shutdown the game, clean up code that runs only once.
public void gameShutdown() {
// ......
state = gameState.DISCONNECTED;
}
// To start and re-start the game.
public void gameStart() {
// Create a new thread
Thread gameThread = new Thread() {
// Override run() to provide the running behavior of this thread.
#Override
public void run() {
gameLoop();
}
};
// Start the thread. start() calls run(), which in turn calls gameLoop().
gameThread.start();
}
// Run the game loop here.
private void gameLoop() {
// Regenerate the game objects for a new game
// ......
//state = State.PLAYING;
// Game loop
long beginTime, timeTaken, timeLeft;
while (true) {
beginTime = System.nanoTime();
if (state == gameState.DISCONNECTED) break; // break the loop to finish the current play
if (state == gameState.PLAYING) {
// Update the state and position of all the game objects,
// detect collisions and provide responses.
gameUpdate();
}
// Refresh the display
repaint();
// Delay timer to provide the necessary delay to meet the target rate
timeTaken = System.nanoTime() - beginTime;
timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000L; // in milliseconds
if (timeLeft < 10) timeLeft = 10; // set a minimum
try {
// Provides the necessary delay and also yields control so that other thread can do work.
Thread.sleep(timeLeft);
} catch (InterruptedException ex) { }
}
}
// Update the state and position of all the game objects,
// detect collisions and provide responses.
public void gameUpdate() {
}
// Refresh the display. Called back via rapaint(), which invoke the paintComponent().
private void gameDraw(Graphics2D g2d) {
switch (state) {
case INITIALIZED:
g2d.setColor (Color.red);
g2d.drawString ("init",20,20);
break;
case PLAYING:
g2d.setColor (Color.red);
g2d.drawString ("play",20,20);
break;
case CONNECTING:
g2d.setColor (Color.red);
g2d.drawString ("connecting",20,20);
break;
case DISCONNECTED:
g2d.setColor (Color.red);
g2d.drawString ("disconnect",20,20);
break;
}
g2d.setColor (Color.GREEN);
g2d.drawString ("Re-paint: " + DRAWS,30,30);
this.DRAWS++;
// ......
}
// Process a key-pressed event. Update the current state.
public void gameKeyPressed(int keyCode) {
switch (keyCode) {
case KeyEvent.VK_UP:
// ......
break;
case KeyEvent.VK_DOWN:
// ......
break;
case KeyEvent.VK_LEFT:
// ......
break;
case KeyEvent.VK_RIGHT:
// ......
break;
}
}
// Process a key-released event.
public void gameKeyReleased(int keyCode) { }
// Process a key-typed event.
public void gameKeyTyped(char keyChar) { }
// Other methods
// ......
// Custom drawing panel, written as an inner class.
class GameCanvas extends JPanel implements KeyListener {
// Constructor
public GameCanvas() {
setFocusable(true); // so that can receive key-events
requestFocus();
addKeyListener(this);
}
// Override paintComponent to do custom drawing.
// Called back by repaint().
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g2d); // paint background
setBackground(Color.BLACK); // may use an image for background
// Draw the game objects
gameDraw(g2d);
}
// KeyEvent handlers
#Override
public void keyPressed(KeyEvent e) {
gameKeyPressed(e.getKeyCode());
}
#Override
public void keyReleased(KeyEvent e) {
gameKeyReleased(e.getKeyCode());
}
#Override
public void keyTyped(KeyEvent e) {
gameKeyTyped(e.getKeyChar());
}
}
// main
public static void main(String[] args) {
// Use the event dispatch thread to build the UI for thread-safety.
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GameApplet();
}
});
}
}
Glancing at that code quickly I can see that you are calling repaint() outside of the Event Dispatch Thread, which can cause issues like the one you are seeing. javax.swing.SwingUtilties.invokeAndWait(Runnable r) will allow you to put that repaint() call on the EDT.
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
See this code for a few corrections.
// <applet code='GameApplet' width=400 height=50></applet>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameApplet extends JApplet { // main class for the game as a Swing application
// Define constants for the game
static final int CANVAS_WIDTH = 493; // width and height of the game screen
static final int CANVAS_HEIGHT = 411;
static final int UPDATE_RATE = 4; // number of game update per second
static final long UPDATE_PERIOD = 1000000000L / UPDATE_RATE; // nanoseconds
Timer timer;
static int DRAWS = 0;
// ......
// Enumeration for the states of the game.
public enum gameState {
INITIALIZED, CONNECTING, PLAYING, DISCONNECTED
}
private gameState state;
// Define instance variables for the game objects
// ......
// ......
// Handle for the custom drawing panel
private GameCanvas canvas;
// Constructor to initialize the UI components and game objects
public GameApplet() {
// Initialize the game objects
gameInit();
// UI components
canvas = new GameCanvas();
// set the size of the applet in HTML, not the content pane!
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
this.setContentPane(canvas);
// Other UI components such as button, score board, if any.
// ......
//this.setVisible(true);
}
// All the game related codes here
// Initialize all the game objects, run only once in the constructor of the main class.
public void gameInit() {
// ......
state = gameState.INITIALIZED;
gameStart();
}
// Shutdown the game, clean up code that runs only once.
public void gameShutdown() {
// ......
state = gameState.DISCONNECTED;
}
#Override
public void destroy() {
timer.stop();
}
// To start and re-start the game.
public void gameStart() {
// Create a new thread
//Thread gameThread = new Thread() {
// Override run() to provide the running behavior of this thread.
// #Override
// public void run() {
gameLoop();
// }
//};
// Start the thread. start() calls run(), which in turn calls gameLoop().
//gameThread.start();
}
// Run the game loop here.
private void gameLoop() {
// Regenerate the game objects for a new game
// ......
//state = State.PLAYING;
// Game loop
ActionListener al = new ActionListener() {
long beginTime, timeTaken, timeLeft;
public void actionPerformed(ActionEvent ae) {
beginTime = System.nanoTime();
if (state == gameState.DISCONNECTED) {
//break; // break the loop to finish the current play
System.out.println("do SOMETHING here..");
}
if (state == gameState.PLAYING) {
// Update the state and position of all the game objects,
// detect collisions and provide responses.
gameUpdate();
}
// Refresh the display
repaint();
// Delay timer to provide the necessary delay to meet the target rate
timeTaken = System.nanoTime() - beginTime;
timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000L; // in milliseconds
if (timeLeft < 10) timeLeft = 10; // set a minimum
}
};
timer = new Timer(40,al);
timer.start();
}
// Update the state and position of all the game objects,
// detect collisions and provide responses.
public void gameUpdate() {
}
// Refresh the display. Called back via rapaint(), which invoke the paintComponent().
private void gameDraw(Graphics2D g2d) {
switch (state) {
case INITIALIZED:
g2d.setColor (Color.red);
g2d.drawString ("init",20,20);
break;
case PLAYING:
g2d.setColor (Color.red);
g2d.drawString ("play",20,20);
break;
case CONNECTING:
g2d.setColor (Color.red);
g2d.drawString ("connecting",20,20);
break;
case DISCONNECTED:
g2d.setColor (Color.red);
g2d.drawString ("disconnect",20,20);
break;
}
g2d.setColor (Color.GREEN);
g2d.drawString ("Re-paint: " + DRAWS,30,30);
this.DRAWS++;
// ......
}
// Process a key-pressed event. Update the current state.
public void gameKeyPressed(int keyCode) {
switch (keyCode) {
case KeyEvent.VK_UP:
// ......
break;
case KeyEvent.VK_DOWN:
// ......
break;
case KeyEvent.VK_LEFT:
// ......
break;
case KeyEvent.VK_RIGHT:
// ......
break;
}
}
// Process a key-released event.
public void gameKeyReleased(int keyCode) { }
// Process a key-typed event.
public void gameKeyTyped(char keyChar) { }
// Other methods
// ......
// Custom drawing panel, written as an inner class.
class GameCanvas extends JPanel implements KeyListener {
// Constructor
public GameCanvas() {
setFocusable(true); // so that can receive key-events
requestFocus();
addKeyListener(this);
}
// Override paintComponent to do custom drawing.
// Called back by repaint().
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g2d); // paint background
setBackground(Color.BLACK); // may use an image for background
// Draw the game objects
gameDraw(g2d);
}
// KeyEvent handlers
#Override
public void keyPressed(KeyEvent e) {
gameKeyPressed(e.getKeyCode());
}
#Override
public void keyReleased(KeyEvent e) {
gameKeyReleased(e.getKeyCode());
}
#Override
public void keyTyped(KeyEvent e) {
gameKeyTyped(e.getKeyChar());
}
}
}
Note that the addition of the single line comment at the top of the source means that (once compiled) it can be launched from the command line using..
> appletviewer GameApplet.java
i use from a class that extended from jframe and it has a button(i use from it in my program)
i want when run jframe in my program the whole of my program pause
until i press the button.
how can i do it
in c++ getch() do this.
i want a function like that.
Pausing Execution with Sleep, although I doubt that is the mechanism that you'll want to use. So, as others have suggested, I believe you'll need to implement wait-notify logic. Here's an extremely contrived example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
#SuppressWarnings("serial")
public class PanelWithButton extends JPanel
{
// Field members
private AtomicBoolean paused;
private JTextArea textArea;
private JButton button;
private Thread threadObject;
/**
* Constructor
*/
public PanelWithButton()
{
paused = new AtomicBoolean(false);
textArea = new JTextArea(5, 30);
button = new JButton();
initComponents();
}
/**
* Initializes components
*/
public void initComponents()
{
// Construct components
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
add( new JScrollPane(textArea));
button.setPreferredSize(new Dimension(100, 100));
button.setText("Pause");
button.addActionListener(new ButtonListener());
add(button);
// Runnable that continually writes to text area
Runnable runnable = new Runnable()
{
#Override
public void run()
{
while(true)
{
for(int i = 0; i < Integer.MAX_VALUE; i++)
{
if(paused.get())
{
synchronized(threadObject)
{
// Pause
try
{
threadObject.wait();
}
catch (InterruptedException e)
{
}
}
}
// Write to text area
textArea.append(Integer.toString(i) + ", ");
// Sleep
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
}
}
}
}
};
threadObject = new Thread(runnable);
threadObject.start();
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(400, 200);
}
/**
* Button action listener
* #author meherts
*
*/
class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent evt)
{
if(!paused.get())
{
button.setText("Start");
paused.set(true);
}
else
{
button.setText("Pause");
paused.set(false);
// Resume
synchronized(threadObject)
{
threadObject.notify();
}
}
}
}
}
And here's your main class:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class MainClass
{
/**
* Main method of this application
*/
public static void main(final String[] arg)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PanelWithButton());
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
});
}
}
As you can see, this example application will continually write to the text area until you click the button that reads 'Pause', whereupon to resume you'll need to click that same button which will now read 'Start'.
You don't say what you mean by pause. What is your app doing?
As a rule of thumb you CAN'T pause a UI app. User interface applications run from a message processing loop. Message comes in, message is dispatched, loop waits for another message. An app still needs to handles things like the user clicking on buttons, resizing the window, closing the app and so forth so this loop runs continuously.
If you want your application to "pause" in the sense of prevent the user doing something, just grey out whatever button or menu it is you don't want users to be doing.
If your app is running a thread in the background and wish it to suspend that action until you resume it, you can do so fairly easily like this.
MyThread mythread = new MyThread();
// Main thread
void pause() {
mythread.pause = true;
}
void resume() {
synchronized (mythread) {
mythread.pause = false;
mythread.notify();
}
}
class MyThread extends Thread {
public boolean pause = false;
public void run() {
while (someCondition) {
synchronized (this) {
if (pause) {
wait();
}
}
doSomething();
}
}
}
It is also possible to use Thread.suspend(), Thread.resume() to accomplish similar but these are inherently dangerous because you have no idea where the thread is when you suspend it. It could have a file open, be half way through sending a message over a socket etc. Putting a test in whatever loop controls your thread allows you do suspend at a point when it is safe to do so.
This answer entirely depends on whether I understand your question correctly, please give a bit more info if you want better answers. Here goes:
Pausing in a loop scenario
boolean paused;
while(true ) {
if(paused)
{
Thread.sleep(1000); // or do whatever you want in the paused state
} else {
doTask1
doTask2
doTask3
}
}
Threads:
You can also put those tasks into a seperate thread and not on the GUI thread which is typically what you would do for long running operations.
Pausing a thread is very easy. Just call suspend() on it. When you want to unpause call resume(). These methods however are dangerous and have been deprecated. Better or rather safer way to do it would be similar to the above by checking a pause flag.Here is a short example I had lying around in my snippets. Cant exactly remember where I got it in the first place:
// Create and start the thread
MyThread thread = new MyThread();
thread.start();
while (true) {
// Do work
// Pause the thread
synchronized (thread) {
thread.pleaseWait = true;
}
// Do work
// Resume the thread
synchronized (thread) {
thread.pleaseWait = false;
thread.notify();
}
// Do work
}
class MyThread extends Thread {
boolean pleaseWait = false;
// This method is called when the thread runs
public void run() {
while (true) {
// Do work
// Check if should wait
synchronized (this) {
while (pleaseWait) {
try {
wait();
} catch (Exception e) {
}
}
}
// Do work
}
}
} // Create and start the thread
MyThread thread = new MyThread();
thread.start();
while (true) {
// Do work
// Pause the thread
synchronized (thread) {
thread.pleaseWait = true;
}
// Do work
// Resume the thread
synchronized (thread) {
thread.pleaseWait = false;
thread.notify();
}
// Do work
}
class MyThread extends Thread {
boolean pleaseWait = false;
// This method is called when the thread runs
public void run() {
while (true) {
// Do work
// Check if should wait
synchronized (this) {
while (pleaseWait) {
try {
wait();
} catch (Exception e) {
}
}
}
// Do work
}
}
}
Hope this helps
try my java pause button:
package drawFramePackage;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.Timer;
public class Milliseconds2 implements ActionListener, MouseListener{
JFrame j;
Timer t;
Integer onesAndZeros, time, time2, placeHolder2;
Boolean hasFired;
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Milliseconds2();
}
public Milliseconds2(){
j = new JFrame();
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setSize(new Dimension(300, 300));
j.setVisible(true);
j.addMouseListener(this);
onesAndZeros = new Integer(0);
time = new Integer(0);
time2 = new Integer(0);
placeHolder2 = new Integer(0);
hasFired = new Boolean(true);
t = new Timer(2400, this);
time = (int) System.currentTimeMillis();
t.start();
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if (onesAndZeros.equals(0)){
t.stop();
if (hasFired){
time2 = t.getDelay() - ((int) System.currentTimeMillis() - time);
}
else{
time2 -= (int) System.currentTimeMillis() - placeHolder2;
}
if (hasFired){
hasFired = false;
}
onesAndZeros = -1;
}
if (onesAndZeros.equals(1)){
//System.out.println(time2);
t.setInitialDelay(time2);
t.start();
placeHolder2 = (int) System.currentTimeMillis();
onesAndZeros = 0;
}
if (onesAndZeros.equals(-1)){
onesAndZeros = 1;
}
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
time = (int) System.currentTimeMillis();
hasFired = true;
System.out.println("Message");
}
}
Freezing your Main Thread will effectively freeze the entire program and could cause the operating system to think the application has crashed, not quite sure so correct me if I'm wrong. You could try to hide/disable the controls and enable them again when the user clicks on your button.
UI performs task using message driven mechanism.
If you have a button in your UI and you want to run something when that button is pressed, you should add an object of ActionListener to your button. Once the button is pressed, it fires the ActionListener object to perform a task, e.g.:
button.addActionListener(new ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// do something
}
});
If you want to stop something when you press a pause button, you will defnitely need a Thread. This is more complicated than the former case.