我的自定义组件无法绘制

My custom component cannot be painted


我正在尝试创建一个 class(称为 Stock),它可以被识别为一个组件——让我在它上面使用 Listener。
但是,除非您指定(这不是一个好主意!)在 panel.paint().
中绘制它,否则它不会被绘制 程序运行如下:

          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);

Stock 不会被绘制,除非 primary(JPanel) 被覆盖,以便有一个规范调用 stock 来绘制:

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

这是我的代码——我想问题可能会发生,因为除了从 Component 继承的 paint 方法之外,我没有重写任何其他东西。
**********修改为可测试,请看下面
**

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。我没有使用 JComponent,因为 JComponent 的功能比我需要使用的要多。 Container 和 Button 继承的组件应该可以正常工作。

p.s.2。即使您使用 JComponent,您也会得到相同的结果。下面的代码。

    import java.awt.*;

导入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();
    }
}

您的问题是布局、大小和 preferredSize 之一。由于您要使用 JPanel 将 Stock 组件添加到 FlowLayout,因此该组件将按其首选大小调整自身大小,即 0、0。如果您为 JPanel 提供了不同的布局,例如

      primary.setLayout(new BorderLayout());

然后添加您的 Stock 对象,它将填充主 JPanel 并自行绘制。

其他选项包括设置 Stock 对象的 preferredSize,甚至覆盖其 getPreferredSize() 方法以使其足够大:

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