2

I have the the main JPanel (in JApplet ) which containts the child JPanel and the button. I want to click the button make the child JPanel removed and another child JPanel added to the main JPanel, but the problem is that only when I reclick the button or adjust the JApplet's size the second child JPanel apprear then.

My button's listener :

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();

        }
        });

My whole code :

 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); 

    }   



}

}

My screen record : http://www.screenr.com/prx8

TU_HEO DAKAI
  • 2,197
  • 8
  • 28
  • 39
  • 1
    Can you elaborate, exactly why you need this image though, why not put this image to the `JLabel` and then add this to the `JPanel`, moreover, loading images to JApplets must always be done on a separate thread, as also stated in the [Java Docs](http://docs.oracle.com/javase/tutorial/uiswing/components/applet.html#images). +1, this thing made me learn something today :-) – nIcE cOw Apr 12 '12 at 07:55
  • 1
    1) *"My whole code :"* For better help sooner, post an [SSCCE](http://sscce.org/). That code has no imports, and we have no `hinhtu2.jpg` here. 2) Please take care when using code formatting, that one missed a closing `}` 3) The paint methods still makes the same mistakes as your last question. 4) Instead of removing components, use a `CardLayout`. 5) It would be better if you described what this applet does and the end effect you are trying to achieve, since 'the way you are going about achieving things' is usually 'very suboptimal'. – Andrew Thompson Apr 12 '12 at 08:12
  • @AndrewThompson: 1. I edited the question, hinhtu2.jpg is added to the same path with my java class files.. 3. Could u tell me what mistakes im facing? 5. I jsut started with applet, so it's just a try here :). – TU_HEO DAKAI Apr 12 '12 at 08:21
  • *"Could u tell me what mistakes im facing?"* I made comments on that last question. Please pay careful attention, as I do not like having to repeat myself. Also, please don't use silly made up words like 'u', it is properly spelled 'you' & we have the big keyboards to type it easily and the bandwidth to send/receive it. – Andrew Thompson Apr 12 '12 at 08:26
  • @AndrewThompson: Sorry, i didn't see your comments.. :( – TU_HEO DAKAI Apr 12 '12 at 08:29

1 Answers1

4

You should call revalidate before repaint here:

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

Revalidate call updates container hierarchy and after that a repaint might be needed. Container resize does both (revalidate and repaint), thats why the panel appears after you resize the applet.

Also i noticed 1 bad thing in yuor code:

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

You are loading image each time your custom component repaints. Better move the image loading into constructor and load it just once.

Mikle Garin
  • 10,083
  • 37
  • 59
  • 1
    You want to add panel just once or with each button click? Since your code will only do that once - custompanel will always have the old first panel value... And one more wild guess - your paintComponent method might not load image @ first call which will cause it to "show up" only after second/third repaint. Try moving image load outside the paint method and see if that helps. – Mikle Garin Apr 12 '12 at 07:46
  • It seems strange, when i access the applet in the browser in another computer, the click button works well... – TU_HEO DAKAI Apr 12 '12 at 08:10