gpt4 book ai didi

java - 如何使用另一个类的按钮更改 JLabel?

转载 作者:行者123 更新时间:2023-12-02 05:08:03 26 4
gpt4 key购买 nike

我有两个类和一个文本文件数据库,第一个类中的JLabel,我们称之为class1,它会自动将其自身设置为数据库中的数字。现在,在 class2 中,我有这个小 JFrame 和一个文本字段,当然还有一个按钮,我在文本字段中输入的值会覆盖数据库中的值,但这里是问题。第一类中的标签在运行时不会更新,但如果我重新启动它,它会显示我想要的值。

如何在程序运行时更新它?我尝试更改另一个类中的 buttonActionperformed 中的标签,但每次都会给我一个 NullPointException

如何解决这个问题?

主类(只是 JFrame)

package BankrollG;

import java.awt.Graphics;
import javax.swing.JFrame;

public class BGbrain {

BGbody body = new BGbody();
JFrame Frame = new JFrame();

public BGbrain() {
Frame.setSize(body.width, body.height);
Frame.setTitle(body.title);
Frame.setResizable(false);
Frame.setDefaultCloseOperation(Frame.EXIT_ON_CLOSE);
Frame.add(body.panel);
Frame.setLocationRelativeTo(null);
Frame.setFocusable(true);

Frame.setVisible(true);
}

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

然后你就得到了带有组件的类:

private JLabel bankroll_label

public BGbody(){
panel.setLayout(null);
windowComponents();
}

public void windowComponents() {
// Bankroll database access
try {

FileReader fr = new FileReader("Bankroll.txt");
BufferedReader br = new BufferedReader(fr);
set_bankroll = br.readLine();

} catch(IOException e) {
System.out.println("FEL MED LÄSNING AV DATABAS /// BGBODY");
}

}
}

然后你就得到了我用 netbeans 函数创建的 JFrame 类

private void AddcurrencyActionPerformed(java.awt.event.ActionEvent evt) {

String CBR = txt_bankroll.getText();

try {
FileWriter fw = new FileWriter("Bankroll.txt");
PrintWriter pw = new PrintWriter(fw);

pw.println(CBR);
pw.close();
} catch(IOException e) {
System.out.println("FEL MED INSKRIVNINGEN I DATABASEN");
}
}

现在,一切都按计划进行,但我无法从按钮类更新我的 JLabel“bankroll_label”,因为它只返回 nullpointsexceptions。数据就在那里,因为 JLabel 从数据库读取,但当按钮类发生更改时它不会更新。因此 getter setter 方法将不起作用,因为值在那里,但它不会更新 JLabel。

我希望这能让我更容易理解我的问题。还有很多代码,与此无关,我希望我至少简化了一些。

最佳答案

你的问题是Java编程中一个基本问题的具体例子——如何在类之间传输信息。有多种方法可以做到这一点,最优雅的方法之一是使用保存程序逻辑代码和关键数据的“模型”类,让一个类通过更改它保存的文本字符串来更改模型的状态。然后使用监听器或观察者模式,让模型通知其他类它已更改,以便其他类可以从模型中提取新信息,即其新字符串。虽然这可能是最好的解决方案,但它可能有点矫枉过正,并且可能超出了您当前的编码水平,所以对于您来说,我不会推荐这个。

相反,我将推荐一种更简单、不太优雅的解决方案,即让一个类调用另一个类的 setter 方法来将新字符串插入其中。

作为志愿者回答者,我们遇到的一个问题是您的问题很难回答,因为它缺少关键代码,这使得我们很难猜测您的代码为何行为不当,为什么具体您当您尝试运行它时遇到 NullPointerException(或 NPE)。所以我所能做的就是猜测,但我想我还是会尝试。

为了简单起见,我们将一个类(保存 JLabel 的类)称为 LabelClass,将另一个类称为 ButtonTextFieldClass

一个可能的原因是您遇到 NullPointerException 是因为您的 ButtonTextFieldClass 可能有一个 LabelClass 变量,但从未初始化该变量,如下所示:

// this guy is null because it is never initialized
private LabelClass labelClass;

一个简单的解决方案可能是尝试像这样初始化它:

private LabelClass labelClass = new LabelClass();

但这不起作用,因为虽然它确实创建并分配了 LabelClass 实例,但它可能不是在运行的 GUI 中可视化的 LabelClass 实例。

更好的解决方案是为 ButtonTextFieldClass 提供一个 setter 方法,允许其他类使用正确的 LabelClass 实例设置 ButtonTextFieldClass

例如,

public void setLabelClass(LabelClass labelClass) {
this.labelClass = labelClass;
}

这样,设置两个类的代码就可以将可视化的 LabelClass 传递给第一个类,并且可以调用它的方法。

LabelClass 的一个简单示例如下所示:

class LabelClass extends JPanel {
private JLabel label = new JLabel("");

public LabelClass() {
setBorder(BorderFactory.createTitledBorder("Label Panel"));
add(label);
}

public void setLabelText(String text) {
label.setText(text);
}
}

我让它扩展了 JPanel,因为这样我就可以自由地将其放入 JFrame 或 JDialog 或其他我认为合适的 JPanel 中。请注意,我已将 JLabel 设为私有(private),并为该类提供了一个公共(public) setter 方法 setLabelText(String text),该方法允许外部类能够设置 JLabel 的文本。

ButtonTextFieldClass 可能类似于:

class ButtonTextFieldClass extends JPanel {
private JTextField textField = new JTextField(10);
private JButton button = new JButton(new ButtonAction("Send Text"));
private LabelClass labelClass;

public ButtonTextFieldClass() {
setBorder(BorderFactory.createTitledBorder("Button TextField Panel"));
add(textField);
add(button);
}

// here we allow other classes to set instances of our LabelClass
public void setLabelClass(LabelClass labelClass) {
this.labelClass = labelClass;
}

// ....

我还为按钮提供了 AbstractAction 来代替 ActionListener,因为它就像类固醇上的 super ActionListener。在其中,我将从 JTextField 获取文本,然后调用 LabelClass 的 setter 方法(如果变量不为空)来设置标签的文本:

  public void actionPerformed(ActionEvent e) {
String text = textField.getText();
if (labelClass != null) {
labelClass.setLabelText(text);
}
}

然后,为了设置所有内容,在另一个类中,我将创建 LabelClassButtonTextFieldClass 的实例,然后通过调用 setter 方法“将它们连接起来”:

  LabelClass labelClass = new LabelClass();
ButtonTextFieldClass buttonTextFieldClass = new ButtonTextFieldClass();
buttonTextFieldClass.setLabelClass(labelClass); // set our reference

整个事情可能看起来像这样:

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

public class TransferData {

private static void createAndShowGui() {
LabelClass labelClass = new LabelClass();
ButtonTextFieldClass buttonTextFieldClass = new ButtonTextFieldClass();
buttonTextFieldClass.setLabelClass(labelClass); // set our reference

JPanel mainPanel = new JPanel(new GridLayout(0, 1));
mainPanel.add(buttonTextFieldClass);
mainPanel.add(labelClass);

JFrame frame = new JFrame("TransferData");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

class LabelClass extends JPanel {
private JLabel label = new JLabel("");

public LabelClass() {
setBorder(BorderFactory.createTitledBorder("Label Panel"));
add(label);
}

public void setLabelText(String text) {
label.setText(text);
}
}

class ButtonTextFieldClass extends JPanel {
private JTextField textField = new JTextField(10);
private JButton button = new JButton(new ButtonAction("Send Text"));

// one possible solution -- give this class a variable
// of the LabelClass -- but don't initialize the variable
// here, but rather do it in a setter
private LabelClass labelClass;

public ButtonTextFieldClass() {
setBorder(BorderFactory.createTitledBorder("Button TextField Panel"));
add(textField);
add(button);
}

// here we allow other classes to set instances of our LabelClass
public void setLabelClass(LabelClass labelClass) {
this.labelClass = labelClass;
}

// an AbstractAction is like a "super" ActionListener
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name); // set the button's text and actionCommand
int mnemonic = (int) name.charAt(0); // get first char
putValue(MNEMONIC_KEY, mnemonic); // set mnemonic
}

@Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
if (labelClass != null) {
labelClass.setLabelText(text);
}
}
}
}

为了简单起见,我在同一个 GUI 中显示了两个 JPanel,但如果一个 JPanel 位于一个 JFrame 中,另一个 JPanel 位于 JDialog 中,它也可以正常工作。

关于java - 如何使用另一个类的按钮更改 JLabel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27595378/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com