更新 Swing JTextField

发布于 2024-12-15 10:06:11 字数 2373 浏览 3 评论 0原文

我无法在创建 gui 的类之外对 JTextField 进行 .setText(...) 。我很困惑,我觉得我缺少一些基本的东西。我这里需要一些帮助。

这就是我正在做的事情:

在一个类(称为 MainClass)中,我创建一个类的实例,该实例

TestText gui = new TestText();

使用设置默认设置的构造函数(一个 JTextField和一个带有监听器的按钮)。然后我调用我编写的 setter,向其传递一个字符串来设置 JTextField 的文本:

gui.setText("new");

但是 "new" 没有显示在图形用户界面。

我知道我的 setter 在类中工作,因为如果我从在 gui 中创建的按钮调用 setter,则更改会显示在 gui 上。

真正让我困惑的部分是:如果我在 setter 之前调用 getter,那么它会返回旧值。然后,如果我在调用 setter 后再次调用 getter,那么它会返回新值,而 gui 继续显示旧值。我想也许它只是没有重新绘制 gui,所以我尝试了 .invalidate().validate().update( ).repaint(),全部来自 MainClass 和 setter 内部。但没有人采取任何行动。

有没有可能我有 2 个不同的 gui 实例,而我只编辑其中一个?

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestText {
    private JTextField textField;
    private JButton button;
    private JPanel frame;
    JFrame jFrame;
    public void setText(String text) {
        textField.setText(text);
    }
    public String getText() {
        return textField.getText();
    }
    public TestText() {
        this.textField.setText("98.6");
        this.jFrame = new JFrame("TestText");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setText("new (button)");
            }
        });
    }
    public void setData(TestText data) {
        data.setText("new (setData)");
    }
    public void getData(TestText data) {
    }
    public boolean isModified(TestText data) {
        return false;
    }
    public void createGui(String[] args) {
        jFrame.setContentPane(new TestText().frame);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.pack();
        jFrame.setVisible(true);
    }
}

然后这是我试图从中创建 gui 的主类:

public class MainClass {

    public static void main(String[] args) {

        TestText gui = new TestText();
        gui.createGui(null);

        System.out.println(gui.getText());
        gui.setData(gui);
        System.out.println(gui.getText());
        gui.setText("new (MainClass)");
        System.out.println(gui.getText());
    }

}

I can't .setText(...) for a JTextField outside of the class that creates the gui. I'm very confused and I feel like there is something basic I am missing. I need some help here.

Here is what I am doing:

In a class (called MainClass) I create an instance of a class that creates my gui

TestText gui = new TestText();

with a constructor that sets the default settings (a JTextField and a button with a listener). Then I call the a setter that I wrote, where I pass it a string that is to set the text of the JTextField:

gui.setText("new");

But "new" doesn't show up on the gui.

I know my setter works from within the class because if I make a call to the setter from the button that I created in gui then the changes show up on the gui.

The part that really confuses me is this: If I call my getter just before my setter, then it returns the old value. Then if I call the getter again after I call the setter then it returns the new value, while the gui continues to show the old value. I thought that maybe it just isn't repainting the gui so I tried all kinds of permutations of .invalidate(), .validate(), .update() and .repaint(), all from the MainClass and from inside the setter. But none did anything.

Is it possible that I somehow have 2 different instances of the gui and I'm only editing one of them?

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestText {
    private JTextField textField;
    private JButton button;
    private JPanel frame;
    JFrame jFrame;
    public void setText(String text) {
        textField.setText(text);
    }
    public String getText() {
        return textField.getText();
    }
    public TestText() {
        this.textField.setText("98.6");
        this.jFrame = new JFrame("TestText");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setText("new (button)");
            }
        });
    }
    public void setData(TestText data) {
        data.setText("new (setData)");
    }
    public void getData(TestText data) {
    }
    public boolean isModified(TestText data) {
        return false;
    }
    public void createGui(String[] args) {
        jFrame.setContentPane(new TestText().frame);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.pack();
        jFrame.setVisible(true);
    }
}

and then here's the main class that I'm trying to create the gui from:

public class MainClass {

    public static void main(String[] args) {

        TestText gui = new TestText();
        gui.createGui(null);

        System.out.println(gui.getText());
        gui.setData(gui);
        System.out.println(gui.getText());
        gui.setText("new (MainClass)");
        System.out.println(gui.getText());
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

£烟消云散 2024-12-22 10:06:11

我认为您似乎缺少对文本字段的引用...

gui.referenceToTextField.setText("new word");

编辑:非常好的 SSCCE!然而,存在几个问题(不一定按照提供的顺序)。

  1. 您正在重写 setText() 方法。除非您希望该方法执行不同的操作,否则不要这样做 - 我不知道您为什么要这样做。

  2. 您甚至没有在 createGui() 方法中使用 args 数组。您可以在不指定任何参数/参数的情况下创建方法。

  3. getData() 方法现在毫无用处(如果我是你,考虑到你想要完成的任务,我会完全删除该方法)。我假设,从 apt 方法名称(另一件好事),您想要从文本字段检索数据。将此行放入方法中(并将单词 void 更改为 String),您就应该设置好了!

    return textField.getText();
    
  4. 说实话,由于 NullPointerException,这甚至不应该运行。您没有初始化 JFrame 之外的任何组件。您需要执行诸如 textField = new JTextField(20) 之类的操作。

  5. 即使您可以运行它,该按钮也根本无法工作,因为该按钮没有被告知它可以执行任何操作。为此,请调用 button.addActionListener(),并将侦听类的名称作为参数。如果 GUI 和监听类碰巧在一个类中(就像我将在一分钟内向您展示的那样),则参数只是 this

  6. 您没有向框架添加任何组件。对于要放入框架中的每个组件,您必须调用 add(Component cmpt)


Having said this, I think I'm just going to try to recreate what you're trying to do here into one class. You don't really need two separate classes unless the listening portion is excessively long.


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TestText extends JFrame implements ActionListener {
    JTextField textField = new JTextField(20);
    JButton set = new JButton("Set Text");
    JButton get = new JButton("Get Text");

    public TestText() {
        super();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(textField);
        set.addActionListener(this); //this tells the program that the button actually triggers an event
        add(set);
        get.addActionListener(this);
        add(get);
        pack();
        setVisible(true);
    }

    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == set) {
            textField.setText(JOptionPane.showInputDialog(null, "Enter a new word for the text field:"));
        } else {
            System.out.println(textField.getText());
        }
    }

    public static void main(String[] args) {
        TestText tt = new TestText();
    }
}

It looks like you're missing the reference to the text field I think...

gui.referenceToTextField.setText("new word");

EDIT: Very nice SSCCE! However, there are several problems (not in the order provided, necessarily).

  1. You are overriding the setText() method. Don't do this unless you want the method to do something different—why you would want to do this I have no idea.

  2. You aren't even using the args array in the createGui() method. You can create methods without specifying any parameters/arguments.

  3. The getData() method is, right now, useless (If I were you, given what you're trying to accomplish, I would remove the method entirely). I'm assuming, from the apt method name (another good thing to do), that you want to retrieve the data from the text field. Put this line inside the method (and change the word void to String) and you should be set!

    return textField.getText();
    
  4. Truthfully, this shouldn't even run due to a NullPointerException. You aren't initializing any of the components other than the JFrame. You need to do things like textField = new JTextField(20).

  5. Even if you could run this, the button wouldn't work at all because the button hasn't been told that it does anything. To do this call button.addActionListener() with the name of the listening class as the argument. If the GUI and listening classes happen to be in one class together (like I will show you in a minute), the argument is simply this.

  6. You aren't adding any components to the frame. For every component you wish to put into your frame, you must call add(Component cmpt).


Having said this, I think I'm just going to try to recreate what you're trying to do here into one class. You don't really need two separate classes unless the listening portion is excessively long.


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TestText extends JFrame implements ActionListener {
    JTextField textField = new JTextField(20);
    JButton set = new JButton("Set Text");
    JButton get = new JButton("Get Text");

    public TestText() {
        super();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(textField);
        set.addActionListener(this); //this tells the program that the button actually triggers an event
        add(set);
        get.addActionListener(this);
        add(get);
        pack();
        setVisible(true);
    }

    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == set) {
            textField.setText(JOptionPane.showInputDialog(null, "Enter a new word for the text field:"));
        } else {
            System.out.println(textField.getText());
        }
    }

    public static void main(String[] args) {
        TestText tt = new TestText();
    }
}
作妖 2024-12-22 10:06:11

经过一些阅读后,我认为这是由于我的代码没有像 @camickr 建议的那样访问事件调度线程。 这里有一些文档帮助我解决了我的问题。

After doing some reading I think it is due to my code not accessing the Event Dispatch Thread like @camickr suggested. Here is some documentation that helped me solve my problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文