调整添加的绘制组件和奇怪的摆动行为

时间:2012-01-17 17:54:33

标签: java swing

我有这个问题困扰了我好几天。我正在制作一个特殊的油漆程序。我制作了一个JPanel,并添加了使用paint(..)方法绘制的自定义jComponents。 问题是,每当我调整窗口大小时,所有添加的组件都会消失。 (或者只是不要画画)所以我最终得到一个空框架。

我也注意到使用这种方法时有一些奇怪的挥杆动作。我在描述此问题的代码中添加了注释。

package simple;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

import javax.swing.*;

public class SimpleFrame extends JFrame {
    JPanel paintArea;
    SimpleCanvas c1;
    SimpleCanvas c2;
    ArrayList<SimpleCanvas> list;

    public static void main(String[] args) {
        SimpleFrame frame = new SimpleFrame();

    }

    public SimpleFrame() {
        super("Test");
        setSize(600,500);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        //The panel to which my SimpleCanvas objects are added
        paintArea = new JPanel();
        paintArea.setPreferredSize(new Dimension(600, 500)); 
        paintArea.addMouseListener(new paintAreaMouseEvents());
        getContentPane().add(paintArea, BorderLayout.CENTER);

        setVisible(true);
        paintArea.setVisible(true);

        //A list to hold all the objects together
        list = new ArrayList<SimpleCanvas>(10);

        //The same as in class paintAreaMouseEvent, but doesnt work
        SimpleCanvas c = new SimpleCanvas();
        c.setBounds(60, 100, 100, 50);
        list.add(c);
        paintArea.add(list.get(list.size() - 1));
        paintArea.repaint();
    }
    //When you click the mouse, it makes an oval
    class paintAreaMouseEvents extends MouseAdapter {
        @Override
        //This does work.
        public void mouseClicked (MouseEvent me) {
            SimpleCanvas c = new SimpleCanvas();
            c.setBounds(me.getX() - 50, me.getY() - 25, 100, 50);

            list.add(c);
            paintArea.add(list.get(list.size() - 1));
            paintArea.repaint();
        }
    }
}

这是SimpleCanvas类

package simple;

import java.awt.*;

import javax.swing.JComponent;

public class SimpleCanvas extends JComponent {
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.BLUE);
        g.fillOval(0, 0, 100, 50);
    }
}

谢谢:)

BTW:只是想说这个网站很棒。我在使用谷歌的时候来到这里很多,现在我终于决定开个账户了。

1 个答案:

答案 0 :(得分:6)

您的问题是布局问题。添加:

System.out.println(getSize());

到您的JComponent的paint方法,看看在调整GUI大小时会发生什么。

这种情况正在发生,因为调整大小正在调用布局管理器操作。

要解决此问题,请不要使用setBounds(...)来调整组件大小,而是使用布局管理器。如果希望布局管理器遵守特定的大小,也可以覆盖JComponent的getPreferredSize方法。最后,不要使用paint方法绘制,而是使用paintComponent方法绘制。教程将解释原因。

此外,如果您绝对需要使用绝对定位来定位某些内容,那么容器必须使用空布局:

  // The panel to which my SimpleCanvas objects are added
  paintArea = new JPanel(null);

修改
如果我正在执行类似上面的程序,我不确定我是否会向JPanel添加新组件,而只是让绘图JPanel保存一个Shapes列表,然后使用一个paintComponent方法绘制形状。 for循环。例如:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class SimpleFrame2 extends JPanel {
   private static final Color ELLIPSE_COLOR = Color.LIGHT_GRAY;
   private static final Color ELLIPSE_FILL_COLOR = Color.blue;
   private static final int PREF_W = 600;
   private static final int PREF_H = 500;
   public static final int ELLIPSE_WIDTH = 100;
   public static final int ELLIPSE_HEIGHT = 50;
   private static final Stroke ELLIPSE_STROKE = new BasicStroke(2f);
   private List<Shape> shapes = new ArrayList<Shape>();

   public SimpleFrame2() {
      addMouseListener(new MouseAdapter() {
         @Override
         public void mousePressed(MouseEvent mEvt) {
            double x = mEvt.getX() - ELLIPSE_WIDTH / 2;
            double y = mEvt.getY() - ELLIPSE_HEIGHT / 2;
            double w = ELLIPSE_WIDTH;
            double h = ELLIPSE_HEIGHT;
            shapes.add(new Ellipse2D.Double(x, y, w, h));
            repaint();
         }
      });
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      // to draw smooth edges
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setStroke(ELLIPSE_STROKE);
      for (Shape shape : shapes) {
         g2.setColor(ELLIPSE_FILL_COLOR);
         g2.fill(shape);
         g2.setColor(ELLIPSE_COLOR);
         g2.draw(shape);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("SimpleFrame2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new SimpleFrame2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

编辑2
拖动形状

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class SimpleFrame3 extends JPanel {
   private static final Color ELLIPSE_COLOR = Color.LIGHT_GRAY;
   private static final Color ELLIPSE_FILL_COLOR = Color.blue;
   private static final int PREF_W = 600;
   private static final int PREF_H = 500;
   public static final int ELLIPSE_WIDTH = 100;
   public static final int ELLIPSE_HEIGHT = 50;
   private static final Stroke ELLIPSE_STROKE = new BasicStroke(2f);
   private List<RectangularShape> rects = new ArrayList<RectangularShape>();

   public SimpleFrame3() {
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      // to draw smooth edges
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setStroke(ELLIPSE_STROKE);
      for (RectangularShape rect : rects) {
         g2.setColor(ELLIPSE_FILL_COLOR);
         g2.fill(rect);
         g2.setColor(ELLIPSE_COLOR);
         g2.draw(rect);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   class MyMouseAdapter extends MouseAdapter {
      private RectangularShape selectedRect = null;
      private Point deltaPt = null;

      @Override
      public void mousePressed(MouseEvent mEvt) {
         if (mEvt.getButton() != MouseEvent.BUTTON1) {
            return;
         }

         if (rects.size() > 0) {
            for (int i = rects.size() - 1; i >= 0; i--) {
               if (rects.get(i).contains(mEvt.getPoint())) {
                  selectedRect = rects.get(i);
                  rects.remove(selectedRect);
                  rects.add(rects.size(), selectedRect);
                  deltaPt = new Point(mEvt.getX() - selectedRect.getBounds().x,
                        mEvt.getY() - selectedRect.getBounds().y);
                  repaint();
                  return;
               }
            }
         }
         double x = mEvt.getX() - ELLIPSE_WIDTH / 2;
         double y = mEvt.getY() - ELLIPSE_HEIGHT / 2;
         double w = ELLIPSE_WIDTH;
         double h = ELLIPSE_HEIGHT;
         Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
         rects.add(ellipse);
         selectedRect = ellipse;
         deltaPt = new Point((int)(mEvt.getX() - x), (int)(mEvt.getY() - y));
         repaint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (selectedRect != null) {
            Rectangle bounds = selectedRect.getBounds();
            bounds.setLocation(e.getX() - deltaPt.x, e.getY() - deltaPt.y);
            selectedRect.setFrame(bounds.x, bounds.y, bounds.width, bounds.height);
            repaint();
         }
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (selectedRect != null) {
            repaint();
            selectedRect = null;
         }
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("SimpleFrame3");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new SimpleFrame3());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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