我的自定义组件无法绘制

时间:2015-12-12 01:03:48

标签: java swing awt


我正在尝试创建一个可以识别为组件的类(称为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);

除非覆盖主要(JPanel),否则不会绘制股票,因此有一个规范要求绘制股票:

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

1 个答案:

答案 0 :(得分:3)

您的问题是布局,大小和preferredSize之一。由于您使用JPanel将您的Stock Component添加到FlowLayout,因此Component会将其自身调整为首选大小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);
}