为什么我用这段代码画不出椭圆?

5
包测试;
导入java.awt.*; 导入java.awt.event.*; 导入java.awt.geom.Ellipse2D; 导入javax.swing.*; 导入java.awt.image.BufferedImage; public class test_bmp extends JPanel implements MouseListener,MouseMotionListener,ActionListener { static BufferedImage image; Color color; Point start=new Point(); Point end =new Point(); JButton elipse=new JButton("椭圆"); JButton rectangle=new JButton("矩形"); JButton line=new JButton("直线"); String selected; public test_bmp() { color = Color.black; setBorder(BorderFactory.createLineBorder(Color.black)); addMouseListener(this); addMouseMotionListener(this); } public void paintComponent(Graphics g) { //super.paintComponent(g); g.drawImage(image, 0, 0, this); Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.black); if(selected=="elipse") { g2.drawOval(start.x, start.y, (end.x-start.x),(end.y-start.y)); System.out.println("开始 : "+start.x+","+start.y); System.out.println("结束 : "+end.x+","+end.y); } if(selected=="line") g2.drawLine(start.x,start.y,end.x,end.y); } //在缓冲图像上绘制 public void draw() { Graphics2D g2 = image.createGraphics(); g2.setPaint(color); System.out.println("画"); if(selected=="line") g2.drawLine(start.x, start.y, end.x, end.y); if(selected=="elipse") { g2.drawOval(start.x, start.y, (end.x-start.x),(end.y-start.y)); System.out.println("开始 : "+start.x+","+start.y); System.out.println("结束 : "+end.x+","+end.y); } repaint(); g2.dispose(); } public JPanel addButtons() { JPanel buttonpanel=new JPanel(); buttonpanel.setBackground(color.lightGray); buttonpanel.setLayout(new BoxLayout(buttonpanel,BoxLayout.Y_AXIS)); elipse.addActionListener(this); rectangle.addActionListener(this); line.addActionListener(this); buttonpanel.add(elipse); buttonpanel.add(Box.createRigidArea(new Dimension(15,15))); buttonpanel.add(rectangle); buttonpanel.add(Box.createRigidArea(new Dimension(15,15))); buttonpanel.add(line); return buttonpanel; } public static void main(String args[]) { test_bmp application=new test_bmp(); //主窗口 JFrame frame=new JFrame("白板"); frame.setLayout(new BorderLayout()); frame.add(application.addButtons(),BorderLayout.WEST); frame.add(application); //窗口大小 frame.setSize(600,400); frame.setLocation(0,0); frame.setVisible(true); int w = frame.getWidth(); int h = frame.getHeight(); image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = image.createGraphics(); g2.setPaint(Color.white); g2.fillRect(0,0,w,h); g2.dispose(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent event) { start = event.getPoint(); } @Override public void mouseReleased(MouseEvent event) { end = event.getPoint(); draw(); } @Override public void mouseDragged(MouseEvent e) { end=e.getPoint(); repaint(); } @Override public void mouseMoved(MouseEvent arg0) { // TODO Auto-generated method stub
} @Override public void actionPerformed(ActionEvent e) { if(e.getSource()==elipse) selected="elipse"; if(e.getSource()==line) selected="line"; draw();
} }

我需要创建一个绘图应用程序。当我通过从左到右拖动鼠标来绘制椭圆时,它没有显示出来。为什么?我应该在这里使用其他函数吗?

1个回答

9

当你向下和向右拖动鼠标时,你的程序确实会画一个椭圆。但是向上或向左拖动则无法工作,因为Graphics.drawOval不支持负宽度或高度。

尝试添加以下方法:

private Shape createEllipse() {
    Ellipse2D e = new Ellipse2D.Double();
    e.setFrameFromDiagonal(start, end);
    return e;
}

然后在drawpaintComponent中像这样调用它:
if(selected=="elipse") {
    g2.draw(createEllipse());
}

另外,您可能不需要在 actionPerformed 的结尾调用 draw()。如果您在线条和椭圆模式之间切换,则会绘制一个具有与最近的线条相同坐标的椭圆形,反之亦然。
还有一个编码风格的问题:为 selected 使用字符串文字是令人困惑的(尽管它确实可以工作)。我建议改用枚举。

谢谢,它运行良好,但我无法理解其中的逻辑。能否解释一下? - swift
该方法的目的是构造一个矩形,其中start在一个角落(可以是4个角落中的任意一个),而end在对角线的另一个角落,并将该矩形用作椭圆的边界框。我改为使用setFrameFromDiagonal。希望现在更清晰了。 - finnw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接