Adding text to a label from another class - Simple Logic Issue

我的未来我决定 提交于 2019-12-08 07:37:20

问题


I have a label and a button in a class called FrameTest, when i press the button, a method named buttonpressed get's executed from the class Test. In this buttonpressed method i will set a text to the label found in the FrameTest class.

The problem i have is that, the text for the label is not getting set. The reason is that i am creating a separate object to call the buttonpressed method;

public void actionPerformed(ActionEvent arg0) {
                    Test t = new Test();
                    t.buttonpress();
                }

and i am creating a separate object in the main method of the Test class to create the UI.

public static void main(String[] args) {

         FrameTest f = new FrameTest();
         f.mainScreen();

    }

The full code as follows;

public class FrameTest extends JFrame {

private JPanel contentPane;
private JLabel lblLabel;
private FrameTest ft = this;

//private FrameTest frame;
/**
 * Launch the application.
 */
public  void mainScreen() {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                //FrameTest frame = new FrameTest();
                //setVisible(true);

                FrameTest frame = ft;
                frame.setVisible(true);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}


public void writeLabel(String k){
    this.lblLabel.setText(k);

}

public FrameTest() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setExtendedState(JFrame.MAXIMIZED_BOTH); 

    //setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    lblLabel = new JLabel("LABEL");
    contentPane.add(lblLabel, BorderLayout.CENTER);

    JButton btnNewButton = new JButton("Press");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Test t = new Test();
            t.buttonpress();
        }
    });
    contentPane.add(btnNewButton, BorderLayout.WEST);
    //pack();
    setLocationByPlatform(true);
}

}

Test Class

public class Test {


public static void main(String[] args) {

     FrameTest f = new FrameTest();
     f.mainScreen();

}

public void buttonpress(){
     FrameTest f = new FrameTest();

     f.writeLabel("Button was pressed");

}

回答1:


1) Dont extend JFrame class unnecessarily.

2) dont use setContentPane() unless thats what you want. Rather just simply JFrame#add(..).

3) Steer away from EventQueue and use SwingUtilities block rather

4) Dont forget to call JFrame#pack(); before setting JFrame visible.

5) Java naming convention is CamelCase so buttonPress() is correct not buttonpress()

Here is an example I made (basically your code fixed):

Test.java: (This is the main class which will create an instance of your FrameTest and has the method to change JLabel text)

import javax.swing.SwingUtilities;

public class Test {

    private static FrameTest f;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                f = new FrameTest();
                f.mainScreen();
            }
        });
    }

    void buttonPress() {
        f.writeLabel("Hello");
    }
}

FrameTest.java: (This class will show the JFrame and create a new instance of class Test to call buttonPress()):

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class FrameTest {

    private JPanel panel;
    private JLabel lblLabel;
    private JFrame frame;

    private void initComponents() {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

        panel = new JPanel();
        panel.setBorder(new EmptyBorder(5, 5, 5, 5));
        panel.setLayout(new BorderLayout(0, 0));

        lblLabel = new JLabel("LABEL");
        panel.add(lblLabel, BorderLayout.CENTER);

        JButton btnNewButton = new JButton("Press");
        btnNewButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Test t = new Test();
                t.buttonPress();
            }
        });

        panel.add(btnNewButton, BorderLayout.WEST);

        frame.add(panel);

        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public void writeLabel(String k) {
        this.lblLabel.setText(k);
    }

    void mainScreen() {
        initComponents();
    }
}



回答2:


Pass your FrameTest object to the buttonpress method and use it there, instead of creating a new object:

public void buttonpress(FrameTest f) {
     f.writeLabel("Button was pressed");    
}

Change the invocation of the method like so:

btnNewButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        Test t = new Test();
        t.buttonpress(FrameTest.this);
    }
});

You have to use FrameTest.this here, as you're inside of an anonymous class implementing ActionListener, so the normal this would reference to that anonymous class.




回答3:


- Well the first approach is using Composition Principle, where you create an instance of FrameTest.java in Test.java class and then access the Label (use Getter Setters for this label in FrameTest) in FrameTest.java class using this instance.

- Second approach is a dirty and quick fix one, make the Label static in FrameTest.java class and directly set the value from Test.java class. Voila its done.....

- The reason your code is not working, cause you have created a very new instance of the FrameTest class. So now you either pass the FrameTest Object Reference Variable to buttonpress() method or make the label static.

Eg:

public class FrameTest extends JFrame {

private JPanel contentPane;
public static JLabel lblLabel;

.....

.....

}

Or

public void buttonpress(FrameTest f) {
     f.writeLabel("Button was pressed");    
}

/////////////////////////// Edited Part ///////////////////////////////////

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

class FrameTest extends JFrame {

    private JPanel contentPane;
    private JLabel lblLabel;
    private FrameTest ft = this;

    public void mainScreen() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {

                    FrameTest frame = ft;
                    frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void writeLabel(String k) {
        this.lblLabel.setText(k);

    }

    public FrameTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setExtendedState(JFrame.MAXIMIZED_BOTH);

        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        lblLabel = new JLabel("LABEL");
        contentPane.add(lblLabel, BorderLayout.CENTER);

        JButton btnNewButton = new JButton("Press");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Test t = new Test();

                t.buttonpress(FrameTest.this); // Passing the current object to
                                                // the Test class
                                                // You can use just "this" , but
                                                // as we are in an Anonymous
                                                // Inner Class here,
                                                // we have to use
                                                // "Class_name.this"

            }
        });
        contentPane.add(btnNewButton, BorderLayout.WEST);
        // pack();
        setLocationByPlatform(true);
    }

}

public class Test {

    public static void main(String[] args) {

        FrameTest f = new FrameTest();
        f.mainScreen();

    }

    public void buttonpress(FrameTest f) { // Receiving the reference to the
                                            // current frame, but remember
                                            // THOUGH IT SEEMS that we are passing the
                                            // reference but still in
                                            //  Here and in Java its always pass
                                            // by copy.( ie pass by value).

        f.writeLabel("Button was pressed");

    }
}



回答4:


Just change your Test class like below

package com.test;

public class Test {

    private static FrameTest f;

    public static void main(String[] args) {

        f = new FrameTest();
        f.mainScreen();

    }

    public void buttonpress() {
        f.writeLabel("Button was pressed");
    }
}

The actual problem was

  1. You created a FrameTest variable f in main and shown the UI to user.
  2. Then on button press you again created another FrameTest instance f, which does not map the original/first f

Now i treat the variable as a class variable and it works as expected



来源:https://stackoverflow.com/questions/13487913/adding-text-to-a-label-from-another-class-simple-logic-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!