我正在制作一个根据用户输入绘制不同形状的程序。按下并拖动光标时绘制形状。但由于某些原因,无论何时按下光标,形状都会在光标下方约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);
}
}
答案 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)
不要将侦听器添加到框架中,直接将它们添加到ShapeDrawer
。 MouseEvent
是生成事件的组件源的上下文。
框架的左上角将是0x0
,但由于框架的边框,框架内容将偏移框架内的多个像素。
例如......
考虑使用KeyListener