【问题标题】:Why doesn't this Java paint program paint more than one oval?为什么这个 Java 绘图程序不能绘制多个椭圆?
【发布时间】:2013-06-03 19:53:26
【问题描述】:

我有一个使用自定义 JPanel 进行绘画的 Java 绘画程序。当单击 JPanel 时会绘制一个小椭圆(或圆形,如果您愿意的话),但每次单击另一个位置时椭圆会消失。坐标也会更新,但椭圆不会停留,它会移动到用户接下来单击的任何位置...... 这是自定义 JPanel 的代码:

int xCord, yCord;

    public class PaintPanel extends JPanel implements MouseListener {
        // default serial whatever...
        private static final long serialVersionUID = -6514297510194472060L;

        // initial values
        int xCord = -10;
        int yCord = -10;

        public PaintPanel() {
            addMouseListener(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(ProgramUI.currentColor);
            g.fillOval(xCord, yCord, 8, 8);
            repaint();
        }

        @Override
        public void mouseClicked(MouseEvent m) {
        }

        @Override
        public void mouseEntered(MouseEvent m) {
        }

        @Override
        public void mouseExited(MouseEvent m) {
        }

        @Override
        public void mousePressed(MouseEvent m) {
            if (paintPanel.contains(m.getPoint())) {
                xCord = m.getX();
                yCord = m.getY();
                System.out.println("x: " + xCord + " y: " + yCord);
            }
        }

        @Override
        public void mouseReleased(MouseEvent m) {
        }

    }

我需要按住鼠标来连续绘制椭圆,直到松开鼠标按钮。这里唯一的问题是鼠标椭圆更新,但不保存它的原始位置。我该如何解决?

【问题讨论】:

    标签: java swing repaint paintcomponent


    【解决方案1】:

    只绘制一个椭圆,因为只有一个fillOval 语句在paintComponent 方法中绘制一个椭圆,所以语句

    super.paintComponent(g);
    

    一旦调用repaint,就会清除任何以前的绘画。

    要绘制多个椭圆,您可以从List<Point> 绘制组件,如Custom Painting Approaches 中所述

    不要从paintComponent 内部呼叫repaint。这会产生无限循环并降低性能。如果需要定期更新,请改为从Swing TimerActionListener 调用repaint

    【讨论】:

      【解决方案2】:

      这是因为组件会重新绘制自身,为了使更改永久化,您应该在每次完成绘制后获取 jpanel 的图像并将其设置为背景...

      【讨论】:

        【解决方案3】:

        您只绘制用户每次点击的最后位置。相反,您需要收集过去的点击并每次都绘制它们。

        这段代码会做你想做的事:

        package com.sandbox;
        
        import javax.swing.*;
        import java.awt.*;
        import java.awt.event.MouseEvent;
        import java.awt.event.MouseListener;
        import java.util.ArrayList;
        
        public class SwingSandbox {
        
        
            public static void main(String[] args) {
        
                JFrame frame = buildFrame();
                frame.add(new PaintPanel());
            }
        
            public static class PaintPanel extends JPanel implements MouseListener {
                // default serial whatever...
                private static final long serialVersionUID = -6514297510194472060L;
        
                ArrayList<Point> points = new ArrayList<Point>();
        
                public PaintPanel() {
                    addMouseListener(this);
                }
        
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(new Color(250));
                    for (Point point : points) {
                        g.fillOval(point.x, point.y, 8, 8);
                    }
                    repaint();
                }
        
                @Override
                public void mouseClicked(MouseEvent m) {
                }
        
                @Override
                public void mouseEntered(MouseEvent m) {
                }
        
                @Override
                public void mouseExited(MouseEvent m) {
                }
        
                @Override
                public void mousePressed(MouseEvent m) {
                    if (this.contains(m.getPoint())) {
                        points.add(m.getPoint());
                    }
                }
        
                @Override
                public void mouseReleased(MouseEvent m) {
                }
        
            }
        
        
            private static JFrame buildFrame() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setSize(200, 200);
                frame.setVisible(true);
                return frame;
            }
        
        
        }
        

        【讨论】:

          猜你喜欢
          • 2017-07-20
          • 2016-03-30
          • 1970-01-01
          • 1970-01-01
          • 2012-03-03
          • 1970-01-01
          • 2012-06-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多