Java 通过EventListener-Swing调用repaint()和/或revalidate()

Java 通过EventListener-Swing调用repaint()和/或revalidate(),java,swing,jframe,jbutton,repaint,Java,Swing,Jframe,Jbutton,Repaint,最近我的秋千有些问题。我正在创建一个项目,该项目需要经常在JFrame和JPanel中编辑内容(在本例中,是JButton上显示的字符串),并希望掌握如何进行编辑 我搜索了很长时间,找到的主要答案是我需要调用.repaint(),可能是在调用.revalidate()之后。但是,我无法使代码正常运行 现在,框架将按其应该的方式开始绘制,但按下按钮后,框架内的文本不会改变-事实上,它会生成一个较大的错误日志,可在此处查看: 下面是我的代码: import javax.swing.*; import

最近我的秋千有些问题。我正在创建一个项目,该项目需要经常在JFrame和JPanel中编辑内容(在本例中,是JButton上显示的字符串),并希望掌握如何进行编辑

我搜索了很长时间,找到的主要答案是我需要调用.repaint(),可能是在调用.revalidate()之后。但是,我无法使代码正常运行

现在,框架将按其应该的方式开始绘制,但按下按钮后,框架内的文本不会改变-事实上,它会生成一个较大的错误日志,可在此处查看:

下面是我的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Actions extends JFrame implements ActionListener
{
    JButton Beans;
    String String1;
    JPanel things;

    public static void main (String[] args)
    {
        new Actions();
    }

    public Actions()
    {
        JPanel things = new JPanel();
        String1 = "Beans";

        this.setSize(400,400);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("Hello there");

        Box theBox = Box.createHorizontalBox();

        Beans = new JButton("" + String1);
        Beans.addActionListener(this);

        theBox.add(Box.createHorizontalStrut(50));
        theBox.add(Beans);

        this.add(theBox);

        setVisible(true);
    }

    public void actionPerformed(ActionEvent e)
    {
        String1 = "Surprise!";
        things.revalidate();
        things.repaint();
    }
}
所以,为了澄清,我有一个JButton,在JPanel中,在JFrame中。按钮本身显示一个字符串,该字符串最初读取“bean”。当我按下按钮时,我希望字符串现在显示为“惊喜!”


谢谢你抽出时间

您的问题是将对象与引用变量混淆,认为更改String1的文本会神奇地导致JButton显示的文本发生更改,但Java的OOP模型不是这样工作的。请理解JButton正在显示一个String对象,即String1最初引用的同一对象,但是当您更改String1引用的字符串时,这对原始String对象没有影响。要更改显示的字符串,必须通过调用JButton的
setText(…)
方法更改JButton显示的字符串对象,并将新字符串传递给它。这是唯一可行的办法

public void actionPerformed(ActionEvent e) {
    Beans.setText("Surprise!");
}
见评论:

// here are several reference variables
// all without assigned objects, and thus
// all holding "null" values:
JButton Beans;
String String1;
JPanel things;


public Actions()  {
    //..... 

    // here you assign the String object, "Beans" to the String1 variable
    String1 = "Beans";

    // .....

    // here you create a JButton and pass in String1's current object, "Beans"
    // into the constructor (note the "" + is NOT needed for Strings, only for numberrs)
    Beans = new JButton("" + String1);

    //.....
}

public void actionPerformed(ActionEvent e)  {
    // here you change the object that String1 refers to
    String1 = "Surprise!";

    // but this has no effect on the original String object, "Beans" displayed in the
    // JButton, but rather all it does is change the state of String1. 
    // To change the state of the JButton, you must explicitly do this 
    // by calling setText on it

    //....

作为旁白,你需要学习和使用。变量名都应该以小写字母开头,而类名应该以大写字母开头。学习这一点并遵循这一点可以让我们更好地理解您的代码,也可以让您更好地理解其他人的代码

另请注意#2:如果您确实绘制了字符串,那么您的原始代码就可以工作了。注意:在下面的代码中,我有一个字符串变量,
currentString
,它最初指的是字符串数组中的第一项,
text
,字符串
“One”
。在JButton的ActionListener中,我更新了名为
index
的数组索引变量,并将
currentString
变量设置为数组中的下一个字符串项,然后调用
repaint()
。此代码之所以有效,是因为我在JPanel的绘制方法中绘制由
currentString
保存的文本,
paintComponent(…)


您的问题是将对象与引用变量混淆,认为更改String1的文本会神奇地导致JButton显示的文本发生更改,但Java的OOP模型不是这样工作的。请理解JButton正在显示一个String对象,即String1最初引用的同一对象,但是当您更改String1引用的字符串时,这对原始String对象没有影响。要更改显示的字符串,必须通过调用JButton的
setText(…)
方法更改JButton显示的字符串对象,并将新字符串传递给它。这是唯一可行的办法

public void actionPerformed(ActionEvent e) {
    Beans.setText("Surprise!");
}
见评论:

// here are several reference variables
// all without assigned objects, and thus
// all holding "null" values:
JButton Beans;
String String1;
JPanel things;


public Actions()  {
    //..... 

    // here you assign the String object, "Beans" to the String1 variable
    String1 = "Beans";

    // .....

    // here you create a JButton and pass in String1's current object, "Beans"
    // into the constructor (note the "" + is NOT needed for Strings, only for numberrs)
    Beans = new JButton("" + String1);

    //.....
}

public void actionPerformed(ActionEvent e)  {
    // here you change the object that String1 refers to
    String1 = "Surprise!";

    // but this has no effect on the original String object, "Beans" displayed in the
    // JButton, but rather all it does is change the state of String1. 
    // To change the state of the JButton, you must explicitly do this 
    // by calling setText on it

    //....

作为旁白,你需要学习和使用。变量名都应该以小写字母开头,而类名应该以大写字母开头。学习这一点并遵循这一点可以让我们更好地理解您的代码,也可以让您更好地理解其他人的代码

另请注意#2:如果您确实绘制了字符串,那么您的原始代码就可以工作了。注意:在下面的代码中,我有一个字符串变量,
currentString
,它最初指的是字符串数组中的第一项,
text
,字符串
“One”
。在JButton的ActionListener中,我更新了名为
index
的数组索引变量,并将
currentString
变量设置为数组中的下一个字符串项,然后调用
repaint()
。此代码之所以有效,是因为我在JPanel的绘制方法中绘制由
currentString
保存的文本,
paintComponent(…)


“我搜索了很长一段时间,找到的主要答案是我需要调用.repaint(),可能是在调用.revalidate()之后。”
--不,在更改JButton或JLabel的文本时不需要这样做。问题出在别处。
“我搜索了很长一段时间,找到的主要答案是我需要调用.repaint(),可能是在调用.revalidate()之后。”
--不,在更改JButton或JLabel的文本时,这不是必需的。问题出在其他地方。这非常有效!并对swing进行了一些深入了解。我承认我开始使用applet,似乎一些坏习惯和错误观念已经被传承了下来。不过,谢谢你@MatthewMakaryn:这与Swing无关,与“神奇思维”有关,认为改变变量所指的内容会影响以前使用变量对象的其他对象。这再次得到了对象和引用变量之间的关键区别。我会在一分钟内更好地解释这一点,但这是一个关键概念,你需要充分理解才能继续前进。好的,谢谢。我还有很长的路要走,我很兴奋能向前迈进!我记得我在一个小程序中这样做过,并且错误地认为它在swing中工作相同。啊,好吧,向前走upwards@MatthewMakaryn
我记得在小程序中这样做过,
-它在小程序中也不起作用。是的,所以我有点傻,记错了,原来我以前的项目是用画法画字符串,