与Graphics2d,画布和形状混淆

时间:2014-08-28 10:56:51

标签: java swing graphics2d

我正在学习java游戏编程的基础知识,我对一些事情感到困惑。 我知道你使用“canvas”类创建一个空白画布,然后使用paint方法创建东西。

Graphics2D是什么?我见过人们使用grahpics2d类来创建一个画布,例如

Graphics2D g2d = (Graphics2D) g; 
g2d.setColor(Color.BLACK);

现在为什么他们使用grahpics2d而不是画布?

我也看到人们通过使用:

创建像矩形的形状
Rectangle r = new Rectangle();

但有些人创建了它们:

Shape shape = new Rectangle2D.Double(value1,valu2,valu3,valu4);

这两者之间有什么区别?

提前致谢。

的问候,

2 个答案:

答案 0 :(得分:3)

首先,我不会使用Canvas对象而是使用JPanel,而且我会在paintComponent方法覆盖中绘制,而不是绘制方法。可以把JPanel看作是一个画布画布,而将Graphics或Graphics2D看作是你用来画画的画笔。换句话说,您需要两者来创建绘图。

对于Rectangle vs. Rectangle2D,当Graphics2D出现时,2D形状是Graphics的新增功能的一部分。它们基于Shape界面,可以为您的绘图提供更多的灵活性和OOP。

有关详细信息,请查看:


修改
回答你的问题:

  

问:所以你会使用JPanel作为我的空画布和Graphics2D g2d =(Graphics2D)g;创建一种可用于更改JPanel的画笔。因此这个g2d.setColor(Color.BLACK);更改JPanel画布的背景颜色。这是对的吗?

是。您甚至可以通过

更改Graphics2D对象的笔划
g2d.setStroke(new BasicStroke(...));

  

问:也可以向我解释一下" Shape"你用它做什么用?

请查看我上面链接的第二个教程,因为它将详细介绍Shape代表什么以及如何使用它。它总结了所有Xxxxx2D类(如Rectangle2D和Ellipse2D)使用的接口。它允许所有人共享某些属性,包括可填写,可绘制,可转换等等。


编辑2
例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;

import javax.swing.*;

@SuppressWarnings("serial")
public class RotateFoo extends JPanel {

   private static final int PREF_WIDTH = 800;
   private static final int PREF_HEIGHT = 600;
   private static final Color STAR_COLOR = Color.red;
   private static final int ROTATE_TIMER_DELAY = 20;
   private static final int POINTS = 5;
   private static final int RADIUS = 50;
   private static final String TITLE = "Press \"r\" to rotate";
   private static final float TITLE_POINTS = 52f;

   private Path2D star = new Path2D.Double(); 
   private Timer rotateTimer = new Timer(ROTATE_TIMER_DELAY, new RotateTimerListener());

   public RotateFoo() {
      double x = 0.0;
      double y = 0.0;
      double theta = 0.0;
      for (int i = 0; i <= POINTS; i++) {
         x = RADIUS + RADIUS * Math.cos(theta);
         y = RADIUS + RADIUS * Math.sin(theta);
         if (i == 0) {
            star.moveTo(x, y);            
         } else {
            star.lineTo(x, y);
         }
         theta += 4 * Math.PI / POINTS;
      }

      double tx = (getPreferredSize().getWidth() - star.getBounds().getWidth()) / 2;
      double ty = (getPreferredSize().getHeight() - star.getBounds().getHeight()) / 2;
      AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
      star.transform(at );

      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();
      String rotateOn = "rotate on";
      String rotateOff = "rotate off";
      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0, false), rotateOn);
      actionMap.put(rotateOn, new AbstractAction() {

         public void actionPerformed(ActionEvent arg0) {
            if (rotateTimer != null && !rotateTimer.isRunning()) {
               rotateTimer.start();
            }
         }
      });
      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0, true), rotateOff);
      actionMap.put(rotateOff, new AbstractAction() {

         public void actionPerformed(ActionEvent arg0) {
            if (rotateTimer != null && rotateTimer.isRunning()) {
               rotateTimer.stop();
            }
         }
      });
      //rotateTimer.start();

      JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
      titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, TITLE_POINTS));
      add(titleLabel);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_WIDTH, PREF_HEIGHT);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(STAR_COLOR);

      if (star != null) {
         g2.draw(star);
      }
   }

   private class RotateTimerListener implements ActionListener {
      private static final double BASE_THETA = Math.PI / 90;

      @Override
      public void actionPerformed(ActionEvent e) {
         double anchorx = getPreferredSize().getWidth() / 2;
         double anchory = getPreferredSize().getHeight() / 2;
         AffineTransform at = AffineTransform.getRotateInstance(BASE_THETA, anchorx, anchory);
         star.transform(at);
         repaint();
      }
   }

   private static void createAndShowGui() {
      RotateFoo mainPanel = new RotateFoo();

      JFrame frame = new JFrame("RotateFoo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

答案 1 :(得分:2)

你必须做出一定的改变:

  • Canvas(或者Panel或JPanel或Frame)是表示GUI对象的对象!这样的对象需要捕获输入事件,或者可能用于布局。所有这些都可以设置为活动和禁用。
  • 图形对象就是画布内部的东西。它负责纯粹的绘图!它可以使用特殊的绘图功能,有笔画,字体和颜色......

所以 - 你有两个不同的课程用于不同的目的!我花了一段时间才明白......

原谅我微不足道的英语...