将文本添加到另一个类的标签 – 简单逻辑问题
我在一个名为FrameTest
的类中有一个标签和一个按钮,当我按下按钮时,一个名为buttonpressed
的方法从类Test
执行。 在这个buttonpressed
方法中,我将设置文本到FrameTest
类中找到的标签。
我遇到的问题是,标签的文本没有设置。 原因是我正在创建一个单独的对象来调用buttonpressed
方法;
public void actionPerformed(ActionEvent arg0) { Test t = new Test(); t.buttonpress(); }
我正在Test
类的main方法中创建一个单独的对象来创建UI。
public static void main(String[] args) { FrameTest f = new FrameTest(); f.mainScreen(); }
完整代码如下;
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); } }
测试类
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)不要不必要地扩展JFrame
类。
2)不要使用setContentPane()
除非那就是你想要的。 而只是简单的JFrame#add(..)
。
3)避开EventQueue
并使用SwingUtilities
块
4)别忘了调用JFrame#pack();
在设置JFrame
之前可见。
5)Java命名约定是CamelCase所以buttonPress()
是正确的而不是buttonpress()
这是我做的一个例子(基本上你的代码是固定的):
Test.java 🙁这是将创建FrameTest
实例并具有更改JLabel
文本的方法的主类)
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 🙁这个类将显示JFrame
并创建一个新的类Test
实例来调用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(); } }
将FrameTest对象传递给buttonpress方法并在那里使用它,而不是创建一个新对象:
public void buttonpress(FrameTest f) { f.writeLabel("Button was pressed"); }
像这样更改方法的调用:
btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Test t = new Test(); t.buttonpress(FrameTest.this); } });
你必须在这里使用FrameTest.this
,因为你在一个实现ActionListener的匿名类中,所以通常this
将引用该匿名类。
–第一种方法是使用Composition
Principle,在Test.java class
创建FrameTest.java
实例 ,然后使用此实例访问FrameTest.java
Test.java class
的Label
(在FrameTest中使用此标签的Getter Setters)。
–第二种方法是脏而快速修复,在FrameTest.java
类中使Label
static
并直接从Test.java
类设置值。 瞧它完成了……
–您的代码无法工作的原因,因为您已经创建了一个非常新的FrameTest class
实例。 所以现在要么将FrameTest
对象引用变量传递给buttonpress()
方法,要么将label
静态 。
例如:
public class FrameTest extends JFrame { private JPanel contentPane; public static JLabel lblLabel; ..... ..... }
要么
public void buttonpress(FrameTest f) { f.writeLabel("Button was pressed"); }
///////////////////////////编辑部分///////////////////// //////////////
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"); } }
只需更改您的Test
类,如下所示
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"); } }
实际问题是
- 您在main中创建了一个
FrameTest
变量f
,并向用户显示了UI。 - 然后按下按钮再次创建另一个
FrameTest
实例f
,它不映射原始/第一个f
现在我将变量视为类变量,它按预期工作