2015-05-20 43 views
0

我的Java GUI有一個奇怪的問題。從外部類訪問的方法,但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避免多個實例,因爲我也有在創建主類的對象其他類。

命名代碼

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類中創建一個附加Textarea的Method,然後調用Code Class中的Method,它就可以工作。但使用g.codelog.append(test)給了我一個Java空指針異常

所以我可以訪問的方法,但我不能訪問Swing組件。

你們能幫我嗎?我不想爲每個要修改的Swing組件在主類中編寫額外的方法。

謝謝

回答

0

這是顯示在屏幕上的UI是不是你已經在你的Code類中創建相同的用戶界面。如果您希望Code能夠訪問UI屬性,則需要將GUI的引用傳遞給它。

話雖如此,我會同意將UI組件直接暴露給任何類,而不是提供getters和setters(如果適用)以提供對被管理信息的訪問。這可以防止胭脂類進行更改到它應該被允許做(比如刪除組件)

取決於你在做什麼的UI,一個Observer Pattern可能是一個更好的選擇,通過Code其中,通過GUI當事情通知它可能對變化感興趣。如果通過使用interface就辦妥了,這會降低你的類之間的耦合,使其更加靈活

謹防static不提供跨對象溝通的機制,應該避免,如果可能的話,尤其是在一些如動態的作爲GUI。

+0

你說,我需要將GUI的參考傳遞給代碼。我認爲這正是我通過編寫'g.codelog.append'所做的。我認爲'g.'就是這個意思。嗯... – Zombievirus

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; 
} 
    ... 
    ... 
} 

我刪除了所有的靜態聲明。它現在正在工作。我現在可以訪問主類中的Swing組件。

這是專業的方式嗎?還是還有改進的餘地。這是我第一次用傳遞參考的方式來做到這一點。直到現在我總是使用靜態對象。

謝謝你

相關問題