Java:鼠标单击时绘制矩形

时间:2016-03-01 20:39:37

标签: java

我想在每次用户点击"矩形"时绘制一个矩形。按钮,然后根据事件x和y坐标单击JFrame。我有一个绘制矩形的组件类,我有另一个具有JFrame鼠标按下侦听器的类。

我的代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import javax.swing.JComponent;


public class RectangleComponent extends JComponent
{

    Rectangle box;

    RectangleComponent()
    {
        box = new Rectangle(5, 10, 20, 30);
        repaint();
    }

    RectangleComponent(int x, int y)
    {
        box = new Rectangle(x, y, 20, 30);

    }

    public void paintComponent(Graphics g)
    {  
        // Recover Graphics2D
        Graphics2D g2 = (Graphics2D) g;

        // Change the color
        Color c = new Color(1.0F,0.0F,1.0F); 
        g2.setColor(c);

        // Draw a rectangle
        g2.draw(box);


    }

}


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Test2
{
    static boolean isPressed = false;

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

        final int FRAME_WIDTH  = 400;
        final int FRAME_HEIGHT = 400;

        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        frame.setTitle("Test 2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        JPanel panel = new JPanel();
        frame.add(panel,BorderLayout.NORTH);


        final JButton btnRectangle = new JButton("Rectangle");
        panel.add(btnRectangle);

        class RectangleButtonListener implements ActionListener
        { 
            public void actionPerformed(ActionEvent event)
            {
                isPressed = true;
            }      
        }

        ActionListener rectButtonListener = new RectangleButtonListener();
        btnRectangle.addActionListener(rectButtonListener);


        class MousePressListener implements MouseListener
        {
            public void mousePressed(MouseEvent event)
            {
                int x = event.getX() ; 
                int y = event.getY() ;


                if(isPressed)
                {

                    RectangleComponent rc = new RectangleComponent(x, y); 
                    frame.add(rc);


                }


            }

            public void mouseReleased(MouseEvent event){}
            public void mouseClicked(MouseEvent event){}
            public void mouseEntered(MouseEvent event){}
            public void mouseExited(MouseEvent event){}
        }

        MousePressListener mListener = new MousePressListener();
        frame.addMouseListener(mListener);


        frame.setVisible(true);
    }

}

现在它似乎正在做我想要的,但是以非常奇怪的方式。如果我单击矩形并单击框架,我什么也看不见,但如果我最大化框架,则矩形出现在我单击的位置。为什么会发生这种情况?修复是什么?

3 个答案:

答案 0 :(得分:2)

首先,当使用paintComponent()时,您需要覆盖它并调用它的超级方法,如下所示:

@Override
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
}

其次,这是您的RectangleComponent类,稍作修改:

public class RectangleComponent extends JComponent
{
    int x, y;

    RectangleComponent(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Color c = new Color(1.0F,0.0F,1.0F);
        g.setColor(c);

        g.drawRect(x, y, 50, 50);
    }
}

我获取了x和y变量并将它们作为成员变量,因此我们可以使用paintComponent()方法访问它们。我还删除了整个“盒子”的想法,并在paintCompnent()

中完成了所有绘图

您还应对Test2 Class进行一些细微修改;

个人推荐,我建议您将绘图代码切换到mouseReleased事件。在JFrame上调用revalidate() and repaint()

public void mouseReleased(MouseEvent event)
{
    int x = event.getXOnScreen();
    int y = event.getYOnScreen();

    if(isPressed)
    {
        RectangleComponent rc = new RectangleComponent(x, y);
        frame.add(rc);
        frame.revalidate();
        frame.repaint();
    }
}

我的结果:

Boxes!

答案 1 :(得分:1)

最大化帧会自动调用repaint()。将repaint()添加到框架后调用RectangleComponent可能最简单。

if(isPressed)
{    
    RectangleComponent rc = new RectangleComponent(x, y); 
    frame.add(rc);
    rc.repaint();
}

答案 2 :(得分:-1)

我认为不是在点击时添加新组件,为什么不只是通过向其添加更多内容然后重新绘制它来更新已存在的组件。

这是如何修复的:

import javax.swing.JComponent ;

import java.awt.event.MouseListener ;
import java.awt.event.MouseEvent ;
import java.awt.Component;
import java.awt.Graphics2D ;
import java.awt.Graphics ;
import java.awt.Shape ;
import java.util.ArrayList ;

public class ShapeComponent extends JComponent
{
      private ArrayList<Shape> shapes ;

      public ShapeComponent(ArrayList<Shape> shapes1)
      {
          shapes = shapes1;
      }

      public void paintComponent(Graphics g)
      {  

          Graphics2D g2 = (Graphics2D) g;

          for (Shape shape : shapes)
          {
              g2.draw(shape);
          }

        }
}

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Test3 
{
    static boolean isPressed = false;
    static ArrayList<Shape> shapes = new ArrayList<Shape>() ;

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

        final int FRAME_WIDTH  = 400;
        final int FRAME_HEIGHT = 400;

        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        frame.setTitle("Test 2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        JPanel panel = new JPanel();
        frame.add(panel,BorderLayout.NORTH);


        final JButton btnRectangle = new JButton("Rectangle");
        panel.add(btnRectangle);

        class RectangleButtonListener implements ActionListener
        { 
            public void actionPerformed(ActionEvent event)
            {
                isPressed = true;
            }      
        }

        ActionListener rectButtonListener = new RectangleButtonListener();
        btnRectangle.addActionListener(rectButtonListener);

        final JComponent component = new ShapeComponent(shapes) ;
        frame.add(component);


        class MousePressListener implements MouseListener
        {
            public void mousePressed(MouseEvent event)
            {
                int x = event.getX() ; 
                int y = event.getY() ;

                System.out.println("you have press the mouse at X : " + x + " and Y : " + y);

                if(isPressed)
                {
                    Rectangle rnew = new Rectangle(x, y, 20, 30);
                    shapes.add(rnew);
                    component.repaint();

                    System.out.println("the button is pressed");
                }
                else
                {
                    System.out.println("the button is NOT pressed");
                }

            }

            public void mouseReleased(MouseEvent event){}
            public void mouseClicked(MouseEvent event){}
            public void mouseEntered(MouseEvent event){}
            public void mouseExited(MouseEvent event){}
        }

        MousePressListener mListener = new MousePressListener();
        frame.addMouseListener(mListener);



        frame.setVisible(true);
    }
}