我的Java GUI有一个奇怪的问题。
我可以从另一个类访问Main Class中的Methods但我无法访问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 c
和static Draw panel
来避免多个实例,因为我还必须在其他类中创建Main类的对象。
另一个名为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
,但它不会让我这样做。如果我在Main Class中创建一个附加Textarea然后从Code Class调用Method的方法,它就能工作。但是使用g.codelog.append(test)
给了我一个Java空指针异常
所以我可以访问方法,但我无法访问Swing组件。
你能帮我吗?我不想在主类中为我想要修改的每个Swing组件编写额外的方法。
谢谢
答案 0 :(得分:0)
屏幕上显示的用户界面与您在UsedRange
课程中创建的用户界面不同。如果您希望Code
能够访问UI属性,则需要将Code
的引用传递给它。
话虽如此,我会将UI组件直接暴露给任何类,而是提供getter和setter(如果适用)以提供对所管理信息的访问。这可以防止rouge类对应该允许的UI进行更改(比如删除组件)
根据您的工作情况,Observer Pattern可能是更好的选择,GUI
会在Code
通知其可能感兴趣的内容时进行更改。如果通过使用GUI
来完成,这将减少您的类之间的耦合并使其更灵活
当心interface
不是提供跨对象通信的机制,应该尽可能避免,特别是在像GUI这样动态的东西中。
答案 1 :(得分:0)
我能够按照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;
}
...
...
}
我删除了所有静态声明。它现在正在运作。我现在可以访问Main Class中的Swing组件。
这是专业的方式吗?还是仍有改进的余地。这是我第一次使用传递参考方式来做到这一点。直到现在我总是使用静态对象。
谢谢