Swing paintComponent无法正常工作

时间:2015-03-26 16:19:15

标签: java swing

我不明白为什么我必须设置 Component.setPreferredSize()来绘制,以及为什么我的椭圆不会放在一个地方。我还有一些其他问题,如下所述。

public class PaintPanel extends JPanel implements ActionListener
{
    private void initStructure()
    {
        for (int i : new Range(MAX_AGENTS)) {
            Agent agent = new Agent();
            agents.add(agent);
            add(agent);

        }
    }

//i want to override parent class 'add', to easy call 'actionPerformed' on children elements.  
    public Component add(Element comp)
    {
        elements.add(comp);
        return super.add(comp);
    }


    @Override
    public void actionPerformed(ActionEvent e)
    {
        for(Element element: elements){
            element.actionPerformed(e);
        }

        repaint();
    }


  //ELEMENT is abstract class: 'public class Element extends JComponent implements ActionListener'

  public class Agent extends Element
  {
    public Agent()
    {
        super();
 //     setPreferredSize(new Dimension(120,120)); !!!! a-a, i don't know the future size of the oval or triangle, i don't want and i can't set this :(
        setVisible(true);
    }


    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        System.out.println("draw"); //called

        Point p1 = new Point(1, 1);
        Point p2 = new Point(101, 101);
        Point p3 = new Point(10, 10);

        int[] xs = { p1.x, p2.x, p3.x };
        int[] ys = { p1.y, p2.y, p3.y };

        Polygon triangle = new Polygon(xs, ys, xs.length);
        g.setColor(new Color(255,255,255)); // !! never painted
        g.fillPolygon(triangle); //!! never painted

        g.drawOval(10,10,10,10); // !!!! painted only when i set preferredSize
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        System.out.println("i am alive"); //working
    }
}

如果我设置了首选尺寸,我得到了下面的图片。

enter image description here

所以

问题

1)是否有任何模式不设置首选大小并在内容中绘制组件 contentPanel <上调用 paint() / em>的

2)为什么 g.fillPolygon 无效?

3)为什么我的 ovals 没有放在一个点上?

2 个答案:

答案 0 :(得分:3)

问题是如果JPanel没有首选大小,并且如果它被添加到使用不填充容器的布局管理器的容器(例如FlowLayout),那么如何GUI会知道绘图JPanel应该是多大?我听说比在JPanel上调用setPreferredSize(...)更好的是覆盖其Dimension getPreferredSize()方法(请问kleopatra,这个网站上的Swing专家)。

关于:

  

为什么g.fillShape无效?

检查API - Graphics是否有fillShape方法?不。但是Graphics2D有fill(Shape s)方法,这就是你想要的。

  

为什么我的椭圆不放在一个点上?

请澄清并提供详细信息。你是什​​么意思&#34;放在一点&#34;?你期待的是什么行为以及为什么?


编辑:您的三角形未被绘制,因为所有点都是共线


例如:

import java.awt.*;

import javax.swing.*;

public class MyDrawingPanel extends JPanel {
   private static final int PREF_W = 100;
   private static final int PREF_H = PREF_W;
   // private Point p1 = new Point(1, 1);
   private Point p1 = new Point(30, 1);
   private Point p2 = new Point(100, 101);
   // private Point p3 = new Point(10, 10);
   private Point p3 = new Point(50, 10);
   private int[] xs = { p1.x, p2.x, p3.x };
   private int[] ys = { p1.y, p2.y, p3.y };
   private Polygon triangle = new Polygon(xs, ys, xs.length);


   public MyDrawingPanel() {
   }

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

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(new Color(255, 255, 255)); // !! never painted
      g.fillPolygon(triangle); // !! never painted

      g.drawOval(10, 10, 10, 10); // !!!! painted only when i set preferredSize
   }

   private static void createAndShowGui() {
      int rows = 4;
      int cols = 4;
      JPanel gridPanel = new JPanel(new GridLayout(rows, cols));
      for (int i = 0; i < rows; i++) {
         for (int j = 0; j < cols; j++) {
            gridPanel.add(new MyDrawingPanel());
         }
      }

      JFrame frame = new JFrame("PaintPanel");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(gridPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }

}

答案 1 :(得分:3)

  

为什么我的椭圆不会放在一个点上?

我猜您要将Agent组件添加到JPanel中。默认情况下,JPanel使用FlowLayout。因此,每个组件放置120个像素,并在行填充时流向新行。

  

我不知道椭圆形或三角形的未来大小,我不想要,我也无法设置这个

不要使用drawOval(...)方法。而是使用表示椭圆的Shape对象。然后你可以得到Shape的大小,并在@hovercraft提到的getPreferredSize()方法中使用这个值。

查看Playing With Shapes以获取有关此概念的更多信息。当然,如果使用此概念,则需要将Shapes定义为实例变量,以便paintComponent()和getpreferredSize()方法都可以引用Shape。