JButton can't enabled, when exdending GUI form - java

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......

Related

NullPointerException in simple JOGL test case

I'm trying a very simple JOGL tutorial using NetBeans and Swing and it seems no matter how I arrange things I keep getting a null pointer exception. Here is the code I am using (adapted from a tutorial):
package testjogl;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import java.awt.Dimension;
public class OpenGLTest extends javax.swing.JFrame implements GLEventListener {
public OpenGLTest() {
initComponents();
}
public void doMain() {
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(this);
canvas.setPreferredSize(new Dimension(640, 480));
this.getContentPane().add(canvas); // <--- This is where the exception happens
this.pack();
this.setVisible(true);
}
#Override
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
#Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
#Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
}
#Override
public void dispose(GLAutoDrawable drawable) { }
/**
* 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>
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new OpenGLTest().doMain();
}
});
}
// Variables declaration - do not modify
// End of variables declaration
}
At the line where I add the canvas to my form, I get:
Exception java.lang.NullPointerException(null) breakpoint hit in sun.awt.image.OffScreenImageSource at line 189 by thread AWT-EventQueue-0.
I've tried several different JOGL tutorials and all of them keep throwing this exception when I add the canvas to my form. I couldn't find the code to OffScreenImageSource, but when I step through, it dies at line 1119 in Container.java. The code is:
invalidateIfValid();
if (peer != null) {
comp.addNotify(); // <---- Dies right here
}
Does anyone have any ideas as to what might be causing this?
Your problem is you don't give enough time for Swing to initialize the component correctly with the OS GDI: As soon as you create the OpenGLTest() instance, you call doMain(). Give Swing some breath and it should work.
public static void main(String args[]) {
OpenGLTest test;
java.awt.EventQueue.invokeLater(() -> {
test = new OpenGLTest()
});
java.awt.EventQueue.invokeLater(() -> {
test.doMain();
});
}
FYI, I didn't validate the syntax.

joystick event in java

I have a java application containing one text-field and I'm using a joystick.
How can I do something in the text-field when a button on the joystick is pressed?
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package op;
import net.java.games.input.Controller;
/**
*
* #author Ahmed
*/
public class Test extends javax.swing.JFrame {
/**
* Creates new form Test
*/
public Test() {
initComponents();
con();
}
private void con(){
JInputJoystick joystick = new JInputJoystick(Controller.Type.STICK);
if( !joystick.isControllerConnected() ){
txt.setText("Not Connected");
}
else
txt.setText(joystick.getControllerType()+" "+joystick.getControllerName()+" Controller Cound!");
if( !joystick.pollController() ) {
txt.setText("Controller disconnected!");
}
// Number of buttons.
}
/**
* 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() {
txt = new javax.swing.JTextField();
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)
.addGroup(layout.createSequentialGroup()
.addGap(70, 70, 70)
.addComponent(txt, javax.swing.GroupLayout.DEFAULT_SIZE, 242, Short.MAX_VALUE)
.addGap(88, 88, 88))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(122, 122, 122)
.addComponent(txt, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(145, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
// Variables declaration - do not modify
private javax.swing.JTextField txt;
// End of variables declaration
}
Based on the tutorial project here: https://theuzo007.wordpress.com/2013/10/26/joystick-in-java-with-jinput-v2/ it looks like you have to loop and just check things, so
private void con(){
JInputJoystick joystick = new JInputJoystick(Controller.Type.STICK);
while (joystick.isControllerConnected()) {
// Go trough all components of the controller.
Component[] components = joystick.getComponents();
for(int i=0; i < components.length; i++) {
Component component = components[i];
Identifier componentIdentifier = component.getIdentifier();
// Buttons
if(componentIdentifier.getName().matches("^[0-9]*$")){ // If the component identifier name contains only numbers, then this is a button.
// Is button pressed?
if(component.getPollData() != 0.0f) {
txt.setText("Button got pressed!")
}
}
}
// We have to give processor some rest.
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
Logger.getLogger(JoystickTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
txt.setText("Controller not connected");
}

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