[英]How to change a JLabel with a button from another class?
我有两个类和一个文本文件数据库,第一个类中的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 方法来将新 String推送到其中。
我们作为志愿者回答者遇到的一个问题是,您的问题很难回答,因为它缺少关键代码,这使我们很难猜测为什么您的代码行为不端,特别是为什么当您遇到 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方法,它允许其他类设置ButtonTextFieldClass
用适当的LabelClass实例。
例如,
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 设为私有,并为该类提供了一个公共 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,因为它就像类固醇上的超级 ActionListener。 在其中,我会从 JTextField 获取文本,然后调用 LabelClass 的 setter 方法(如果变量不为 null)来设置标签的文本:
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
if (labelClass != null) {
labelClass.setLabelText(text);
}
}
然后要设置所有内容,在另一个类中,我将创建LabelClass
和ButtonTextFieldClass
实例,然后通过调用 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 中而另一个在 JDialog 中,它也可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.