2

I want to change a JPanel-object in an applet at startup/init. I can't figure out how to do this. I've made a simple example of my problem in which I clear the JPanel. It does not work when it is called by the init() method but it works when I press the button. What can I do to change the JPanel at startup/init?

import javax.swing.JApplet;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class TestStartUpApplet extends JApplet {

    JPanel panel;   

    @Override
    public void init() {
        System.out.println("Init");
        erasePanel();
    }

    private void erasePanel() {
        Graphics g = panel.getGraphics();
        g.clearRect(0, 0, 117, 48);
    }

    public TestStartUpApplet() {
        getContentPane().setLayout(null);

        panel = new JPanel();
        panel.setBackground(Color.RED);
        panel.setBounds(35, 36, 117, 48);
        getContentPane().add(panel);

        JButton btnTest = new JButton("Test");
        btnTest.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                erasePanel();
            }
        });
        btnTest.setBounds(35, 108, 117, 25);
        getContentPane().add(btnTest);

    }
}
Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
Paul Koning
  • 63
  • 1
  • 8

4 Answers4

3

Works just for me:

public class AppletPaintTest extends JApplet {

    @Override
    public void init() {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                setLayout(new BorderLayout());

                ImagePane pane = new ImagePane();
                pane.setBackground(Color.RED);
                pane.setOpaque(false); // Little trick

                add(pane);

            }
        });

    }

    @Override
    public void start() {
        super.start();
    }

    public class ImagePane extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {

            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g.create();

            Insets insets = getInsets();
            int x = insets.left;
            int y = insets.top;
            int width = getWidth() - 1 - (insets.left + insets.right);
            int height = getHeight() - 2 - (insets.top + insets.bottom);

            g2d.setColor(getBackground());
            g2d.fillRect(x + 10, y + 10, width - 20, height - 20);

            g2d.dispose();

        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2

question

  1. no idea why do you want to clear empty JPanel without any custom painting

  2. what's wrong with JPanel with red Background

  3. you clear JApplet before became visible on the screen

  4. doesn't works correctly, because doesn't works anything

suggestions

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 1&2) As I wrote, this is just an example. I am writing an application where I have a method that draws an image on a JPanel object. This has to be shown when the applet starts. Problem is the same. It works when I press a button but I cannot get it to work 'on startup'. 3) I guess that is the problem, so where can I put my method erasePanel() just after the moment the applet is visible? 4) That's why I posted my problem here ;-) Thanks for the suggestions. – Paul Koning Aug 02 '12 at 20:56
  • @Paul Koning start with 2D Graphics tutorial, [there are a few examples](http://stackoverflow.com/questions/tagged/java+swing+paintcomponent), painting for JPanale in the JApplet or JFrame or JDialog is the same, to try to avoiding to use method paint(), use only paintComponent() for Swing JComponents – mKorbel Aug 02 '12 at 21:07
  • @PaulKoning your making assumptions about how the paint engine works which are fundamentally wrong. Try calling something like invalidate &/or repaint in the applets run method, rather then trying to circumvent the paint process (which is what your erase method is trying to do) – MadProgrammer Aug 02 '12 at 21:17
  • Thanks, it's clear to me that I have to change the code, I made my own panel class and now it works. – Paul Koning Aug 02 '12 at 22:31
  • @PaulKoning: That's the right choice; also consider this [hybrid approach](http://stackoverflow.com/a/11372932/230513) for flexibility and this discussion of [`contentPane()`](http://stackoverflow.com/a/11769153/230513). – trashgod Aug 02 '12 at 23:21
2

Whenever you do any custom painting outside of the usually system calls to your paint() or paintComponent() methods, you must call invalidate() on any components you wish to repaint. So for your erasePanel() method, I would suggest setting some flag then calling panel.invalidate(). Then inside your panel's paintComponent() method, you can check the flag to see if you need to draw the introductory picture or just leave the panel blank.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
1

Ok, it seems that the problem was that my coding was just bad. I wanted to change a panel object by a method from another class and that's not the way to do it. I rewrote my code and made a panel class in which the painting is done using paintcomponent. I now use objects of this panel class and it shows the graphics I want at startup.

Thanks for the help!

Paul Koning
  • 63
  • 1
  • 8