gpt4 book ai didi

java - 在 Jpanel 上绘制多个形状时出现歧义

转载 作者:行者123 更新时间:2023-11-29 05:51:58 25 4
gpt4 key购买 nike

下面的代码有几个问题:

1) 多边形连接最后一个点和第一个点本身,不应该自己做,但用户应该绘制它。

2) 点击其他形状后多边形线条消失。

package Circles;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;

import javax.swing.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Iterator;

//////////////////////////////////////////////////////////////PaintDemo
class PaintDemo2 {
//============================================================= main
public static void main(String[] args) {
PaintWindow2 window = new PaintWindow2();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}//end main
}//endclass PaintDemo


@SuppressWarnings("serial")
////////////////////////////////////////////////////////////PaintWindow
class PaintWindow2 extends JFrame {
PaintPanel2 canvas = new PaintPanel2();
//====================================================== constructor
public PaintWindow2() {
//--- create the buttons
JButton circleButton = new JButton("Circle");
circleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
canvas.setShape(PaintPanel2.CIRCLE);
}});
JButton rectangleButton = new JButton("Rectangle");
rectangleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
canvas.setShape(PaintPanel2.Ellipse);
}});

JButton polyButton = new JButton("Polygon");
polyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
canvas.setShape(PaintPanel2.POLY);
}});

//--- layout the buttons
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2, 1));
buttonPanel.add(circleButton);
buttonPanel.add(rectangleButton);
buttonPanel.add(polyButton);

//--- layout the window
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
content.add(buttonPanel, BorderLayout.WEST);
content.add(canvas , BorderLayout.CENTER);
this.setTitle("Paint Demo");
this.pack();
}//end constructor
}//endclass PaintWindow


///////////////////////////////////////////////////////////// PaintPanel2
@SuppressWarnings("serial")
class PaintPanel2 extends JPanel implements MouseListener,
MouseMotionListener {
//--- Public constants used to specify shape being drawn.
public static final int NONE = 0;
public static final int LINE = 1;
public static final int Ellipse = 2;
public static final int CIRCLE = 3;
public static final int POLY = 4;

//--- Variables to store the current figure info
private int _shape = NONE;
public int getShape() {
return _shape;
}

private int _currentStartX = 0; // where mouse first pressed
private int _currentStartY = 0;
private int _currentEndX = 0; // where dragged to or released
private int _currentEndY = 0;

//--- BufferedImage to store the underlying saved painting.
// Will be initialized first time paintComponent is called.
private BufferedImage _bufImage = null;
private boolean polygonIsNowComplete = false;

//--- Private constant for size of paint area.
private static final int SIZE = 600; // size of paint area

private final Point trackPoint = new Point();
private Path2D currentShape;
private ArrayList<Path2D> lstPloys = new ArrayList<Path2D>();;
private Point lastPoint;
private Point currentPoint;
@SuppressWarnings("rawtypes")
private ArrayList points = new ArrayList();


//====================================================== constructor
public PaintPanel2() {
setPreferredSize(new Dimension(SIZE, SIZE));
setBackground(Color.white);
//--- Add the mouse listeners.
this.addMouseListener(this);
this.addMouseMotionListener(this);
}//endconstructor


//========================================================= setShape
public void setShape(int shape) {
//--- Provided so users can set the shape.
_shape = shape;
}//end setShape


//=================================================== paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g; // downcast to Graphics2D
if (_bufImage == null) {
//--- This is the first time, initialize _bufImage
int w = this.getWidth();
int h = this.getHeight();
_bufImage = (BufferedImage)this.createImage(w, h);
Graphics2D gc = _bufImage.createGraphics();
gc.setColor(Color.white);
gc.fillRect(0, 0, w, h); // fill in background
}
g2.drawImage(_bufImage, null, 0, 0); // draw previous shapes

drawCurrentShape(g2);
}//end paintComponent


//================================================= drawCurrentShape
private void drawCurrentShape(Graphics2D g2) {
//--- Draws current shape on a graphics context, either
// on the context passed to paintComponent, or the
// context for the BufferedImage.
switch (_shape) {
case NONE :
break;

case CIRCLE:
g2.drawOval(_currentStartX, _currentStartY,
_currentEndX - _currentStartX,
_currentEndY - _currentStartY);
break;

case Ellipse:
g2.draw(new Ellipse2D.Double(_currentStartX, _currentStartY,
_currentEndX - _currentStartX,
_currentEndY - _currentStartY));
break;

case POLY:

drawPolyGon(g2);
break;

default: // should never happen
g2.drawString("Huh?", 10, 20);
break;
}
}//end paintComponent



private void drawPolyGon(Graphics2D g2) {

g2.create();
if (lastPoint != null) {
g2.setColor(Color.RED);
g2.fillOval(lastPoint.x - 2, lastPoint.y - 2, 4, 4);
}
if (currentShape != null) {
g2.setColor(Color.RED);
g2.draw(currentShape);
if (lastPoint != null && currentPoint != null) {
g2.setColor(new Color(255, 0, 0, 64));
g2.draw(new Line2D.Float(lastPoint, currentPoint));

}
}
g2.setColor(Color.BLACK);
for (Path2D shape : lstPloys) {
g2.draw(shape);
}
g2.dispose();

// TODO Auto-generated method stub

}


//===================================================== mousePressed
public void mousePressed(MouseEvent e) {
_currentStartX = e.getX(); // save x coordinate of the click
_currentStartY = e.getY(); // save y
_currentEndX = _currentStartX; // set end to same pixel
_currentEndY = _currentStartY;
}//end mousePressed

//===================================================== mouseDragged
public void mouseDragged(MouseEvent e) {

_currentEndX = e.getX(); // save new x and y coordinates
_currentEndY = e.getY();
this.repaint();
// show new shape
}//end mouseDragged

//==================================================== mouseReleased
public void mouseReleased(MouseEvent e) {
// This will save the shape that has been dragged by
// drawing it onto the bufferedImage where all shapes
// are written.
_currentEndX = e.getX(); // save ending coordinates
_currentEndY = e.getY();

//--- Draw the current shape onto the buffered image.
Graphics2D grafarea = _bufImage.createGraphics();
drawCurrentShape(grafarea);

this.repaint();
}//end mouseReleased


public void mouseMoved (MouseEvent e) {

if (currentShape != null) {
currentPoint = e.getPoint();
repaint();
} else {
currentPoint = null;
}


}
public void mouseEntered (MouseEvent e) {}
public void mouseExited (MouseEvent e) {}
public void mouseClicked (MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
if (e.getClickCount() == 1) {
Point p = e.getPoint();
lastPoint = p;
if (currentShape == null) {
currentShape = new Path2D.Float();
currentShape.moveTo(p.x, p.y);
} else {
currentShape.lineTo(p.x, p.y);
}
repaint();
} else if (e.getClickCount() == 2) {
currentShape.closePath();
lstPloys.add(currentShape);
currentShape = null;
lastPoint = null;
repaint();
}
}


}
}

最佳答案

绘制周期是无状态的,也就是说,图形的内容不会从一个周期传递到另一个周期。

您需要在每个绘制周期重新绘制组件的全部内容。

您已尝试实现双缓冲区解决方案,但您没有传递缓冲区的图形上下文,而是传递了绘制系统提供给您的图形内容。如果您将缓冲区的图形上下文传递给 drawCurrentShape 方法,它可能会解决您的问题(并消除缓存所有形状的需要)

已更新

因此,在 PaintPanel2 组件的 paintComponent 方法中,您正在创建一个 BufferedImage,但您并未为其绘制组件...

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

Graphics2D g2 = (Graphics2D)g; // downcast to Graphics2D
if (_bufImage == null) {
//--- This is the first time, initialize _bufImage
int w = this.getWidth();
int h = this.getHeight();
_bufImage = (BufferedImage)this.createImage(w, h);
Graphics2D gc = _bufImage.createGraphics();
gc.setColor(Color.white);
gc.fillRect(0, 0, w, h); // fill in background
}
g2.drawImage(_bufImage, null, 0, 0); // draw previous shapes

drawCurrentShape(g2);
}//end paintComponent

相反,您应该使用从缓冲图像到 drawCurrentShape

的图形上下文
public void paintComponent(Graphics g) {
super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g; // downcast to Graphics2D
Graphics2D gc = null;
if (_bufImage == null) {
//--- This is the first time, initialize _bufImage
int w = this.getWidth();
int h = this.getHeight();
_bufImage = (BufferedImage)this.createImage(w, h);
gc = _bufImage.createGraphics();
gc.setColor(Color.white);
gc.fillRect(0, 0, w, h); // fill in background
} else {
gc = _bufImage.createGraphics();
}
drawCurrentShape(g2);
gc.dispose();

g2.drawImage(_bufImage, null, 0, 0); // draw previous shapes
}//end paintComponent

需要注意的是,这可能会产生一些其他问题,但这个概念是合理的。

就个人而言,我更喜欢保留所有形状的 List 并重新绘制它们。这使您能够选择、移动、删除、重新排序和更改程序中的所有形状,并提供一种历史记录 ;)

关于java - 在 Jpanel 上绘制多个形状时出现歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13560264/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com