更改JLabel的文本 - 初学者

3
我的代码;
package com.test;

import java.awt.EventQueue;

public class TestGU {

    private JFrame frame;
    private JLabel la;

    /**
     * Launch the application.
     */
    public  void mainM() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TestGU window = new TestGU();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void redefine(String text){
         la.setText(text);
    frame.repaint(); 

    }

    /**
     * Create the application.
     */
    public TestGU() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        la = new JLabel("New label");
        frame.getContentPane().add(null);
    }

}

我正在尝试从下面的主方法(这是一个单独的类)更改标签的文本:

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {

        TestGU g = new TestGU();
        g.mainM();
        g.redefine("New Value");
}
}

1.) 当执行 main 方法时,我期望标签的文本为 "New Value",但它仍然包含文本 New label。 没有任何变化,我该如何纠正这个问题?


frame.getContentPane().add(null); 无法编译。这是你真正的代码吗?另外,你的代码运行了两次 initialize,因此有两个 TestGU 对象。 - assylias
1
JLabel 也未添加到框架中。 - Adam
"null 意味着绝对布局,对吗?" 错了。它意味着在内容面板中不添加任何内容。顺便说一句 - 使用布局! - Andrew Thompson
我该如何添加绝对布局? - Sharon Watinsan
+1 是为了添加所需的代码,以便准确地找出问题所在...并且不扩展 JFrame。 ;) - Andrew Thompson
显示剩余2条评论
4个回答

6

看起来您正在创建两个 TestGU 实例,而您的 redefine 方法更改了未被显示的实例上标签的值。

现在只是检查一下我的理论....

编辑:
您不需要创建第二个实例;您的 mainM 方法应该为:

public void mainM() {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

PS - 我假设你的初始化方法实际上已经有这行代码了,对吗?

frame.getContentPane().add(la);

不要使用add(null),因为这完全不起作用。


2
请看这个例子,以获取一些想法。 TestGU
import java.awt.EventQueue;
import javax.swing.*;

public class AnotherClass {

   public static void main(String[] args) {

        Runnable r = new Runnable() {
            public void run() {
               TestGU g = new TestGU();
               g.redefine("New Value");
            }
        };
        EventQueue.invokeLater(r);
    }
}

class TestGU {

    private JFrame frame;
    private JLabel la;

    public void redefine(String text){
         la.setText(text);
    }

    /**
     * Create the application.
     */
    public TestGU() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        la = new JLabel("New label");
        frame.getContentPane().add(la);
        frame.pack();
        frame.setVisible(true);
   }
}

是的,但我想要从另一个类中更改标签的文本。 - Sharon Watinsan
1
@AndrewThompson - 别太苛刻了,至少他们没有对JFrame进行子类化。 - Qwerky
@Qwerky 实际上是“她” - Sharon Watinsan

2

永远不要使用JFrame作为顶层容器。

添加到JFrame的组件未注册以便由AWTEvent队列监听。

因此,您的setText()方法无法创建适当的事件来重绘组件。

setContentPane( new JPanel(){{ add(la); }} );

而且它将按预期工作,无需调用任何绘制/重绘方法。


1

您创建了两个 TestGU 实例(一个在 Test 中,另一个在 TestGUmainM() 中),但只有一个是可见的。请将您的 mainM() 方法更改为以下内容:

/**
 * Launch the application.
 */
public void mainM() {
    this.frame.setVisible(true);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接