【问题标题】:Methods from external class accessible but GUI Components not外部类的方法可访问但 GUI 组件不可访问
【发布时间】:2015-05-20 03:01:14
【问题描述】:

我的 Java GUI 有一个奇怪的问题。

我可以从另一个类访问主类中的方法,但我无法访问 Swing 组件。

让我告诉你我是如何构建整个东西的

主类:

public class GUI extends JFrame {
static Code c = new Code();
static Draw panel = new Draw();

JTextArea codelog;
JLabel lblFile;
...
...

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

                GUI frame = new GUI();
                frame.create();


        }
    });

}

public void create() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(1280,720);
    ...
    ...
    contentPane = new JPanel();

    setContentPane(contentPane);
    contentPane.setBackground(Color.DARK_GRAY);
    GridBagLayout gbl_contentPane = new GridBagLayout();

    setResizable(false);

    ...
    ...

    panel.setBackground(Color.BLACK);
    gbc_panel.fill = GridBagConstraints.BOTH;
    gbc_panel.gridx = 1;
    gbc_panel.gridy = 1;
    contentPane.add(panel, gbc_panel);

    codelog = new JTextArea();
    codelog.setEditable(true);
    JScrollPane scrollPane_1 = new JScrollPane(codelog);
    codelog.setLineWrap(true);
    scrollPane_1.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    codelog.setVisible(true);
    scrollPane_1.setVisible(true);
    GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
    gbc_scrollPane_1.gridheight = 2;

    gbc_scrollPane_1.gridwidth = 4;

    gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
    gbc_scrollPane_1.gridx = 8;
    gbc_scrollPane_1.gridy = 1;
    contentPane.add(scrollPane_1, gbc_scrollPane_1);

    ...
    ...

}

public void refresh(){
        panel.repaint();
}

}

我使用static Code cstatic Draw panel 来避免多个实例,因为我还必须在其他类中创建主类的对象。

另一个名为 Code 的类

public class Code {

...
...
static GUI g = new GUI();
String test;
...
...

public void hpgl(){

g.codelog.append(test); // gives me nullPointerException !!
g.refresh   // works

...
...

}

}

问题是我可以从其他类(例如代码)访问主类(GUI)的方法,但我无法访问组件(例如 JTextArea)。

主类中的refresh() 方法证明了这一点。我可以访问方法,并且在主类中 repaint() 有效。但是,如果我尝试使用 GUI.panel.repaint() 从另一个类重新绘制它将不起作用,因为在这种情况下我会直接从代码类访问 panel

JTextArea 也是如此。我正在尝试从代码中附加codelog,但它不会让我这样做。如果我在主类中创建一个附加文本区域的方法,然后从代码类调用该方法,它就可以工作。但是使用 g.codelog.append(test) 会给我一个 Java 空指针异常

所以我可以访问方法,但不能访问 Swing 组件。

你们能帮帮我吗?我不想在主类中为我要修改的每个 Swing 组件编写额外的方法。

谢谢

【问题讨论】:

    标签: java swing class methods


    【解决方案1】:

    屏幕上可见的 UI 与您在 Code 类中创建的 UI 不同。如果您希望 Code 能够访问 UI 属性,则需要将 GUI 的引用传递给它。

    话虽如此,我还是建议将 UI 组件直接暴露给任何类,而是提供 getter 和 setter(如果适用)来提供对所管理信息的访问。这可以防止 rouge 类对其应该被允许做的 UI 进行更改(如删除组件)

    根据您的操作,Observer Pattern 可能是更好的选择,Code 会在它可能对更改感兴趣时由GUI 通知。如果通过使用interfaces 来完成,这将减少您的类之间的耦合并使其更加灵活

    注意static 不是提供跨对象通信的机制,应尽可能避免使用,尤其是在像 GUI 这样动态的东西中。

    【讨论】:

    • 您说,我需要将 GUI 的引用传递给代码。我认为这正是我写g.codelog.append 所做的事情。我认为g. 就是这样。嗯...
    【解决方案2】:

    我能够按照 MadProgrammer 的建议解决问题。

    这是我改变的。

    我有 3 个课程:

    Main Class
    
    Draw
    
    Code
    

    主类

    public class GUI extends JFrame {
    
        Draw panel = new Draw(this);
        Code c = new Code(this);
        ...
        ...
    }
    

    代码类

    public class Code {
    
        private GUI g;
        private Draw b;
    
    public Code(GUI g){
        this.g = g;
    }
        ...
        ...
    }
    

    绘图类

    public class Draw extends JPanel{
    
        private GUI x;
        private Code c;
    
    public Draw(GUI x){
        this.x = x;
    }
        ...
        ...
    }
    

    我删除了所有的静态声明。它现在正在工作。我现在可以访问主类中的 Swing 组件了。

    这是专业的方法吗?或者还有改进的余地。这是我第一次使用传递引用的方式来做到这一点。到目前为止,我一直使用静态对象。

    谢谢

    【讨论】:

      猜你喜欢
      • 2012-01-04
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 2015-12-07
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多