Search code examples
javaswingjframejcomponent

JFrame display error


I'm trying to display a simple image using JFrame and JComponent. I've read through some of the existing questions and answers but it's no use. The following are my codes of my subclasses to JComponent and JFrame:

import java.awt.*;
import javax.swing.JComponent;

public class FaceComponent extends JComponent {

public FaceComponent() {        
}

public void painComponent(Graphics g) {

    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());

    g.setColor(Color.YELLOW);
    g.fillOval(60, 60, 200, 200);

    g.setColor(Color.MAGENTA);
    g.fillOval(90, 100, 40, 20);
    g.fillOval(180, 100, 40, 20);

    g.setColor(Color.PINK);
    g.drawLine(120, 160, 140, 180);
    g.drawLine(140, 180, 160, 160);
    g.drawLine(120, 160, 140, 200);
    g.drawLine(140, 200, 160, 160);

    g.setColor(Color.BLACK);
    g.setFont(new Font("SansSerif", Font.ITALIC, 24));
    g.drawString("Whatsup", 30, 200);

}

}

Here's my FaceWindow with JFrame imported:

import javax.swing.JFrame;

public class FaceWindow {
public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setTitle("lab09ex1");
    frame.setSize(400, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(true);
    frame.setVisible(true);

    FaceComponent fc = new FaceComponent();
    frame.add(fc);
}
}

But it ends out with an empty grey display screen instead of what I'm input in my program. What's the matter? Sorry to be not specific in this question but it's the only way to show you my current situation.


Solution

  • In FaceComponent, painComponent should be paintComponent

    • There is no need for this method to be public, you never want anybody to ever call it. You should always use the @Override annotation when you are trying to override a method, this will raise a compile to error if you make mistake, saving you a lot of wasted time...
    • Using new Font("SansSerif", Font.ITALIC, 24) within a paint method is ill advised, as this can take time if it needs to load the font. Better to preload it in the constructor and apply it as required.
    • FaceComponent should override the getPreferredSize method and should return a "preferred" or "default" size, this will ensure that the component is not automatically sized to 0x0 by some layout managers.
    • Consider using pack over setSize
    • Make sure you always add your components to the frame before making it visible, this will also solve issues with components not appearing when the frame is first made visible
    • You should always much sure that you UI is created and modified within the context of the Event Dispatching Thread, see Initial Threads for more details