【问题标题】:How to access Variable in Main class from another class如何从另一个类访问主类中的变量
【发布时间】:2021-08-09 01:58:21
【问题描述】:

我正在使用我的主类作为我正在处理的程序的 UI,而在另一个类中,我有一个循环运行,直到它失去网络连接。 说字段:

lastCrashField = new JLabel("",SwingConstants.CENTER);
    lastCrashField.setBounds(80,180,200,30);
    lastCrashField.setBorder(blackLine);

totalCrashField = new JLabel("",SwingConstants.CENTER);
    totalCrashField.setBounds(80,240,200,30);
    totalCrashField.setBorder(blackLine);

我如何从不同的类更新 UI 中的这两个字段,现在已经环顾了一段时间,到目前为止,我一直在思考一个空白,也许我需要重新考虑我从他们的字段中处理这些字段的方式基地...

【问题讨论】:

标签: java


【解决方案1】:

你说:

如何从另一个类访问主类中的变量

要直接回答您的问题,请选择以下方法之一:

  • 将对每个字段的引用作为参数传递给另一个类的对象的方法。
  • 创建两个 JLabel 小部件的实例成员。将它们标记为非private 以供其他类的对象直接访问。

第一个项目符号的代码。

public class CollisionForm extends … 
{
    // Member fields
    private JLabel lastCrashField, totalCrashField ;

    // In constructor, populate those two field references.
    …

    // Pass references to each of the two fields to your logic method doing some work to produce fresh data.
    void whatever() 
    {
        SomeHelperObject someHelperObject = new SomeHelperObject() ;
        someHelperObject.updateCrashFields( lastCrashField , totalCrashField ) ;
    }
}

public class SomeHelperClass
{
    // Passing two references to JLabel objects.
    void someLogic( JLabel lastCrash , JLabel totalCrash ) 
    {
        lastCrash.setText( … ) ;
        totalCrash.setText( … ) ;
    }
}

第二个项目符号的代码。

public class CollisionForm extends … 
{
    // Member fields
    public JLabel lastCrashField, totalCrashField ;  // Public, not private.

    // In constructor, populate those two field references.
    …

    void whatever() 
    {
        SomeHelperObject someHelperObject = new SomeHelperObject( this ) ;  // Pass instance of Swing form (or controller) to the helper class constructor.
        someHelperObject.updateCrashFields() ;
    }
}

public class SomeHelperClass
{
    // Member fields
    CollisionForm form ;

    // Receiving instance of `CollisionForm` in the constructor of this class.
    SomeHelperClass( CollisionForm collisionForm ) 
    {
        this.form = collisionForm ;
    }

    void someLogic() 
    {
        this.form.lastCrashField.setText( … ) ;
        this.form.totalCrashField.setText( … ) ;
    }
}

但是我不推荐使用这些方法中的任何一种来处理 Swing 小部件。继续阅读。

你说:

UI 中来自不同类的 2 个字段

通常您应该让其他类直接操作您的 GUI 小部件。

最好让包含/管理小部件的对象(GUI 布局对象或控制器对象)请求其他类来工作。任何结果数据都应返回到布局/控制器,然后更新小部件。

public class CollisionForm extends … 
{
    // Member fields
    private JLabel lastCrashField, totalCrashField ;  

    // In constructor, populate those two field references.
    …

    void whatever() 
    {
        SomeHelperObject someHelperObject = new SomeHelperObject() ;  // Passing nothing about widgets. This other class remains blissfully ignorant of anything related to Swing.
        List< Integer > freshCrashData = someHelperObject.someLogic() ;
        this.lastCrashField.setText( freshCrashData.get( 0 ) ) ;
        this.totalCrashField.setText( freshCrashData.get( 1 ) ) ;
    }
}

// This version of our `SomeHelperClass` class knows nothing about Swing nor the widgets on our form.
public class SomeHelperClass
{
    List< Integer > someLogic()  // <-- Instead of `void`, return data
    {
        return List.of(
            … ,  // Last crash data.
            …    // Total crash data.
        );       // The calling method on the Swing form uses this data in this returned `List` to update its own widgets. 
    }
}

提示:在 Java 16+ 中,我将使用新的 record 功能来定义一个类,该方法将返回其实例,而不是笨拙的模棱两可的 List

你说:

我有一个循环运行,直到它失去网络连接

这听起来像是您在使用后台线程。

注意:切勿从其他线程访问您的 Swing 小部件。使用“SwingWorker”类,后台线程通过该类要求 Swing 自己的 UI 线程更新其小部件。

Stack Overflow 上已经广泛介绍了 Swing 线程。因此,搜索此站点以了解更多信息。并阅读 Oracle 的 concurrency with Swing 教程。

【讨论】:

  • 在写完这篇文章并安顿下来(显然)之后,我实际上想到了前两个选项,但由于某种原因,我无法在 main 方法之外编写 JLabels(看看你的例子是可能的,现在我也在管理,所以不确定我昨晚在尝试什么)。正如我现在可以做到的那样,我想我会在 UI 类中使用适当的 Set 方法来解决这个问题,该方法将正确处理它,而不是与其他对象跳来跳去。不过感谢您提供有用的材料!
猜你喜欢
  • 2013-10-25
  • 2017-02-24
  • 2014-07-06
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 2011-10-22
  • 2023-04-07
相关资源
最近更新 更多