尝试在java中绘制线时出现意外输出

时间:2014-03-27 11:14:38

标签: java swing user-interface

这是我的第一个GUI练习。我试图用for循环绘制一条线,但由于某种原因,我还没弄清楚为什么我只得到它的最后一个点(像素)。我猜repaint()做的事与我的想法有所不同,但我还无法弄清楚它是什么。

这是我的代码:

 package com.mycompany;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class MousePanel extends JPanel implements MouseListener{

        int pointX, pointY, oldX, oldY;

        public MousePanel(){
            super();
            addMouseListener(this);   
        }

        public void mouseClicked(MouseEvent mouse){


            // Tell the panel that we need to redraw things.
                oldX=pointX;
                oldY=pointY;
            // Get the location of the current mouse click.
                pointX = mouse.getX();
                pointY = mouse.getY();
            // Tell the panel that we need to redraw things.

                for (int i=0 ; i<50 ; i++)
                {
                    pointX ++;
                    repaint();

                }
                System.out.println("x:"+pointX+", y:"+pointY);

            }

        public void paintComponent(Graphics g){
            g.fillOval(pointX, pointY, 5, 5);
        }

        public void mouseEntered(MouseEvent mouse){ }   
        public void mouseExited(MouseEvent mouse){ }
        public void mousePressed(MouseEvent mouse){ }
        public void mouseReleased(MouseEvent mouse){ }

        public static void main(String arg[]){
            JFrame frame = new JFrame("MousePanel");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(640,400);

            MousePanel panel = new MousePanel();
            frame.setContentPane(panel);
            frame.setVisible(true);
        }
    }

的 Java代码:

for (int i=0 ; i<50 ; i++)
            {
                pointX ++;
                repaint();

            }

3 个答案:

答案 0 :(得分:1)

  

我只得到它的最后一个点(像素)。

这就是你在paintComponent()方法中绘制的所有东西。

如果您想要所有椭圆形,那么每次调用paintComponent()方法时都需要重新绘制所有椭圆。

有关实现此目的的两种常用方法,请参阅Custom Painting Approaches

  1. 跟踪要在ArrayList中绘制的所有对象,然后每次调用paintComponent()时遍历List
  2. 将对象绘制到BufferedImage,然后在paintComponent()方法中绘制BufferedImage。

答案 1 :(得分:0)

重绘将始终绘制组件的固定结束状态..

而且,由于您在一次回调中请求重绘,您将获得以下

x=1
repaint 
x=2
repaint 
...
etc.

重绘本身直到完成循环才会发生,并且可以处理下一个UI事件(这是您的重绘请求)。大约50个重绘请求可能会合并为一个,再次调用paintComponent。

现在油漆看到它应该使用你当前的x值绘制一个5px的椭圆形,并且这样做。

所以你可能会用一个重绘请求替换for循环,并将paintComponent更改为在oldX,oldY和pointX之间绘制,pointY

答案 2 :(得分:0)

你正在重新涂抹椭圆形50次。我不太确定你想做什么。如果要填充宽度/高度为50像素的椭圆,可以更新方法paintComponent

   public void paintComponent(Graphics g){
    g.fillOval(pointX, pointY, 50, 50);
}

在这种情况下,for循环不是必需的,只有重绘就足够了。

如果你想绘制一条线,那就是drawLine方法。我看到你已经存储了旧的像素位置,所以你可以去

    public void paintComponent(Graphics g){
       g.drawLine(pointX, pointY, oldX, oldY);
    }

同样,只需要重新绘制并且没有循环。我已经发布了以下代码

public class MousePanel extends JPanel implements MouseListener {

int pointX, pointY, oldX, oldY;

public MousePanel(){
    super();
    addMouseListener(this);
}

public void mouseClicked(MouseEvent mouse){


    // Tell the panel that we need to redraw things.
    oldX=pointX;
    oldY=pointY;
    // Get the location of the current mouse click.
    pointX = mouse.getX();
    pointY = mouse.getY();
    // Tell the panel that we need to redraw things.
    repaint();
    System.out.println("x:"+pointX+", y:"+pointY);

}

public void paintComponent(Graphics g){
    g.drawLine(pointX, pointY, oldX, oldY);
}

public void mouseEntered(MouseEvent mouse){ }
public void mouseExited(MouseEvent mouse){ }
public void mousePressed(MouseEvent mouse){ }
public void mouseReleased(MouseEvent mouse){ }

public static void main(String arg[]){
    JFrame frame = new JFrame("MousePanel");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(640,400);

    MousePanel panel = new MousePanel();
    frame.setContentPane(panel);
    frame.setVisible(true);
}

}