简体   繁体   中英

Methods from external class accessible but GUI Components not

I have a weird Problem with my Java GUI.

I can access the Methods in the Main Class from another Class but i cannot access the Swing Components.

Let me show you how i built the whole thing

Main Class:

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();
}

}

I am using static Code c and static Draw panel to avoid multiple instances as i also have to create Objects of the Main class in other classes.

The other Class named Code

public class Code {

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

public void hpgl(){

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

...
...

}

}

The Problem is that i can access the Methods of the Main Class (GUI) from other classes (such as Code) but i cannot access the Components (such as JTextArea).

The refresh() Method in the Main Class proves it. I can access the Method and in the Main Class the repaint() works. But if i try to repaint from another class using GUI.panel.repaint() it won't work because i would in that case access the panel directly from Code Class.

The Same goes for the JTextArea. I am trying to append codelog from Code but it won't let me do it. If i create a Method in Main Class which appends the Textarea and then call the Method from Code Class it works. But using g.codelog.append(test) gives me a Java null pointer exception

So i can access the Methods but i cannot access the Swing Components.

Can you guys please help me. I don't want to have to write an extra Method in the Main Class for every single Swing Component i want to modify.

Thank You

The UI which is visible on the screen is not the same UI you have created in your Code class. If you want Code to be able to access the UI properties, you will need to pass a reference of the GUI to it.

Having said that, I would be apposed to exposing the UI components directly to any class an instead provide getters and setters (where applicable) to provide access to the information been managed. This prevents rouge classes from making changes to the UI which it should be allowed to do (like remove components)

Depending on what you are doing, an Observer Pattern might be a better choice, where by Code is notified by GUI when something it might be interested in changes. If done through the use of interface s, this will reduce the coupling between your classes and make it more flexible

Beware static is not a mechanism for providing cross object communication and should be avoid if at all possible, especially in something as dynamic as a GUI.

I was able to solve the Problem following MadProgrammer's Suggestion.

This is what i changed.

I have 3 Classes:

Main Class

Draw

Code

Main Class

public class GUI extends JFrame {

    Draw panel = new Draw(this);
    Code c = new Code(this);
    ...
    ...
}

Code Class

public class Code {

    private GUI g;
    private Draw b;

public Code(GUI g){
    this.g = g;
}
    ...
    ...
}

Draw Class

public class Draw extends JPanel{

    private GUI x;
    private Code c;

public Draw(GUI x){
    this.x = x;
}
    ...
    ...
}

I removed all the Static declarations. It is now working. I can access the Swing Components in the Main Class now.

Is this the Professional way to do it? or is there still room for improvement. This is the first time i used the passing reference way to do it. Until now i always used static Objects.

Thank You

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM