鼠标监听器没有给出正确的分数

时间:2014-05-23 01:57:49

标签: java swing user-interface listener shapes

我正在制作一个根据用户输入绘制不同形状的程序。按下并拖动光标时绘制形状。但由于某些原因,无论何时按下光标,形状都会在光标下方约25个像素处开始。任何人都知道为什么以及如何解决它?

我的代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;


public class DrawShapes extends JFrame
{
    private JLabel display;
    private Point point1, point2;
    private ShapeDrawer drawer;

public DrawShapes()
{
    Container contain = getContentPane();

    point1 = null;
    point2 = null;

    //Setup JLabel and add it to container
    display = new JLabel("Line");
    contain.add(display, BorderLayout.SOUTH);

    //Setup JPanel and add it to top of container
    drawer = new ShapeDrawer();
    drawer.setPreferredSize(new Dimension(500,500));
    contain.add(drawer, BorderLayout.NORTH);

    //Setup listeners
    ShapeListener  listener = new ShapeListener();
    addKeyListener(listener);
    addMouseListener(listener);
    addMouseMotionListener(listener);

    setTitle("Press l for line, o for oval, r for rectangle");
    pack();
    setVisible(true);
}

//Class for drawing shapes
private class ShapeDrawer extends JPanel
{
    public void paintComponent(Graphics paint)
    {
        super.paintComponent(paint);

        Graphics2D g2 = (Graphics2D) paint;
        setBackground(Color.white);
        g2.setColor(Color.black);

        //Draw different shapes based on user input
        if(point1 != null && point2 != null)
        {
            if(display.getText().equals("Circle"))
            {
                g2.fillOval(point1.x - 6, point1.y - 6,
                        6* 2, 6 * 2);
            }
            else if(display.getText().equals("Oval"))
            {
                g2.drawOval(point1.x,point1.y,point2.x,point2.y);
            }
            else if(display.getText().equals("Line"))
            {
                g2.drawLine(point1.x, point1.y, point2.x, point2.y);
            }
            else if(display.getText().equals("Rectangle"))
            {
                g2.drawRect(point1.x, point1.y, point2.x, point2.y);
            }
        }
    }
}

private class ShapeListener implements MouseListener, MouseMotionListener ,KeyListener
{
    //Change the label if something else is pressed
    public void keyPressed(KeyEvent event)
    {
        if(event.getKeyText(event.getKeyCode()).equals("C"))
            display.setText("Circle");
        else if(event.getKeyText(event.getKeyCode()).equals("O"))
            display.setText("Oval");
        else if(event.getKeyText(event.getKeyCode()).equals("R"))
            display.setText("Rectangle");
        else if(event.getKeyText(event.getKeyCode()).equals("L"))
            display.setText("Line");
    }       

    public void keyReleased(KeyEvent event){};
    public void keyTyped(KeyEvent event){};

    //Get first point where mouse is pressed
    public void mousePressed(MouseEvent event)
    {
        point1 = event.getPoint();

    }

    //Get the point while mouse is being pressed
    public void mouseDragged(MouseEvent event) 
    {
        point2 = event.getPoint();
        drawer.repaint();

    }

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



}
}

和主要方法

import javax.swing.JFrame;
class ShapesViewer
{
public static void main(String[] args)
{
    DrawShapes shapes = new DrawShapes();

    shapes.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

2 个答案:

答案 0 :(得分:2)

您需要将MouseListener添加到绘图JPanel而不是JFrame。

改变这个:

ShapeListener  listener = new ShapeListener();
addMouseListener(listener);
addMouseMotionListener(listener);

到此:

drawer.ShapeListener  listener = new ShapeListener();
drawer.addMouseListener(listener);
drawer.addMouseMotionListener(listener);

由于菜单栏,JFrame中点的位置比JPanel高25个​​点。

答案 1 :(得分:1)

不要将侦听器添加到框架中,直接将它们添加到ShapeDrawerMouseEvent是生成事件的组件源的上下文。

框架的左上角将是0x0,但由于框架的边框,框架内容将偏移框架内的多个像素。

例如......

Example

考虑使用KeyListener

key bindings API