2014-03-05 101 views
1

我試圖在actionListener方法中向我的JFrame添加一個JPanel,但它只在第二次點擊按鈕後纔出現。這是我的代碼的一部分,其中panCoursJPanelConstituerData目標JFrame將JPanel添加到actionListener中的contentPane

addCours.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      panCours.setBounds(215, 2, 480, 400); 
      panCours.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le cours")); 
      ConstituerData.this.getContentPane().add(panCours); 
     } 
    }); 

我不明白爲什麼我點擊按鈕不會立即出現。有關如何解決這個問題的任何解釋和幫助?

+0

看看在'actionPerformed'結尾的'JFrame'上調用'pack'是否解決了你的問題。 –

+0

這個調用解決了這個問題,但創建了另一個問題:它將我的'JFrame'的每個維度都設置爲0. – sk001

+0

@HoNoSousa - 他用外觀來看一個空佈局,所以這不會有太大的幫助。嘗試在您的JFrame或JPanel上調用repaint。 –

回答

2

您需要添加對repaint();(以及可能revalidate();)的調用才能立即顯示JPanel。下面是一個演示您的問題(和解決方案)的基本示例;

public class Test { 

    public static void main(String[] args) { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLayout(null); 

     JButton button = new JButton("Test");      
     button.setBounds(20, 30, 100, 40); 
     button.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       JPanel panel = new JPanel(); 
       panel.setBackground(Color.red); 
       panel.setBounds(215, 2, 480, 480); 
       frame.add(panel); 
       frame.revalidate(); // Repaint here!! Removing these calls 
       frame.repaint(); // demonstrates the problem you are having. 

      } 
     }); 

     frame.add(button); 
     frame.setSize(695, 482); 
     frame.setVisible(true);    

    } 
} 

上面說了,(其他人的建議),這是唯一正確的,我建議不要在將來使用null佈局。擺動佈局開始時有點尷尬,但從長遠來看,它們會幫助你很多。

+3

請不要暗示人們使用'null'佈局......這只是合適的壞建議,並引入更多的問題 – MadProgrammer

+0

謝謝,@RudiKershaw。如果我只有一個「JPanel」添加,現在是正確的。但我想根據按鈕的選擇在許多'JPanel'之間切換。使用這個解決方案,顯示的'JPanel'不是與'JButton'點擊相對應的那個。我能怎麼做 ? – sk001

+0

@MadProgrammer - 很好,我會更新我的答案來建議佈局。但一般來說,一旦有人正在進入一個項目,他們不會想要改變。建議使用佈局管理器將在未來幫助他們,但現在對他們無幫助。 –

2

答案可以在下面的代碼片段找到: 你需要revalidate()這個contentPane,而不是重畫框架。您可以像這樣將所需的任何面板添加到內容面板。如果您將contentPane聲明爲私有字段,則不需要您撥打getContentPane()。 contentPane是全球性的,因此可以直接從課程中的任何位置進行調整。 請注意NullPointerExeptions如果您在初始化之前提及它,可以拋出它。

public class testframe extends JFrame { 

private JPanel contentPane; 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       testframe frame = new testframe(); 
       frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

/** 
* Create the frame. 
*/ 
public testframe() { 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    contentPane = new JPanel(); 
    setContentPane(contentPane); 

    JButton btnNewButton = new JButton("New button"); 
    btnNewButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      JPanel a = new JPanel(); 
      contentPane.add(a); 
      contentPane.revalidate(); 
     } 
    }); 
    contentPane.add(btnNewButton); 
} 

} 
+0

http://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint - 要絕對安全,可能需要重新驗證和重新繪製。但certinaly不*只是*重新驗證。 –