Call function on fix time interval using Thread - java

I want to call my function on specific time interval. For now my time interval set fixed as 1 minute. I have following code example:
Timer.java
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Timer implements Runnable{
public static volatile boolean isRunning = true;
#Override
public void run() {
while (isRunning) {
if(Thread.currentThread().getName().equals("TimerThread")){
System.out.println("Start Time "+new Date());
try {
test();
Thread.sleep(60000);
} catch (InterruptedException ex) {
Logger.getLogger(Timer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("End Time "+new Date());
}
}
}
public void test(){
System.out.println("Call Test ===========================> "+new Date());
}
}
NewJFrame.java
import java.awt.event.ItemEvent;
import java.util.Date;
public class NewJFrame extends javax.swing.JFrame {
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jToggleButton1 = new javax.swing.JToggleButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jToggleButton1.setText("Start");
jToggleButton1.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
jToggleButton1ItemStateChanged(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(162, 162, 162)
.addComponent(jToggleButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(138, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(129, 129, 129)
.addComponent(jToggleButton1)
.addContainerGap(142, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jToggleButton1ItemStateChanged(java.awt.event.ItemEvent evt) {
// TODO add your handling code here:
if(evt.getStateChange() == ItemEvent.SELECTED){
jToggleButton1.setText("Stop");
timer = new Timer();
timer.isRunning = true;
timerThread = new Thread(timer);
timerThread.setName("TimerThread");
timerThread.start();
}else{
jToggleButton1.setText("Start");
timer.isRunning = false;
System.out.println("Stop Time ===============> "+new Date());
}
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
public Timer timer;
public Thread timerThread;
// Variables declaration - do not modify
private javax.swing.JToggleButton jToggleButton1;
// End of variables declaration
}
When I start thread then I will get following output:
Start Time Sat Aug 08 10:45:01 IST 2015
Call Test ===========================> Sat Aug 08 10:45:01 IST 2015
Once Time interval completed then I get following output:
End Time Sat Aug 08 10:46:01 IST 2015
Start Time Sat Aug 08 10:46:01 IST 2015
Call Test ===========================> Sat Aug 08 10:46:01 IST 2015
after that I have stop my thread on 00:00:30 second so I will get following output:
Stop Time ===============> Sat Aug 08 10:46:31 IST 2015
I have stop my Thread on 00:00:30 second but my function call automatically after 00:00:30 second
Any one help me that how can I call any function on fixed time interval using Thread Just like When I click on Start button then my thread will start and call function then after wait for 2 minute. After 2 minute again call my function and repeat cycle. If I click stop button then thread will stop until I will start Thread using Start button.

The correct answer is: Don't use a Thread. Use a Timer, SwingTimer or ScheduledExecutorService depending on what you want the Thread to do.
To answer the actual question though you want then check isRunning and exit immediately after the sleep completes. You can also send an interrupt to the thread to make the sleep stop immediately if that is something you want.

Related

Save State of Java GUI

I'm pretty new to creating GUIs in Java, so I'm not sure if this is easy or difficult to do. I'm creating a random name chooser, where the user inputs names and then randomly selects some. I am trying to have it save the names entered after the application is closed, and then placed back when it is reopened. I am not sure the best way to go about this; I've looked around a little bit and read a bit about serialization, but it isn't making a lot of sense. Here's my code from NetBeans so far.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.DefaultListModel;
import sun.applet.Main;
import sun.audio.*;
public class NameChooser extends javax.swing.JFrame {
private ArrayList <Integer> integers;
private Integer index;
private DefaultListModel dlm;
/**
* Creates new form NameChooser
*/
public NameChooser()
{
initComponents();
integers = new ArrayList <Integer>();
dlm = new DefaultListModel();
}
public Integer generateNum()
{
int pings = 0;
do
{
pings = 0;
int temp = (int)(Math.random() * dlm.getSize());
index = new Integer(temp);
for (int k = 0; k < integers.size(); k++)
{
if ((integers.get(k).compareTo(index)) == 0)
{
pings++;
}
}
}
while (pings != 0);
return index;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
selectButton = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
names = new javax.swing.JList<>();
nameField = new javax.swing.JTextField();
resetButton = new javax.swing.JButton();
removeButton = new javax.swing.JButton();
jMenuBar1 = new javax.swing.JMenuBar();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
selectButton.setFont(new java.awt.Font("Dialog", 1, 18)); // NOI18N
selectButton.setText("Choose Name");
selectButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
selectButtonActionPerformed(evt);
}
});
names.setFixedCellHeight(30);
names.setFixedCellWidth(200);
names.setLayoutOrientation(javax.swing.JList.VERTICAL_WRAP);
jScrollPane2.setViewportView(names);
nameField.setText("Enter Name Here");
nameField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nameFieldActionPerformed(evt);
}
});
resetButton.setText("Reset");
resetButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
resetButtonActionPerformed(evt);
}
});
removeButton.setText("Remove");
removeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
removeButtonActionPerformed(evt);
}
});
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addGap(349, 349, 349)
.addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 197, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(resetButton))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(23, 23, 23)
.addComponent(removeButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(nameField, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
.addGap(18, 18, 18)))
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 589, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(64, 64, 64))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(119, 119, 119)
.addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(26, 26, 26)
.addComponent(removeButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(26, 26, 26))
.addGroup(layout.createSequentialGroup()
.addContainerGap(84, Short.MAX_VALUE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 418, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(resetButton)
.addGap(40, 40, 40))
);
pack();
}// </editor-fold>
private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {
integers.add(generateNum());
if (integers.size() <= dlm.getSize())
{
int [] indexes = new int [integers.size()];
for (int i = 0; i < indexes.length; i++)
{
indexes[i] = integers.get(i).intValue();
}
try {
// Open an audio input stream.
File soundFile = new File("C:\\Users\\Oskar\\Desktop\\sound.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
// Get a sound clip resource.
Clip clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
//playSound();
names.setSelectedIndices(indexes);
}
}
private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {
integers.clear();
int[]indexes = new int[0];
names.setSelectedIndices(indexes);
}
private void nameFieldActionPerformed(java.awt.event.ActionEvent evt) {
//Add Name
int size = nameField.getDocument().getLength();
if (size <= 0)
return;
dlm.addElement(nameField.getText());
nameField.setText("");
names.setModel(dlm);
}
private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {
if (names.getSelectedIndex() != -1)
{
dlm.remove(names.getSelectedIndex());
}
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NameChooser.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NameChooser.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NameChooser.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NameChooser.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NameChooser().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextField nameField;
private javax.swing.JList<String> names;
private javax.swing.JButton removeButton;
private javax.swing.JButton resetButton;
private javax.swing.JButton selectButton;
// End of variables declaration
}
Could I just make an array or arraylist containing the entered names, somehow save that to a file, then load that file upon running the program to import the names? Or possibly just save the state of the jList? Any help is appreciated.
It is not possible to serialize the state of a Java GUI, because many GUI objects are not serializable.
The JList class is declared as Serializable, so you may be able to serialize it. (It depends on the types of the elements in the list. They also have to be serializable.)
It is theoretically possible to write code that will traverse a GUI data structures, extract the state that needs to be saved into a serializable data structure, and then serialize it. Then you need code to do the reverse; i.e. rebuild / repopulate the GUI from the saved state. (But I suspect you would be better off dealing with this in a different way; e.g. using a custom "preferences" mechanism implemented using properties files or similar.)
However, your aim is to persist the data that you are displaying and updating in the GUI, it is better to do this at the "model" level. Depending on the nature of the model, and the requirements for handling the data, there are other alternatives to object serialization that are:
more efficient,
more scalable,
more resistant to data loss; e.g. when an application crashes,
more able to cope with evolution of the application, and
able to be accessed from outside of Java.
Have a look at java.util.prefs.Preferences. When your app closes, you can do something like...
public void savePreferences() {
Preferences preferences = Preferences.userNodeForPackage(NameChooser.class);
preferences.put("names", "name1, name2, name3");
}
You'll have to extract the names from JList and convert it to a comma delimited string (use StringBuilder). You should be able to get it using JList.getModel. Then when your app loads...
public void loadPreferences() {
Preferences preferences = Preferences.userNodeForPackage(NameChooser.class);
namesAsString = preferences.get("names", null);
}
String.split the namesAsString and whack it back in your JList. Make sense? You got a NullPointerException because I bet you just copy pasted the code. Here's a more simple example:
package example;
import java.util.Date;
import java.util.prefs.Preferences;
public class Example {
public static void main(String[] args) {
Preferences pref = Preferences.userNodeForPackage(Example.class);
String namesAsString = pref.get("names", "empty");
// on first run, this will be empty because you have not saved anything yet
// on succeeding runs, you should see something like:
// Names in preferences: name1Mon May 07 07:15:46 BST 2018, name2Mon May 07 07:15:46 BST 2018
System.out.println("Names in preferences: " + namesAsString);
// simulating new name every time this is run, hence the date
String name1 = "name1" + new Date();
String name2 = "name2" + new Date();
pref.put("names", name1 + ", " + name2);
}
}
You can make a use of Database if you would like to in order to maintain your state. But seems like, just for tiny thing maintaining a database would be costly.
Rather save them in a flat file .txt file and define your own delimiter.
For example:
Insert each record in a new line.
Each value in a record is separated by a pipe |.
Sample of file data:
First Name | Second Name | Anything
First Name 2 | Second Name 2 | Anything else
Then once your application loads up, check for the existence of this file and then read this file. You will need to create your parser which understands your file syntax. And then populate your GUI as per these data (if any).
Update the file if your application requires so
Another approach would be to Create a java class "State" (normal POJO) and then serialize it and save it in your file. When the application loads up, then deserialize it and use in your application.
The problem is:
Overhead of serializing and de-serializing and storing the file
Ensure when object upgrades then you need to maintain old fields (legacy) else your deserializing won't work (common problem of serialization/deserialization).
Google topic around this for more details.

JButton can't enabled, when exdending GUI form

I have four small class: one extends from JFrame and has GUI form, second — extends from him and contains button work logic. Third class call second's class method, when second — call him :)). My problem in second method in second class: button can't enable! I click — it disabled, but, when calling method enableButton — nothing do!
First class:
public class ClassParent extends JFrame {
protected JButton button;
private JPanel mainJPanel;
public ClassParent() {
super("Window");
setContentPane(mainJPanel);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public void showWindow() {
setVisible(true);
}
}
Second class:
public class ClassChildren extends ClassParent {
private CallerClass callerClass;
public ClassChildren(CallerClass callerClass) {
super();
this.callerClass = callerClass;
callerClass.setClassChildren(this);
button.addActionListener(a -> {
callerClass.callMe();
button.setEnabled(false);
});
}
public void enableButton() {
button.setEnabled(true);
}
}
Third class:
public class CallerClass {
private ClassChildren classChildren;
public void setClassChildren(ClassChildren classChildren) {
this.classChildren = classChildren;
}
public void callMe() {
classChildren.enableButton();
}
}
Main class:
public class Main {
public static void main(String[] args) {
new ClassChildren(new CallerClass()).showWindow();
}
}
And GUI form photo (I can't find code, other than open it in notepad :)):
Why is this happening and how fix it?
Apparently the OP has solved his problem, but I think this is an interesting and common-enough problem, so I've created a Minimal, Complete and Verifiable Example of what my recommended approach would be, for future reference.
You can check it out below, or you can get the full project from the GitHub repository.
(Reviews, suggestions, revisions and feedback are also welcome!)
Main JFrame:
/**
* #author Rodrigo Legendre Lima Rodrigues (AKA ArchR / AlmightyR)
* <rodrigolegendre.developer#gmail.com>
*/
public class Main extends javax.swing.JFrame {
/**
* A public method so we can enable/disable state from outside the class
* (while keeping the components encapsulated).
*
* #param enabled The input state the components should assume.
*/
public void setInputState(boolean enabled) {
this.startProcessButton.setEnabled(enabled);
}
/**
* Creates new form Main
*/
public Main() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
startProcessButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Primary Frame");
startProcessButton.setText("Process");
startProcessButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startProcessButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(startProcessButton, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(startProcessButton)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
#SuppressWarnings("Convert2Lambda")
private void startProcessButtonActionPerformed(java.awt.event.ActionEvent evt) {
//We need a non-annonymous reference for this frame to use within our annonymous 'run()'.
Main main = this;
//Here is were we disable input for (the components of) this frame before running the secondary frame.
this.setInputState(false);
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Secondary(main).setVisible(true);
}
});
}
/**
* #param args the command line arguments
*/
#SuppressWarnings("Convert2Lambda")
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Main().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton startProcessButton;
// End of variables declaration
}
Secondary JFrame:
/**
*
* #author Rodrigo Legendre Lima Rodrigues (AKA ArchR)
* <rodrigolegendre.developer#gmail.com>
*/
public class Secondary extends javax.swing.JFrame {
/**
* A variable to hold a reference to the main frame. We need this to enable
* the input of main again after this frame's work is done.
*/
private Main main;
/**
* A self-reference to this frame. We need this to hide the frame from
* within the worker, after it's job is done.
*/
private Secondary secondary;
/**
* A SwingWorker executes a process without interfering with the UI's
* execution, which could otherwise cause delays or complete "locking" of
* the visual and input processes.
*/
SwingWorker<Integer, Integer> swingWorker = new SwingWorker<Integer, Integer>() {
#Override
#SuppressWarnings("SleepWhileInLoop")
protected Integer doInBackground() throws Exception {
//Execute the process...
for (int i = 0; i <= 100; i++) {
progressBar.setValue(i);
Thread.sleep(100);
}
//We handle reactivating the main frame's inputs on the closing event,
//to make sure they get enabled after this frame is closed,
//regardless of sucess, cancelation or failure.
//We close and dispose of the secondary frame.
//Note: We have set default close behavior for this frame to be disposing, so we simply send it a closing event.
secondary.dispatchEvent(new WindowEvent(secondary, WindowEvent.WINDOW_CLOSING));
//Alternatively:
//main.setInputState(true);
//secondary.setVisible(false);
//secondary.dispose();
return 100;
}
};
/**
* In order to start the process while keeping all related code contained
* within this class, we make it listen to it's own WindowOpened event.
*
* In order to avoid calling an overridable method ('addListener()') from
* the constructor, which could be "forgotten" on extensions, we create a
* private method to initialize all self-listeners.
*/
private void initSelfListeners() {
WindowListener taskStarterWindowListener = new WindowListener() {
#Override
public void windowOpened(WindowEvent e) {
//This starts the process when the window opens.
System.out.println("Performing task...");
swingWorker.execute();
}
//<editor-fold defaultstate="collapsed" desc="UNUSED EVENTS/METHODS">
#Override
public void windowClosing(WindowEvent e) {
//Do nothing.
}
#Override
public void windowClosed(WindowEvent e) {
//Do nothing.
}
#Override
public void windowIconified(WindowEvent e) {
//Do nothing.
}
#Override
public void windowDeiconified(WindowEvent e) {
//Do nothing.
}
#Override
public void windowActivated(WindowEvent e) {
//Do nothing.
}
#Override
public void windowDeactivated(WindowEvent e) {
//Do nothing.
}
//</editor-fold>
};
//Here is where the magic happens. We make (a listener within) the frame start listening to the frame's own WindowOpened event.
this.addWindowListener(taskStarterWindowListener);
}
/**
* Creates new form Secondary
*/
#SuppressWarnings("LeakingThisInConstructor")
private Secondary() {
initComponents();
initSelfListeners();
this.secondary = this;
}
public Secondary(Main main) {
this();
this.main = main;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
processingLabel = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Secondary Frame");
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
processingLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
processingLabel.setText("Processing...");
progressBar.setStringPainted(true);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(processingLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(processingLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void formWindowClosing(java.awt.event.WindowEvent evt) {
//When the window is closed, we enable the input in the main frame again.
//This is advantageous as it handles most cases in one go...
//The cases were the window closes after the process is complete,
//the cases there the window closes due to cancelation,
//or the cases where it is closed by the user (after an error message) after a failure.
main.setInputState(true);
}
/**
* #param args the command line arguments
*/
#SuppressWarnings("Convert2Lambda")
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Secondary.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Secondary().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel processingLabel;
private javax.swing.JProgressBar progressBar;
// End of variables declaration
}
Problem was in that I call firstly callMe() and enable buttons and then — I disabled they in listeners......

how to monitor the close event of a JDialog?

I have got a tricky problem. I need to pop a confirm message box for user to decide close or not when someone click the close sign on the right upper corner of the window. But It doesn't work. Whatever you choose in the pop message box , the dialog will always be closed. But the same logic works fine when I create a JFrame.
Below is my code in my netbeans IED.
I just use a WindowAdpter to catch the close event, plz igore the dummy code generated by neatbean.
Thanks.
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class TestClosingDialog extends javax.swing.JDialog {
public TestClosingDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int a = JOptionPane.showConfirmDialog(null,"Are you sure you need to close?", "Tip", JOptionPane.YES_NO_OPTION);
if (a == 0) {
System.out.println("yes " + a);
System.exit(0); //close
} else if (a==1) {
System.out.println("no " + a);
}
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the dialog */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
TestClosingDialog dialog = new TestClosingDialog(new JFrame(), true);
dialog.setVisible(true);
}
});
}
// Variables declaration - do not modify
// End of variables declaration
}
Change setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); to setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING);
This will require you to manually dispose of the dialog. Depending on your needs, you would simply need to change System.exit(0); to dispose();
I would, personally, advise against extending directly from a top level container like JDialog, but that's just me.
I prefer to use, something like, a JPanel that has a helper method that can display an dialog. This method would create the dialog and add the panel to it, for example

how to write answers in textArea GUI from base code

I had some questions earlier regarding this base code which were
solved here but now my issue is that i have to take this code and get
out the result in GUI textArea. What ive done so far is that ive
designed a textArea and a button but now im stuck. I dont know how to
translate that code i used as a base into the GUI and make it possible
to click on the button and display the answers into the textdisplay. I
dont know if i should copy this base code somewhere or do i need to do
totally different thing inside of the GUI? For instance under
jButtonActionPerformed, what do i need to do... im sorry im new to
this and so lost. Ive googled all day but its hard to understand.
Here is the base code :
import java.lang.String;
class Vara {
//Deklarerar variabler
private String name;
private double price;
private int antal;
//tildela konstruktorer för de deklarerade variablerna
public Vara (String name, int antal, double price) {
this.name = name;
this.antal = antal;
this.price = price;
} // slut constructor
public void setName(String name) {
this.name = name; }
public void setPrice (double price) {
this.price = price; }
public void setAntal (int antal) {
this.antal = antal; }
public String getName() {
return this.name;}
public double getPrice() {
return this.price; }
public int getAntal() {
return this.antal; }
}
//testklassen ska stå som en egen klass
class Test {
public static void main(String[] args){
Vara var = new Vara("Banan",5, 12.5);
System.out.println("Namnet är " +var.getName() +" och priset är " +var.getPrice() +" och antalet är "+var.getAntal() );// här slutar system.out
}
}
And here is the beginning of my code in GUI which i havent done anything on so far except creating a textArea and a button.
public class NewJFrame extends javax.swing.JFrame {
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);
jButton1.setText("jButton1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap(29, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 213, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(69, 69, 69))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 361, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 231, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(17, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
txtDisplay.setText(null);
txtDisplay.append(String.valueOf(String)+"\n");
// TODO add your handling code here:
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/*
* Set the Nimbus look and feel
*/
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/*
* If Nimbus (introduced in Java SE 6) is not available, stay with the
* default look and feel. For details see
* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
}
in GUI Class make set the modifier to "Public Static" so it can be accessed from other class.
public static javax.swing.JTextArea jTextArea1;
then you can enter Value in this jTextArea1 from other classes. by accessing directly like this
NewJFrame.jTextArea1.append("text to append");
From your question it is not obvious if you want to put in data into your JTextArea or to read the content entered in the JTextArea in order to store it somewhere else. I will answer for both cases.
An elegant way to wire up data and GUI is to insert the data model object (in your case an instance of the class Vara) into a GUI object. E.g. this can be done right at the GUI object creation as shown in the code below. I commented each new line in your code with "// CHANGED: ...".
public class NewJFrame extends javax.swing.JFrame {
// CHANGED: store the model for this GUI
private Vara vara;
/**
* Creates new form NewJFrame
*/
public NewJFrame(Vara vara) { // CHANGED: provide the model for this GUI
this.vara = vara; // CHANGED: store the model for this GUI
initComponents();
// CHANGED: set TextArea content according to the data in the
// provided model object (if this is what you want)
jTextArea1.setText(vara.getName());
}
...
...
...
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
txtDisplay.setText(null);
txtDisplay.append(String.valueOf(String)+"\n");
// CHANGED: read the entered text from the TextArea and store it as the
// new name of the Vara object (if this is what you want to happen when
// the user clicks on the button)
vara.setName(jTextArea1.getText());
}
...
...
...
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
}
Some tips for a better programmer life:
use English everywhere, also in the comments
always name the GUI elements reasonable, e.g. your jButton1 could be btnSave ("btn" stands for Button) and your jTextArea1 could be taVaraName ("ta" stands for TextArea) - this greatly increase readability of your GUI code and makes debugging and maintaining much easier
use Eclipse for Java development, esp. if you want to build GUIs. It comes with a plugin called Eclipse WindowBuilder. This is "a powerful and easy to use bi-directional Java GUI designer", means you can: (1) easily drag-and-drop your GUI elements and get the code automatically generated for you; (2) modify any part of the code and see the drag-and-drop view automatically changing accordingly. It generates much cleaner and often shorter GUI code than the one you posted and lets you modify everything (does not have the "don't modify" parts you have in your code)

How to pause and resume a simple game in Java

i made simple game by java , it's about "tennis background" and "tennis ball" , and the ball is randomally move automatically ,
my game consist of two file , 1st file fore Jpanel , and 2nd file for JFrame ,
my question is : i need to control of "stopping and resuming" the ball by clicking the mouse ,
i tried to put wait() during thread running loop , but it's faild , i don't know what is the reason ! , so please review my code and then tell me what is the wrong , and what is the true method of "pause&resume" thread in my simple game !
tennis.java file (which contain the thread):
/*
* tennis.java
*
* Created on Nov 15, 2011, 3:35:28 PM
*/
package io;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class tennis extends javax.swing.JPanel implements Runnable{
BufferedImage ball;
BufferedImage bg;
int ball_h = 0;
int ball_w = 0;
int height = 0;
int width = 0;
int yPos = -1;
int xPos = 10;
int pause = 20;
// Move Speed
int xMov = 5;
int yMov = 10;
boolean clicked = false;
int play = 0;
Thread runner;
/** Creates new form tennis */
public tennis() throws IOException {
ball = ImageIO.read(new File("tennis/ball.png"));
bg = ImageIO.read(new File("tennis/bg.jpg"));
ball_h = 50;
ball_w = 50;
height = 600 - ball_h;
width = 800 - ball_w;
runner = new Thread(this);
runner.start();
}
public void start(){
if(play == 0){
play = 1;
clicked = true;
}else{
play = 0;
clicked = true;
}
System.out.println(play);
}
public void stop(){
runner = null;
}
#Override
public void paint(Graphics g){
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bg, 0, 0, 800,600, this);
g2D.drawImage(ball, xPos, yPos,50,50, this);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
// Variables declaration - do not modify
// End of variables declaration
#Override
public void run() {
while(runner == runner){
if(xPos >= (width))
{
xMov *= -1;
}
xPos += xMov;
if(xPos < 1)
{
xMov *= -1;
}
if(yPos >= (height-ball_h))
{
yMov *= -1 ;
}
yPos += yMov;
if(yPos < 1)
{
yMov *= -1 ;
}
repaint();
try {
if(play == 1){
Thread.sleep(pause);
}else{
synchronized(this){
while(play == 0){
wait();
}
}
}
} catch (InterruptedException ex) {
Logger.getLogger(tennis.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Tennis3D.java file(frame for starting the game and define the thread) :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/*
* Tennis3D.java
*
* Created on Nov 15, 2011, 3:42:42 PM
*/
package io;
import io.tennis;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Tennis3D extends javax.swing.JFrame implements MouseListener{
tennis tennis;
/** Creates new form Tennis3D */
public Tennis3D() {
super("Tennis3D");
setSize(800,600);
try {
tennis = new tennis();
add(tennis);
tennis.addMouseListener(this);
} catch (IOException ex) {
Logger.getLogger(Tennis3D.class.getName()).log(Level.SEVERE, null, ex);
}
setVisible(true);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
Tennis3D tennis = new Tennis3D();
}
// Variables declaration - do not modify
// End of variables declaration
#Override
public void mouseClicked(MouseEvent e) {
tennis.start();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Thank you for your help :)
This is piggy-backing on what Nerdtron wrote in the comment above. Typically a game loop looks like this
while (!game.isOver())
{
if (!game.isPaused())
game.update() // this moves your ball, players, etc
}
Your approach is strange. Most games have a sort of main loop where methods update(deltaTime) and draw() are called sequentially.
Typical main loop:
initGame();
while(!gameOver)
{
readInput();
update(deltaTime);
draw();
}
update(dt) is something like
for(GameObject go : myObjectList)
{
go.update(deltaTime);
}
If you want to skip some objects you could use something like:
for(GameObject go : myObjectList)
{
if(go.isActive())
{
go.update(deltaTime);
}
}
So your task would be trivial if you use game-loop structure like that.
To stop a thread wait()ing you need to call notifyAll() on the same object.
From the Javadoc for Object.wait()
Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
I would suggest you call notifyAll() in a synchronized block when you set play = 1;
A common way to achieve this is by using different states. So when you would put the game on pause it would go in PAUSE state. When resumed it would go back in RUNNING state or some other (more specific) state.
This is done by keeping the state in a variable. The C-way is to define integers like follows:
final int PAUSE = 1;
final int RUNNING = 2;
The Java-way is more like this: (using enums)
public enum State {
RUNNING,
PAUSE
}
Then, in your main loop (run method) you check the state in which the game is at that moment, and perform actions accordingly.
switch(state){
case PAUSE:
Thread.sleep(100);
break;
case RUNNING:
// do something entertaining
break;
}
so, if youre game loop includes a tick method or a particular method that updates the values of all the game objects, you can make a boolean called aused and only update the game values only if !paused.
And you can also use a class that extends Mouse adapter and add a mouselistener to your main class. so whenever the mouse clicked it checks if it is paused of not. if paused it unpauses it, if unpause then it pauses it

Categories

Resources