Skip to content

How to add a JPanel graphic to a JFrame without covering the JFrame

I’m trying to add a small tornado graphic (upside down pyramid) to my Frame. I can get the tornado by adding it to the frame in the main method but when I do that all I see is the tornado graphic and not the GUI underneath it.

So, I’m now trying to add the Tornado graphic to the frame when its created in the createComponents method but it now doesn’t appear at all. Instead all I can see it the GUI in the frame.

I’ probably missing something easy but I can’t seem to figure it out. I’m not sure what I need to to in order to get the GUI and the tornado graphic both to appear.

    public class EFScaleViewer {

        public static void main(String[] args) {
            // TODO Auto-generated method stub
            TornadoFrame frame = new TornadoFrame();

            frame.setTitle("EF Scale");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);  
        }
}

Here is where I create the frame and am trying to add the tornado:

public class TornadoFrame extends JFrame{

    private JButton submit;
    private JLabel label;
    static JLabel errorLabel;
    static JTextField textBox;   
    JPanel tornado = new TornadoComponent();

    private static final int FRAME_WIDTH = 400;
    private static final int FRAME_HEIGHT = 300;

    //Constructor for the frame 
    public TornadoFrame() {
        super();
        setSize(FRAME_WIDTH, FRAME_HEIGHT);
        createComponents();
    }

    private void createComponents()
       {
          textBox = new JTextField("    "); 
          submit = new JButton("Submit");
          label = new JLabel("Please enter a windspeed:");
          errorLabel = new JLabel("Error Message " );

          JPanel panel = new JPanel();
          panel.add(label);
          panel.add(textBox);
          panel.add(submit);

         panel.add(errorLabel);   
         panel.add(tornado);
         add(panel);
       }    
}

I know this is working but I may be missing something so here is where I create the tornado:

public class TornadoComponent extends JPanel {
    public void paintComponent(Graphics g) {
        int[] xPoints = {100,200,0};
        int[] yPoints = {0,200,200};
        int nPoints = 3;

        g.drawPolygon(xPoints, yPoints, nPoints);

    }
}

Answer

You have to set the JPanels size for it to be able to display Graphics.

static class TornadoComponent extends JPanel {

    public TornadoComponent() {
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    public void paintComponent(Graphics g) {
        //Whatever
    }
}

And in order to trigger paintComponent(Graphics g) you have to add tornado.repaint(); at the end of your createComponents() function.

private void createComponents() {
    //All your components
    panel.add(tornado);
    add(panel);
    tornado.repaint();
}

Now the Polygon is shown but not at the right place (slightly off the image)

Therefore we have to arrange your JPanels a bit:

    private void createComponents() {
        textBox = new JTextField("    ");
        submit = new JButton("Submit");
        label = new JLabel("Please enter a windspeed:");
        errorLabel = new JLabel("Error Message " );

        JPanel upper = new JPanel();
        upper.setLayout(new BoxLayout(upper,BoxLayout.X_AXIS));
        upper.add(label);
        upper.add(textBox);
        upper.add(submit);
        upper.add(errorLabel);
        JPanel lower = new JPanel();
        lower.setLayout(new BoxLayout(lower,BoxLayout.X_AXIS));
        lower.add(tornado);
        JPanel over = new JPanel();
        over.setLayout(new BoxLayout(over,BoxLayout.Y_AXIS));
        over.add(upper);
        over.add(lower);
        add(over);
        tornado.repaint();
    }

Basically I make some boxes…

Over
    Upper
        ... your stuff with text
    Lower
        Our tornado

Now our tornado is the wrong way round…

int[] xPoints = {100,200,150};
int[] yPoints = {0,0,150};

And voilà:

Tornado

We just created a very basic tornado that is not aiming at anything 🙂

If you want to change the tornados position later you just have to recall tornado.repaint(); and you are all set.