创建在插入每个点后更新的多边形
Create Polygon that update after the insertion of every point
我在学校项目中遇到问题,我在其中创建了一个多边形,当我插入点时,多边形会在插入每个点后更新。
例如
我的程序:
我想要的结果:
我的理解是,为了让它看起来像结果,删除 Point3 和 Point1 之间的 link,新的将在 Point4 和 Point1 之间。如果这是解决方案,我不知道要在我的代码中添加什么来修复它。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;
import java.util.*;
public class ShapesByMouseDrag3 extends JFrame {
private static final int FW = 800;
private static final int FH = 600;
private Point p1;
private Point p2;
private int x;
private int y;
ArrayList<Integer> alX = new ArrayList<>();
ArrayList<Integer> alY = new ArrayList<>();
JRadioButton lineRB = new JRadioButton("Line");
JRadioButton rectRB = new JRadioButton("Rectangle");
JRadioButton Ellipse = new JRadioButton("Ellipse");
JRadioButton PolygonRB = new JRadioButton("Polygon");
public static void main(String[] args) {
new ShapesByMouseDrag3();
}
public ShapesByMouseDrag3() {
setSize(FW, FH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Draw Graphics Objects by Mouse Drag");
setLocationRelativeTo(null);
setLayout(new BorderLayout());
PaintPanel paintPanelObj = new PaintPanel(FW, FH);
JPanel chooseShapePanel = new JPanel();
chooseShapePanel.setBackground(Color.WHITE);
chooseShapePanel.setLayout(new GridLayout(4, 1));
chooseShapePanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Shapes"));
//Create the radio buttons.
//Create a button group and add buttons
ButtonGroup bgroup = new ButtonGroup();
bgroup.add(lineRB);
bgroup.add(rectRB);
bgroup.add(Ellipse);
bgroup.add(PolygonRB);
// add buttons to chooseShapePanel panel
chooseShapePanel.add(lineRB);
chooseShapePanel.add(rectRB);
chooseShapePanel.add(Ellipse);
chooseShapePanel.add(PolygonRB);
add(paintPanelObj, BorderLayout.CENTER);
add(chooseShapePanel, BorderLayout.WEST);
setVisible(true);
pack();
}
private class PaintPanel extends JPanel {
private int PW; // panel-width
private int PH; // panel-height
Collection<Shape> shapeList = new ArrayList<Shape>();
Collection<Shape> shapeListR = new ArrayList<Shape>();
public PaintPanel(int W, int H) {
PW = W;
PH = H;
setPreferredSize(new Dimension(PW, PH)); // set width & height of panel
setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Canvas"));
addMouseListener(new MouseClickListener());
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2f));
g2.setColor(Color.blue);
if (lineRB.isSelected()) {
makeLine();
} else if (rectRB.isSelected()) {
makeRectangle();
} else if (Ellipse.isSelected()) {
makeEllipse();
} else if (PolygonRB.isSelected()) {
makePolygon();
}
// draw all the shapes stored in the collection
Iterator itr = shapeList.iterator();
while (itr.hasNext()) {
g2.draw((Shape) itr.next());
}
// reset
p1 = null;
p2 = null;
}
public void makeLine() {
if (p1 != null && p2 != null) {
shapeList.add(new Line2D.Double(p1.x, p1.y, p2.x, p2.y));
}
}
public void makeRectangle() {
double RectangleX = Math.min(p1.x, p2.x);
double RectangleY = Math.min(p1.y, p2.y);
double RectangleW = Math.abs(p1.x - p2.x);
double RectangleH = Math.abs(p1.y - p2.y);
if (p1 != null && p2 != null) {
shapeList.add(new Rectangle2D.Double(RectangleX, RectangleY, RectangleW, RectangleH));
}
}
public void makeEllipse() {
double EllipseX = Math.min(p1.x, p2.x);
double EllipseY = Math.min(p1.y, p2.y);
double EllipseW = Math.abs(p1.x - p2.x);
double EllipseH = Math.abs(p1.y - p2.y);
if (p1 != null && p2 != null) {
shapeList.add(new Ellipse2D.Double(EllipseX, EllipseY, EllipseW, EllipseH));
}
}
public void makePolygon() {
int[] xArray = new int[alX.size()];
int[] yArray = new int[alY.size()];
for (int i = 0; i < alX.size(); i++) {
xArray[i] = alX.get(i);
yArray[i] = alY.get(i);
}
if (p1 != null && p2 != null) {
shapeList.add(new Polygon(xArray, yArray, xArray.length));
}
}
private class MouseClickListener extends MouseAdapter {
public void mousePressed(MouseEvent event) {
p1 = new Point(event.getX(), event.getY());
alX.add(p1.x);
alY.add(p1.y);
}
public void mouseEntered(MouseEvent event) {
alX.clear();
alY.clear();
}
public void mouseReleased(MouseEvent event) {
p2 = new Point(event.getX(), event.getY());
alX.add(p2.x);
alY.add(p2.y);
repaint();
}
}
}
}
不要使用 paintComponent
来构建形状,这不是 paintComponent
的用途。
我会使用 Path2D
(优于 Polygon
),因为您可以更轻松地向 Path2D
添加新点。
下面是一个简单的例子,它使用两个Path2D
实例来跟踪形状。第一个是我们不断添加点的“开放”路径,第二个是第一个的“封闭”副本。这是故意的,就好像你在每次点击后关闭形状,它只会绘制从第一个点击点延伸的线。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Path2D polygon = null;
// Give some guidence
private Point lastClickPoint = null;
private Point currentMousePoint = null;
public TestPane() {
MouseAdapter ma = new MouseAdapter() {
// This is the "acutal" shape been draw
// This allows us to "close" the polygon
// without it breaking the underlying shape
private Path2D mouseShape = null;
@Override
public void mouseClicked(MouseEvent e) {
if (mouseShape == null) {
mouseShape = new Path2D.Double();
mouseShape.moveTo(e.getX(), e.getY());
} else {
mouseShape.lineTo(e.getX(), e.getY());
}
polygon = new Path2D.Double();
polygon.append(mouseShape, true);
polygon.closePath();
lastClickPoint = e.getPoint();
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
currentMousePoint = e.getPoint();
repaint();
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
if (polygon != null) {
g2d.draw(polygon);
}
if (lastClickPoint != null && currentMousePoint != null) {
g2d.setColor(Color.GRAY);
g2d.draw(new Line2D.Double(lastClickPoint, currentMousePoint));
}
g2d.dispose();
}
}
}
这是一个重点示例,仅解决一个问题,您将需要修改代码以适应它。我会在每次单击鼠标时确定您要创建的形状类型,并创建一个可以绘制的“中间”形状,直到用户“提交”更改,届时将添加形状List
,但这就是我
我在学校项目中遇到问题,我在其中创建了一个多边形,当我插入点时,多边形会在插入每个点后更新。
例如
我的程序:
我想要的结果:
我的理解是,为了让它看起来像结果,删除 Point3 和 Point1 之间的 link,新的将在 Point4 和 Point1 之间。如果这是解决方案,我不知道要在我的代码中添加什么来修复它。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;
import java.util.*;
public class ShapesByMouseDrag3 extends JFrame {
private static final int FW = 800;
private static final int FH = 600;
private Point p1;
private Point p2;
private int x;
private int y;
ArrayList<Integer> alX = new ArrayList<>();
ArrayList<Integer> alY = new ArrayList<>();
JRadioButton lineRB = new JRadioButton("Line");
JRadioButton rectRB = new JRadioButton("Rectangle");
JRadioButton Ellipse = new JRadioButton("Ellipse");
JRadioButton PolygonRB = new JRadioButton("Polygon");
public static void main(String[] args) {
new ShapesByMouseDrag3();
}
public ShapesByMouseDrag3() {
setSize(FW, FH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Draw Graphics Objects by Mouse Drag");
setLocationRelativeTo(null);
setLayout(new BorderLayout());
PaintPanel paintPanelObj = new PaintPanel(FW, FH);
JPanel chooseShapePanel = new JPanel();
chooseShapePanel.setBackground(Color.WHITE);
chooseShapePanel.setLayout(new GridLayout(4, 1));
chooseShapePanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Shapes"));
//Create the radio buttons.
//Create a button group and add buttons
ButtonGroup bgroup = new ButtonGroup();
bgroup.add(lineRB);
bgroup.add(rectRB);
bgroup.add(Ellipse);
bgroup.add(PolygonRB);
// add buttons to chooseShapePanel panel
chooseShapePanel.add(lineRB);
chooseShapePanel.add(rectRB);
chooseShapePanel.add(Ellipse);
chooseShapePanel.add(PolygonRB);
add(paintPanelObj, BorderLayout.CENTER);
add(chooseShapePanel, BorderLayout.WEST);
setVisible(true);
pack();
}
private class PaintPanel extends JPanel {
private int PW; // panel-width
private int PH; // panel-height
Collection<Shape> shapeList = new ArrayList<Shape>();
Collection<Shape> shapeListR = new ArrayList<Shape>();
public PaintPanel(int W, int H) {
PW = W;
PH = H;
setPreferredSize(new Dimension(PW, PH)); // set width & height of panel
setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Canvas"));
addMouseListener(new MouseClickListener());
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2f));
g2.setColor(Color.blue);
if (lineRB.isSelected()) {
makeLine();
} else if (rectRB.isSelected()) {
makeRectangle();
} else if (Ellipse.isSelected()) {
makeEllipse();
} else if (PolygonRB.isSelected()) {
makePolygon();
}
// draw all the shapes stored in the collection
Iterator itr = shapeList.iterator();
while (itr.hasNext()) {
g2.draw((Shape) itr.next());
}
// reset
p1 = null;
p2 = null;
}
public void makeLine() {
if (p1 != null && p2 != null) {
shapeList.add(new Line2D.Double(p1.x, p1.y, p2.x, p2.y));
}
}
public void makeRectangle() {
double RectangleX = Math.min(p1.x, p2.x);
double RectangleY = Math.min(p1.y, p2.y);
double RectangleW = Math.abs(p1.x - p2.x);
double RectangleH = Math.abs(p1.y - p2.y);
if (p1 != null && p2 != null) {
shapeList.add(new Rectangle2D.Double(RectangleX, RectangleY, RectangleW, RectangleH));
}
}
public void makeEllipse() {
double EllipseX = Math.min(p1.x, p2.x);
double EllipseY = Math.min(p1.y, p2.y);
double EllipseW = Math.abs(p1.x - p2.x);
double EllipseH = Math.abs(p1.y - p2.y);
if (p1 != null && p2 != null) {
shapeList.add(new Ellipse2D.Double(EllipseX, EllipseY, EllipseW, EllipseH));
}
}
public void makePolygon() {
int[] xArray = new int[alX.size()];
int[] yArray = new int[alY.size()];
for (int i = 0; i < alX.size(); i++) {
xArray[i] = alX.get(i);
yArray[i] = alY.get(i);
}
if (p1 != null && p2 != null) {
shapeList.add(new Polygon(xArray, yArray, xArray.length));
}
}
private class MouseClickListener extends MouseAdapter {
public void mousePressed(MouseEvent event) {
p1 = new Point(event.getX(), event.getY());
alX.add(p1.x);
alY.add(p1.y);
}
public void mouseEntered(MouseEvent event) {
alX.clear();
alY.clear();
}
public void mouseReleased(MouseEvent event) {
p2 = new Point(event.getX(), event.getY());
alX.add(p2.x);
alY.add(p2.y);
repaint();
}
}
}
}
不要使用 paintComponent
来构建形状,这不是 paintComponent
的用途。
我会使用 Path2D
(优于 Polygon
),因为您可以更轻松地向 Path2D
添加新点。
下面是一个简单的例子,它使用两个Path2D
实例来跟踪形状。第一个是我们不断添加点的“开放”路径,第二个是第一个的“封闭”副本。这是故意的,就好像你在每次点击后关闭形状,它只会绘制从第一个点击点延伸的线。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Path2D polygon = null;
// Give some guidence
private Point lastClickPoint = null;
private Point currentMousePoint = null;
public TestPane() {
MouseAdapter ma = new MouseAdapter() {
// This is the "acutal" shape been draw
// This allows us to "close" the polygon
// without it breaking the underlying shape
private Path2D mouseShape = null;
@Override
public void mouseClicked(MouseEvent e) {
if (mouseShape == null) {
mouseShape = new Path2D.Double();
mouseShape.moveTo(e.getX(), e.getY());
} else {
mouseShape.lineTo(e.getX(), e.getY());
}
polygon = new Path2D.Double();
polygon.append(mouseShape, true);
polygon.closePath();
lastClickPoint = e.getPoint();
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
currentMousePoint = e.getPoint();
repaint();
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
if (polygon != null) {
g2d.draw(polygon);
}
if (lastClickPoint != null && currentMousePoint != null) {
g2d.setColor(Color.GRAY);
g2d.draw(new Line2D.Double(lastClickPoint, currentMousePoint));
}
g2d.dispose();
}
}
}
这是一个重点示例,仅解决一个问题,您将需要修改代码以适应它。我会在每次单击鼠标时确定您要创建的形状类型,并创建一个可以绘制的“中间”形状,直到用户“提交”更改,届时将添加形状List
,但这就是我