K.Mole
K.Mole

Reputation: 334

My custom component cannot be painted


I'm trying to create a class(called Stock) which can be identified as a Component--and let me use Listener on it.
However, it is not painted unless you specify (not a good idea!) to paint it in panel.paint().
The program runs as this:

          JFrame frame = new JFrame ("..");
          frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
          final Stock theStock=new Stock();
          JPanel primary = new JPanel();
          primary.setPreferredSize(new Dimension(500,500));
          primary.add(theStock);
          frame.getContentPane().add(primary);
          frame.pack();
          frame.setVisible(true);

The Stock will not be painted unless primary(JPanel) is overriden so that there is a specification calling the stock to draw:

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.black);
        g.drawRect(x-2, y-2, 74, 124);
    }

Here's my code--I guess the problem may happen because I did not override anything else than paint method inherited from Component.
**********Modified to be testable, please see below
**

import java.awt.*;

import javax.swing.*;


@SuppressWarnings("serial")
public class Stock extends Component{
    private int x; //the position for image
    private int y;//position for image

    public Stock() {
        x=285;
        y=280;

    }


    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.black);
        g.drawRect(x-2, y-2, 74, 124);
    }

    public void works(){
          JFrame frame = new JFrame ("..");
          frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
          final Stock theStock=new Stock();
          JPanel primary = new JPanel(){
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    theStock.paint(g);
                }
          };
          primary.setPreferredSize(new Dimension(500,500));
          primary.add(theStock);
          frame.getContentPane().add(primary);
          frame.pack();
          frame.setVisible(true);
    }

    public void doesNotWork(){
          JFrame frame = new JFrame ("..");
          frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
          final Stock theStock=new Stock();
          JPanel primary = new JPanel();
          primary.setPreferredSize(new Dimension(500,500));
          primary.add(theStock);
          frame.getContentPane().add(primary);
          frame.pack();
          frame.setVisible(true);
    }

    public static void main(String[] args) {
        Stock a = new Stock();
        a.works();
        //a.doesNotWork();
    }
}

p.s.1. I'm not using JComponent because JComponent has more functionalities than I need to use. Component, as from which Container and Button inherit, should work well.

p.s.2. Even you use JComponent you get the same result. Code below.

    import java.awt.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class Stock extends JComponent{
    private int x; //the position for image
    private int y;//position for image

    public Stock() {
        x=285;
        y=280;

    }



    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.black);
        g.drawRect(x-2, y-2, 74, 124);
    }

    public void works(){
          JFrame frame = new JFrame ("..");
          frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
          final Stock theStock=new Stock();
          JPanel primary = new JPanel(){
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    theStock.paint(g);
                }
          };
          primary.setPreferredSize(new Dimension(500,500));
          primary.add(theStock);
          frame.getContentPane().add(primary);
          frame.pack();
          frame.setVisible(true);
    }

    public void doesNotWork(){
          JFrame frame = new JFrame ("..");
          frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
          final Stock theStock=new Stock();
          JPanel primary = new JPanel();
          primary.setPreferredSize(new Dimension(500,500));
          primary.add(theStock);
          frame.getContentPane().add(primary);
          frame.pack();
          frame.setVisible(true);
    }

    public static void main(String[] args) {
        Stock a = new Stock();
        //a.works();
        a.doesNotWork();
    }
}

Upvotes: 2

Views: 57

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285430

Your problem is one of layouts, size and preferredSize. Since you're adding a your Stock Component to a FlowLayout using JPanel, the Component will size itself at its preferred size which is 0, 0. If you gave the JPanel a different layout, say

      primary.setLayout(new BorderLayout());

and then added your Stock object, it would fill the primary JPanel and it would paint itself.

Other options include setting your Stock objects preferredSize, or even overriding its getPreferredSize() method so that it's large enough:

@Override
public Dimension getPreferredSize() {
    if (isPreferredSizeSet()) {
        return super.getPreferredSize();
    }
    return new Dimension(PREF_W, PREF_H);
}

Upvotes: 3

Related Questions