【问题标题】:Drawing multiple graphic2d components into JPanel将多个graphic2d组件绘制到JPanel中
【发布时间】:2015-06-25 03:56:44
【问题描述】:

我已经阅读了很多关于绘制 Graphics2D 组件和添加到 JPanel/JFrame 的教程,但是我找不到如何简单地将多个这些组件添加到一个 JPanel 中。我下面的代码只添加了 1 个组件(行),我找不到为什么不能添加更多。

我做错了什么?

期望的行为:应该有 3 条红线。

我的整个代码:

package Examples;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Example1 extends JFrame {

    private final JPanel panel;

    public Example1() {

        // jpanel with graphics
        panel = new JPanel();
        panel.setPreferredSize(new Dimension(200, 200));
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        panel.setBackground(Color.WHITE);
        add(panel);


        // adding lines to jpanel
        AddMyLine(); // 1st: this works well
        AddMyLine(); // 2nd: this doesn't work
        AddMyLine(); // 3rd: this doesn't work


        setLayout(new FlowLayout(FlowLayout.LEFT));
        setSize(250, 250);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        setLocationRelativeTo(null);
    }


    // add new line to jpanel
    private void AddMyLine() {
        MyLine c = new MyLine();
        System.out.println(c);
        panel.add(c);
    }



    // line component
    private class MyLine extends JComponent {

        public MyLine() {
            setPreferredSize(new Dimension(200, 200));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D)g;
            g2d.setColor(Color.red);
            g2d.setStroke(new BasicStroke(1));
            int x1 = (int)Math.round(Math.random()*200);
            int y1 = (int)Math.round(Math.random()*200);
            int x2 = (int)Math.round(Math.random()*200);
            int y2 = (int)Math.round(Math.random()*200);
            g2d.drawLine(x1,y1,x2,y2);
        }
    }


    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Example1();
            }
        });     

    }
}

【问题讨论】:

    标签: java swing graphics2d jcomponent


    【解决方案1】:

    您的 MyLine 类不应是 Swing 组件,因此不应扩展 JComponent。相反,它应该是一个逻辑实体,实际上可以是实现 Shape 的东西,例如 Line2D,或者可以是您自己的完整类,但应该知道如何绘制自己,即,如果它不实现 Shape,那么它应该具有其他类可以调用的某种类型的draw(Graphics2D g) 方法。我认为你应该努力扩展面板的 JPanel 类,以便覆盖它的 paintComponent 方法,给它一个集合来保存添加到其中的任何 MyLine 项目,并在paintComponent 中绘制 MyLine 项目。

    其他选项包括直接在 BufferedImage 上绘图,然后在 JPanel 的 paintComponent 方法中显示该 BufferedImage。这对于静态图像非常有用,但对于需要更改或移动的图像则不利。

    例如,

    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.geom.Ellipse2D;
    import java.awt.geom.Line2D;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.*;
    
    public class DrawChit extends JPanel {
       private static final int PREF_W = 500;
       private static final int PREF_H = PREF_W;
       private List<Shape> shapes = new ArrayList<>();
    
       public DrawChit() {
          setBackground(Color.white);
       }
    
       public void addShape(Shape shape) {
          shapes.add(shape);
          repaint();
       }
    
       @Override // make it bigger
       public Dimension getPreferredSize() {
          if (isPreferredSizeSet()) {
             return super.getPreferredSize();
          }
          return new Dimension(PREF_W, PREF_H);
       }
    
       @Override
       protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D) g;
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
          for (Shape shape : shapes) {
             g2.draw(shape);
          }
       }
    
       private static void createAndShowGui() {
          DrawChit drawChit = new DrawChit();
    
          drawChit.addShape(new Line2D.Double(10, 10, 100, 100));
          drawChit.addShape(new Ellipse2D.Double(120, 120, 200, 200));
    
          JFrame frame = new JFrame("DrawChit");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(drawChit);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    或者使用我自己的 MyDrawable 类的示例,它生成的 GUI 如下所示:

    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.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Line2D;
    import java.awt.geom.Rectangle2D;
    import java.awt.geom.RoundRectangle2D;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    @SuppressWarnings("serial")
    public class DrawChit extends JPanel {
       private static final int PREF_W = 600;
       private static final int PREF_H = PREF_W;
       private List<MyDrawable> drawables = new ArrayList<>();
    
       public DrawChit() {
          setBackground(Color.white);
       }
    
       public void addMyDrawable(MyDrawable myDrawable) {
          drawables.add(myDrawable);
          repaint();
       }
    
       @Override
       // make it bigger
       public Dimension getPreferredSize() {
          if (isPreferredSizeSet()) {
             return super.getPreferredSize();
          }
          return new Dimension(PREF_W, PREF_H);
       }
    
       @Override
       protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D) g;
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
          for (MyDrawable myDrawable : drawables) {
             myDrawable.draw(g2);
          }
       }
    
       public void clearAll() {
          drawables.clear();
          repaint();
       }
    
       private static void createAndShowGui() {
          final List<MyDrawable> myDrawables = new ArrayList<>();
          myDrawables.add(new MyDrawable(new Line2D.Double(100, 40, 400, 400),
                Color.red, new BasicStroke(40)));
          myDrawables.add(new MyDrawable(new Ellipse2D.Double(50, 10, 400, 400),
                Color.blue, new BasicStroke(18)));
          myDrawables.add(new MyDrawable(new Rectangle2D.Double(40, 200, 300, 300),
                Color.cyan, new BasicStroke(25)));
          myDrawables.add(new MyDrawable(new RoundRectangle2D.Double(75, 75, 490, 450, 40, 40),
                Color.green, new BasicStroke(12)));
    
          final DrawChit drawChit = new DrawChit();
    
          JFrame frame = new JFrame("DrawChit");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(drawChit);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
    
          int timerDelay = 1000;
          new Timer(timerDelay, new ActionListener() {
             private int drawCount = 0;
    
             @Override
             public void actionPerformed(ActionEvent e) {
                if (drawCount >= myDrawables.size()) {
                   drawCount = 0;
                   drawChit.clearAll();
                } else {
                   drawChit.addMyDrawable(myDrawables.get(drawCount));
                   drawCount++;
                }
             }
          }).start();
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    
    class MyDrawable {
       private Shape shape;
       private Color color;
       private Stroke stroke;
    
       public MyDrawable(Shape shape, Color color, Stroke stroke) {
          this.shape = shape;
          this.color = color;
          this.stroke = stroke;
       }
    
       public Shape getShape() {
          return shape;
       }
    
       public Color getColor() {
          return color;
       }
    
       public Stroke getStroke() {
          return stroke;
       }
    
       public void draw(Graphics2D g2) {
          Color oldColor = g2.getColor();
          Stroke oldStroke = g2.getStroke();
    
          g2.setColor(color);
          g2.setStroke(stroke);
          g2.draw(shape);
    
          g2.setColor(oldColor);
          g2.setStroke(oldStroke);
       }
    
       public void fill(Graphics2D g2) {
          Color oldColor = g2.getColor();
          Stroke oldStroke = g2.getStroke();
    
          g2.setColor(color);
          g2.setStroke(stroke);
          g2.fill(shape);
    
          g2.setColor(oldColor);
          g2.setStroke(oldStroke);
       }
    
    }
    

    【讨论】:

      【解决方案2】:

      您不应该通过添加组件来绘制线条。组件是面板、按钮等。

      请参阅本教程了解如何使用 Graphics2D 进行绘图:https://docs.oracle.com/javase/tutorial/2d/geometry/primitives.html

      【讨论】:

        【解决方案3】:

        您的代码添加了三个组件,但面板不够大,无法显示其他两个组件

            panel.setPreferredSize(new Dimension(200, 600));
            setSize(250, 800);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-12
          • 1970-01-01
          相关资源
          最近更新 更多