Reputation: 31
I know this seems simple but I have read every other version of this question on stack and other sites and cannot figure it out. I even simplified the issue and made a brand new separate program with only the 6 lines of code yet it still isn't working, I'll explain...
I am in the middle of creating a game and it requires two jframes. When I click the button on FRAME1 I want the jlabel on FRAME2 to change. Originally I wanted the labels' contents to change to the text inputted into a textfield on FRAME1 but after I started to struggle I have simplified it even more to try and get to the bottom of the problem.
Please find attached my code for FRAME1 and FRAME2.
FRAME1:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
FRAME2 set = new FRAME2();
set.setval("f");
}
I have only included the code I have added, the rest was computer generated in the NetBeans IDE.
FRAME2:
public void setval(String v){
val=v;
System.out.println(val);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jLabel1.setText(val);
}
UPDATE - full program
class 1
package crossjframe.image.change.test;
public class CrossjframeImageChangeTest {
public static void main(String[] args) throws InterruptedException {
a a = new a ();
a.setVisible(true);
b b = new b ();
b.setVisible(true);
}
}
Class 2
package crossjframe.image.change.test;
public class a extends javax.swing.JFrame {
public a() {
initComponents();
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
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(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(97, Short.MAX_VALUE)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(132, 132, 132))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(77, 77, 77)
.addComponent(jButton1)
.addContainerGap(198, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
b set = new b();
set.setval("f");
}
public static void main(String args[]) {
//<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(a.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(a.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(a.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(a.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new a().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
// End of variables declaration
}
Class 3
package crossjframe.image.change.test;
public class b extends javax.swing.JFrame {
String val="k";
public b() {
initComponents();
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setText("jLabel1");
jLabel1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jLabel1MouseClicked(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(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(238, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
}
public void setval(String v){
val=v;
System.out.println(val);
jLabel1.setText(val);
}
public static void main(String args[]) {
//<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(b.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(b.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(b.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(b.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new b().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
// End of variables declaration
}
Upvotes: 0
Views: 1249
Reputation: 324108
When I click the button on FRAME1
All your ActionListener code does is change the text of the "val" variable.
Nowhere do you actual update the text of the label.
If you want to update the text of the label then you need to update the label itself:
public void setval(String v)
{
//val=v;
//System.out.println(val);
jlabel1.setText( v );
}
Edit:
First of all learn an use proper Java naming conventions. Class names should start with an upper case character. Neither of your classes "a" or "b" follow these conventions making your code incredibly hard to read. If you expect people to take the time to look at your code, then make your code readable!!!
In your main() method you create an instance of class "a" and you create an instance of class "b" and make the frame visible. But you never keep a reference to class "b", so you can never invoke a method on class "b" again.
In the ActionListener of class "a" you create a second instance of the "b" class and invoke the setVal(...) method but you never make the frame visible, so you never see the change.
So the main problem you have is the design of your classes. If you want class "a" to invoke a method of class "b" then you class "a" needs to have a reference to class "b". The easiest way to do this is to create class "b" in the constructor of class "a" and then keep an instance variable for class "b".
You can't keep creating a new instance of a class to invoke a method on the class. You can't create an instance of
Then in the ActionListener code you access this instance variable for class "b" instead of creating a new instance of class "b".
Upvotes: 0
Reputation: 347194
So, in order to change the value of any object, you need a reference to said object.
While some would suggest passing a reference of the JLabel
from the first window to the second, I'd avoid this for a number of reasons...
It might be suggested that you create a interface
which provides the functionality that the second windows needs (set label value), to which the first window conforms to, then pass a reference of the first window to the second window.
This is not a bad idea, but we can still do better.
One of the primary principles most UI developers drive for is the concept of "model-view-controller", which is part of the "separation of responsibility" concept.
The idea been, that it's not actually the UI's responsibility to carry the state (ie the score), that responsibility is actually the "models". This allows you to pass a reference of the model to as many view's as you want and they will use it's information to display what ever state they need.
In your case, this means that the first window would update the state of the model (via a controller), the model would then generate a suitable event notification, which the second window would be registered to, and when triggered, would update the state of the UI accordingly.
This is commonly know as a "observer pattern".
Based on the available snippet of the code, you're creating a new instance of FRAME2
every time that the button is clicked, which is a bad idea, and passing the value to it, but not actually applying the value to the label, which would probably be mute anyway as the frame might not be visible - or you know have three windows on the screen all displaying something different
Upvotes: 1