1

so I'm playing with JPanels and JFrames and I'm noticing that the JPanel I created is not showing displaying when I add it to a Jframe object. Note, that when I created a JPanel in my Jframe constructor giving the jpanel parameters before being added to the Jframe, it worked. However now I'm using a JPanel object I created and it's not working anymore. This is what I have done.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyGui extends JFrame {

    MyMouseListener listen = new MyMouseListener();

    public MyGui() {
        setSize(500, 500);
        //setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        getContentPane().setBackground(Color.WHITE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        Panel panel = new Panel();
        add(panel, BorderLayout.WEST);
        //setVisible(true);
        show();
    }

    public static void main(String[] a) {
        MyGui gui = new MyGui();
    }
}

class Panel extends JPanel {

    MyMouseListener listen = new MyMouseListener();

    public Panel() {
        setPreferredSize(new Dimension(300, 300));
        addMouseListener(listen);
        setBackground(Color.YELLOW);
        setLayout(new GridLayout(3, 1));
    }

    public void paint(Graphics g) {
        super.paintComponents(g);
        g.drawOval((int) Math.round(listen.p.getX()),
                (int) Math.round(listen.p.getX()), 1, 1);
    }
}

class MyMouseListener implements MouseListener {

    Point p = new Point();

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("Mouse was clicked");
    }

    @Override
    public void mousePressed(MouseEvent e) {
        p = e.getPoint();
        System.out.println(p);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}

EDIT: Actually I think I've found the error. The JPanel has it's paint method which when deleted allows the Jframe to show the panel. However I need to be able to draw stuff on the JPanel.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Michael Nana
  • 1,969
  • 4
  • 24
  • 36
  • 1
    Call pack() or setSize() before showing the frame. If you add the panel after showing call revalidate(); repaint(); – StanislavL Sep 18 '13 at 12:30
  • The only thing I changed in your code to see your panel was to change `super.paintComponents(g);` to `super.paintComponent(g);`. That still leave out your oval that isn't painted. – Jonathan Drapeau Sep 18 '13 at 12:49
  • @JonathanDrapeau So it looked liked this? public void paintComponent (Graphics g){ super.paintComponent(g); g.drawOval((int)Math.round(listen.p.getX()), (int)Math.round(listen.p.getX()), 1, 1); } – Michael Nana Sep 18 '13 at 12:54
  • @JonathanDrapeau Because mine doesn't work. – Michael Nana Sep 18 '13 at 12:54
  • `public void paint (Graphics g){ super.paintComponent(g); g.drawOval((int)Math.round(listen.p.getX()), (int)Math.round(listen.p.getX()), 1, 1); }`, didn't mention changing anything else but that line. :) – Jonathan Drapeau Sep 18 '13 at 12:55
  • Why you using `show()` and why not `setVisible(true)` ? – nIcE cOw Sep 18 '13 at 12:58
  • @MichaelNana : Please have a look at this [answer](http://stackoverflow.com/a/11372350/1057230) – nIcE cOw Sep 18 '13 at 14:03

5 Answers5

4

its

super.paintComponent(g);

Advice:

1)You are making things unnecessarily complex. e.g to close the window you should use

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

instead of the call to System.exit(0); and using window listeners

2)As said by @mKorbel , you should use SwingUtilities.invokeLater to start your gui as Java GUIs are supposed to run on EDT(Event Dispatch Thread) and should not run on main thread.

Naveen
  • 7,944
  • 12
  • 78
  • 165
  • Thanks for your suggestions. I have apdated my code with the changes. Anyway, taking out super.paintComponent(g) still doesn't make the JPanel visible in the JFrame. – Michael Nana Sep 18 '13 at 12:47
  • You don't have to take out anything.Just remove the **s** in the line `super.paintComponents(g);` inside your `paint`.Now it should look like `super.paintComponent(g);`.Then,it runs fine – Naveen Sep 18 '13 at 12:50
  • I did that too and it still doesn't work. public void paintComponent (Graphics g){ super.paintComponent(g); g.drawOval((int)Math.round(listen.p.getX()), (int)Math.round(listen.p.getX()), 1, 1); } – Michael Nana Sep 18 '13 at 12:52
2

1) super.paintComponents(g); inside paint() could be

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    ....
}

2) don't to set any size setSize(500,500); or setPreferredSize(new Dimension(300, 300));, to use pack() and then (uncomment) setVisible(true) for JFrame and to override getPreferredSize() for JPanel

3) MyGui gui=new MyGui(); inside public static void main(String []a){, should be wrapped into invokeLater, more see in Oracle tutorial Initial Thread

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • There's a preferred size set to the `JPanel`, making `pack()` and `setVisible` work correctly. – Jonathan Drapeau Sep 18 '13 at 12:41
  • 1
    @Jonathan Drapeau [agree with final result, but isn't about good coding practicies](http://stackoverflow.com/a/9258934/714968) – mKorbel Sep 18 '13 at 12:44
  • @mKorbel Are you talking about the paintComponent inside the JPanel? because I have included the call to the super and commented it out and on both occasions the JPanel still didn't show up. – Michael Nana Sep 18 '13 at 12:51
  • @Michael Nana see my linked code in above comment addressed to Jonathan Drapeau – mKorbel Sep 18 '13 at 12:55
1

Did you try to set the layout manager and add the panel to the contentPane instead of the JFrame itself ?

getContentPane().setLayout(new BorderLayout());
getContentPane().add(panel, BorderLayout.WEST);
Hugo G.
  • 636
  • 6
  • 21
  • 1
    You should always add your Panel to the contentPane anyway. http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html – Hugo G. Sep 18 '13 at 13:28
0

Default Layout manager for frame is FlowLayout not BorderLayout. Try to setLayout(new BorderLayout()) in your MyGui contructor.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

You didn't set a Layout to your content pane. Try something like getContentPane.setLayout(new Layout())

View the oracle docs for details about layout managers: http://docs.oracle.com/javase/tutorial/uiswing/layout/layoutlist.html

Hope this helps

jMan
  • 587
  • 1
  • 8
  • 23
Sorontur
  • 500
  • 4
  • 15