删除 java 个图形中的绘制线
Deleting drawn line in java graphics
我有一个列表,其中包含我在 gui 上绘制的线条。我希望能够 select 一行并通过单击该行将其删除。我可以 select 并删除,但问题是重绘方法会在我这样做时擦除所有绘制的线条。当我开始绘制新线时,减去先前删除的线的线重新出现。
我觉得可能是因为迭代器,但我不完全确定。任何人都可以帮助解决这个问题吗?还是我做错了?
这是我的代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LinesDemo extends JPanel {
private List<Line2D> linesList = new ArrayList<>();
private List<Line2D> lineCollection = new ArrayList<>();
private Line2D line = null;
Point pointStart = null;
Point pointEnd = null;
// Width and height of rectangular region around mouse
// pointer to use for hit detection on lines
private static final int HIT_BOX_SIZE = 4;
/**
* Create the panel.
*/
public LinesDemo() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
pointStart = e.getPoint();
line = new Line2D.Double(e.getPoint(), e.getPoint());
linesList.add(line);
}
@Override
public void mouseReleased(MouseEvent e) {
pointStart = null;
}
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
getClickedLine(x, y);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
pointEnd = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
pointEnd = e.getPoint();
line.setLine(pointStart, pointEnd);
lineCollection.add(line);
repaint();
}
});
}
private Shape getClickedLine(int x, int y) {
int boxX = x - HIT_BOX_SIZE / 2;
int boxY = y - HIT_BOX_SIZE / 2;
int width = HIT_BOX_SIZE;
int height = HIT_BOX_SIZE;
for(Line2D selectedLine:lineCollection) {
if (selectedLine.intersects(boxX, boxY, width, height)) {
System.out.println("intersects!");
removeLine(selectedLine);
return selectedLine;
}
}
return null;
}
private void removeLine(Line2D line) {
Iterator<Line2D> it = lineCollection.iterator();
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaint();
}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if(pointStart != null) {
g2d.setPaint(Color.RED);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(Shape content : lineCollection){
g2d.draw(content);
}
g2d.dispose();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving and Scaling");
LinesDemo m = new LinesDemo();
frame.add(m);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
UPD2:
您的代码已修复。还有很多其他问题,例如:每次拖动鼠标时都会在列表中添加一个点,等等。
它远非完美,但已经有足够的变化供您分析。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LinesDemo extends JPanel {
private List<Line2D> linesList = new ArrayList<>();
private Line2D line = new Line2D.Double();
Point pointStart = null;
Point pointEnd = null;
// Width and height of rectangular region around mouse
// pointer to use for hit detection on lines
private static final int HIT_BOX_SIZE = 4;
/**
* Create the panel.
*/
public LinesDemo() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
pointStart = e.getPoint();
pointEnd = e.getPoint();
line = new Line2D.Double(pointStart, pointEnd);
linesList.add(line);
}
@Override
public void mouseReleased(MouseEvent e) {
line.setLine(pointStart, pointEnd);
pointStart = null;
}
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
getClickedLine(x, y);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
pointEnd = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
pointEnd = e.getPoint();
line.setLine(pointStart, pointEnd);
repaint();
}
});
}
private Shape getClickedLine(int x, int y) {
int boxX = x - HIT_BOX_SIZE / 2;
int boxY = y - HIT_BOX_SIZE / 2;
int width = HIT_BOX_SIZE;
int height = HIT_BOX_SIZE;
for(Line2D selectedLine:linesList) {
if (selectedLine.intersects(boxX, boxY, width, height)) {
System.out.println("intersects!");
removeLine(selectedLine);
return selectedLine;
}
}
return null;
}
private void removeLine(Line2D line) {
Iterator<Line2D> it = linesList.iterator();
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaint();
}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(Color.RED);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(Shape content : linesList){
g2d.draw(content);
}
g2d.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving and Scaling");
LinesDemo m = new LinesDemo();
frame.add(m);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
原文:
我不能 运行 你的程序,但你可以尝试替换
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaint();
}
}
和
boolean repaintNeeded = false;
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaintNeeded = true;
}
}
if (repaintNeeded) {
repaint();
}
UPD1:
我能够 运行 你的代码。
其实有很多地方需要改进。
具体针对您的问题,这两件事导致您的线条未被绘制:
@Override
public void mouseReleased(MouseEvent e) {
pointStart = null;
}
和
if(pointStart != null) {
所以每次松开鼠标,你的代码都不会绘制任何东西。
线条消失的原因是您在 paintComponent()
:
中明确抑制了它们的绘制
if (pointStart != null) {
pointStart
已在 mouseReleased
中设置为 null
,因此绘制了 none 条线。删除该检查,您的代码将按预期工作。
附带说明一下,您应该在 event dispatch thread 中创建 GUI。
我有一个列表,其中包含我在 gui 上绘制的线条。我希望能够 select 一行并通过单击该行将其删除。我可以 select 并删除,但问题是重绘方法会在我这样做时擦除所有绘制的线条。当我开始绘制新线时,减去先前删除的线的线重新出现。
我觉得可能是因为迭代器,但我不完全确定。任何人都可以帮助解决这个问题吗?还是我做错了?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LinesDemo extends JPanel {
private List<Line2D> linesList = new ArrayList<>();
private List<Line2D> lineCollection = new ArrayList<>();
private Line2D line = null;
Point pointStart = null;
Point pointEnd = null;
// Width and height of rectangular region around mouse
// pointer to use for hit detection on lines
private static final int HIT_BOX_SIZE = 4;
/**
* Create the panel.
*/
public LinesDemo() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
pointStart = e.getPoint();
line = new Line2D.Double(e.getPoint(), e.getPoint());
linesList.add(line);
}
@Override
public void mouseReleased(MouseEvent e) {
pointStart = null;
}
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
getClickedLine(x, y);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
pointEnd = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
pointEnd = e.getPoint();
line.setLine(pointStart, pointEnd);
lineCollection.add(line);
repaint();
}
});
}
private Shape getClickedLine(int x, int y) {
int boxX = x - HIT_BOX_SIZE / 2;
int boxY = y - HIT_BOX_SIZE / 2;
int width = HIT_BOX_SIZE;
int height = HIT_BOX_SIZE;
for(Line2D selectedLine:lineCollection) {
if (selectedLine.intersects(boxX, boxY, width, height)) {
System.out.println("intersects!");
removeLine(selectedLine);
return selectedLine;
}
}
return null;
}
private void removeLine(Line2D line) {
Iterator<Line2D> it = lineCollection.iterator();
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaint();
}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if(pointStart != null) {
g2d.setPaint(Color.RED);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(Shape content : lineCollection){
g2d.draw(content);
}
g2d.dispose();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving and Scaling");
LinesDemo m = new LinesDemo();
frame.add(m);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
UPD2:
您的代码已修复。还有很多其他问题,例如:每次拖动鼠标时都会在列表中添加一个点,等等。 它远非完美,但已经有足够的变化供您分析。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LinesDemo extends JPanel {
private List<Line2D> linesList = new ArrayList<>();
private Line2D line = new Line2D.Double();
Point pointStart = null;
Point pointEnd = null;
// Width and height of rectangular region around mouse
// pointer to use for hit detection on lines
private static final int HIT_BOX_SIZE = 4;
/**
* Create the panel.
*/
public LinesDemo() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
pointStart = e.getPoint();
pointEnd = e.getPoint();
line = new Line2D.Double(pointStart, pointEnd);
linesList.add(line);
}
@Override
public void mouseReleased(MouseEvent e) {
line.setLine(pointStart, pointEnd);
pointStart = null;
}
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
getClickedLine(x, y);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
pointEnd = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
pointEnd = e.getPoint();
line.setLine(pointStart, pointEnd);
repaint();
}
});
}
private Shape getClickedLine(int x, int y) {
int boxX = x - HIT_BOX_SIZE / 2;
int boxY = y - HIT_BOX_SIZE / 2;
int width = HIT_BOX_SIZE;
int height = HIT_BOX_SIZE;
for(Line2D selectedLine:linesList) {
if (selectedLine.intersects(boxX, boxY, width, height)) {
System.out.println("intersects!");
removeLine(selectedLine);
return selectedLine;
}
}
return null;
}
private void removeLine(Line2D line) {
Iterator<Line2D> it = linesList.iterator();
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaint();
}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(Color.RED);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(Shape content : linesList){
g2d.draw(content);
}
g2d.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving and Scaling");
LinesDemo m = new LinesDemo();
frame.add(m);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
原文: 我不能 运行 你的程序,但你可以尝试替换
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaint();
}
}
和
boolean repaintNeeded = false;
while(it.hasNext()) {
Line2D selectedLine = it.next();
if(selectedLine.equals(line)) {
it.remove();
repaintNeeded = true;
}
}
if (repaintNeeded) {
repaint();
}
UPD1: 我能够 运行 你的代码。 其实有很多地方需要改进。 具体针对您的问题,这两件事导致您的线条未被绘制:
@Override
public void mouseReleased(MouseEvent e) {
pointStart = null;
}
和
if(pointStart != null) {
所以每次松开鼠标,你的代码都不会绘制任何东西。
线条消失的原因是您在 paintComponent()
:
if (pointStart != null) {
pointStart
已在 mouseReleased
中设置为 null
,因此绘制了 none 条线。删除该检查,您的代码将按预期工作。
附带说明一下,您应该在 event dispatch thread 中创建 GUI。