2012-04-12 75 views
2

我有主JPanel(在JApplet中)包含子JPanel和按鈕。我想單擊該按鈕,將JPanel刪除,並將另一個子JPanel添加到主JPanel,但問題是隻有當我重新點擊該按鈕或調整JApplet的大小時,第二個子JPanel纔會出現。重繪JPanel不能在JApplet中工作

我的按鈕的監聽器:

button.addActionListener(new ActionListener(){ 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      panel.remove(custompanel); 
      panel.add(new CustomPanel("/hinhtu2.jpg"), BorderLayout.CENTER); 
      panel.repaint(); 
      panel.revalidate(); 

     } 
     }); 

我的整個代碼:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.BorderFactory; 
import javax.swing.ImageIcon; 
import javax.swing.JApplet; 
import javax.swing.JButton; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class applet extends JApplet { 
    public void init() { 

    try { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createGUI(); 
      } 
     }); 
    } catch (Exception e) { 
     //System.err.println("createGUI didn't successfully complete"); 
     e.printStackTrace(); 
    } 
} 

private void createGUI() { 
    final JPanel panel = new JPanel(new BorderLayout()); 
    JButton button = new JButton("CLICK ME"); 
    panel.add(button, BorderLayout.SOUTH); 
    final CustomPanel custompanel = new CustomPanel("/hinhtu.jpg"); 
    panel.add(custompanel, BorderLayout.CENTER); 

    button.addActionListener(new ActionListener(){ 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      panel.remove(custompanel); 
      panel.add(new CustomPanel("/hinhtu2.jpg"), BorderLayout.CENTER); 
      panel.repaint(); 
      panel.revalidate(); 

     } 

     }); 

    add(panel); 
    } 

public class CustomPanel extends JPanel{ 
    String resource; 
    public CustomPanel(String resource){ 
     super(); 
     this.resource = resource; 



    } 
    public void paintComponent(Graphics g) { 



     Image x = Toolkit.getDefaultToolkit().getImage(getClass().getResource(resource)); 
     g.drawImage(x, 0, 0, null); 

    } 



} 

}

我的屏幕記錄:http://www.screenr.com/prx8

+1

你能否解釋一下,到底爲什麼你需要這個形象雖然,爲什麼不把這個圖像是'JLabel',然後將其添加到'JPanel',而且,裝載圖像JApplets必須始終在一個單獨的線程中完成的,正如[Java文檔]中所述(http://docs.oracle.com/javase/tutorial/uiswing/components/applet.html#images)。 +1,這個東西讓我今天學到了一些東西:-) – 2012-04-12 07:55:30

+1

1)*「我的整個代碼:」*爲了更快地提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。該代碼沒有進口,我們在這裏沒有'hinhtu2.jpg'。 2)請注意使用代碼格式時,錯過了一個關閉'}'3)繪製方法仍然會犯與上一個問題相同的錯誤。 4)而不是刪除組件,使用'CardLayout'。 5)如果你描述了這個applet的作用和你試圖達到的最終效果,那會更好,因爲'你實現事物的方式'通常'非常不理想'。 – 2012-04-12 08:12:10

+0

@AndrewThompson:1.我編輯了這個問題,hinhtu2.jpg被添加到我的java類文件的相同路徑中。3.你能告訴我我面臨的錯誤嗎? 5.我只是從小程序開始,所以這只是一個嘗試:)。 – 2012-04-12 08:21:13

回答

4

你應該調用revalidate再重繪此之前:

 panel.remove(custompanel); 
     panel.add(new CustomPanel("/hinhtu2.jpg"), BorderLayout.CENTER); 
     panel.repaint(); 
     panel.revalidate(); 

重新驗證調用更新容器層次結構以及可能需要重繪後。容器大小調整可以同時進行(重新驗證和重新繪製),這就是調整小程序後面板出現的原因。

此外,我注意到,在上你的代碼1個壞事:

public void paintComponent(Graphics g) { 
    Image x = Toolkit.getDefaultToolkit().getImage(getClass().getResource(resource)); 
    g.drawImage(x, 0, 0, null); 
} 

您正在加載圖像每個時候你的自定義組件進行重新繪製。更好地將圖片加載到構造函數中並加載一次。

+0

重新驗證之前重新繪製不起作用.. – 2012-04-12 07:39:52

+1

你想添加面板只是一次或每個按鈕點擊?因爲你的代碼只會做一次 - custompanel將始終具有舊的第一個面板值...還有一個瘋狂的猜測 - 您的paintComponent方法可能不會加載image @ first call,這將導致它僅在第二次/第三次重新繪製後「顯示」。看看是否有幫助 – 2012-04-12 07:46:04

+0

這似乎很奇怪,當我在另一臺電腦的瀏覽器中訪問小程序時,點擊按鈕效果不錯... – 2012-04-12 08:10:35