2012-04-12 73 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