Java 回转部件工作不正常

Java 回转部件工作不正常,java,swing,Java,Swing,我不明白为什么我必须设置Component.setPreferredSize()来绘制,为什么我的椭圆没有放在一个地方。此外,我还有一些其他问题,如下所述 public class PaintPanel extends JPanel implements ActionListener { private void initStructure() { for (int i : new Range(MAX_AGENTS)) { Agent ag

我不明白为什么我必须设置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
    }
}
在这种情况下,如果我设置了首选尺寸,我会得到下面的图片

所以

问题

1) 在contentPanel上调用paint()的组件中,是否存在不设置首选大小和绘制组件的图案

2) 为什么g.不工作


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

问题是如果JPanel没有首选大小,并且如果它被添加到使用布局管理器的容器中,而该容器没有填充容器(例如FlowLayout),那么GUI如何知道图形JPanel应该是什么大小?我听说在你的JPanel上调用
setPreferredSize(…)
比调用
setPreferredSize(…)
更好的方法是覆盖它的
Dimension getPreferredSize()
方法(询问该网站的Swing专家kleopatra)

关于:

为什么g.fillShape不起作用

检查API——图形是否有fillShape方法?不。但是Graphics2D有一个
填充(Shape s)
方法,这就是您想要的

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

请澄清这一点并提供详细信息。“放在一点上”是什么意思?你到底期待什么样的行为?为什么


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


例如:

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

}
import java.awt.*;
导入javax.swing.*;
公共类MyDrawingPanel扩展了JPanel{
专用静态最终整型预调W=100;
私有静态final int PREF_H=PREF_W;
//专用点p1=新点(1,1);
专用点p1=新点(30,1);
专用点p2=新点(100101);
//专用点p3=新点(10,10);
专用点p3=新点(50,10);
私有int[]xs={p1.x,p2.x,p3.x};
私有int[]ys={p1.y,p2.y,p3.y};
私有多边形三角形=新多边形(xs,ys,xs.length);
公共MyDrawingPanel(){
}
@凌驾
公共维度getPreferredSize(){
如果(isPreferredSizeSet()){
返回super.getPreferredSize();
}
返回新维度(PREF_W,PREF_H);
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 setColor(新颜色(255、255、255));/!!从未涂漆
g、 填充多边形(三角形);/!!从未涂漆
g、 drawOval(10,10,10,10);/!!仅在设置首选尺寸时绘制
}
私有静态void createAndShowGui(){
int行=4;
int cols=4;
JPanel gridPanel=newjpanel(新网格布局(行、列));
对于(int i=0;i
问题是如果JPanel没有首选大小,并且如果它被添加到使用布局管理器的容器中,而该容器没有填充容器(例如FlowLayout),那么GUI如何知道图形JPanel应该是什么大小?我听说在你的JPanel上调用
setPreferredSize(…)
比调用
setPreferredSize(…)
更好的方法是覆盖它的
Dimension getPreferredSize()
方法(询问该网站的Swing专家kleopatra)

关于:

为什么g.fillShape不起作用

检查API——图形是否有fillShape方法?不。但是Graphics2D有一个
填充(Shape s)
方法,这就是您想要的

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

请澄清这一点并提供详细信息。“放在一点上”是什么意思?你到底期待什么样的行为?为什么


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


例如:

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

}
import java.awt.*;
导入javax.swing.*;
公共类MyDrawingPanel扩展了JPanel{
专用静态最终整型预调W=100;
私有静态final int PREF_H=PREF_W;
//专用点p1=新点(1,1);
专用点p1=新点(30,1);
专用点p2=新点(100101);
//专用点p3=新点(10,10);
专用点p3=新点(50,10);
私有int[]xs={p1.x,p2.x,p3.x};
私有int[]ys={p1.y,p2.y,p3.y};
私有多边形三角形=新多边形(xs,ys,xs.length);
公共MyDrawingPanel(){
}
@凌驾
公共维度getPreferredSize(){
如果(isPreferredSizeSet()){
返回super.getPreferredSize();
}
返回新维度(PREF_W,PREF_H);
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 setColor(新颜色(255、255、255));/!!从未涂漆
g、 填充多边形(三角形);/!!从未涂漆
g、 drawOval(10,10,10,10);/!!仅在设置首选尺寸时绘制
}
私有静态void createAndShowGui(){
int行=4;
int cols=4;
JPanel gridPanel=newjpanel(新网格布局(行、列));
对于(int i=0;i