2015-08-22 70 views
1

我有一个包含gui上绘制的线条的列表。我希望能够选择一条线并通过点击该线删除它。我可以选择并删除,但问题是重绘方法删除所有绘制的线条,当我这样做。当我开始画一条新线时,线条减去先前删除的线条重新出现。在java图形中删除画线

我觉得这可能是因为迭代器,但我不完全确定。任何人都可以帮忙解决这个问题吗?还是我做错了?

Delete line2D 这里是我的代码:

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); 
} 
} 
+0

你的代码说控制台应该为它找到的每一行打印“相交”。你是否看到过这个消息(这意味着你的重绘代码不健全)或两次(表明你的移除/检测不好)?找出后,使用更多的System.println来放大这个问题。 – usr2564301

+0

@Jongware消息显示一次。 – sw2

回答

3

线消失的原因是,您明确抑制paintComponent()他们的绘画:

if (pointStart != null) { 

pointStart已被设置为nullmouseReleased,所以没有线的拿得出。删除该检查,并且您的代码应按照您的预期工作。

请注意,您应该在event dispatch thread中创建GUI。

+0

omg非常感谢你! – sw2

+0

@ sw2不客气:-) – kiheru

1

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); 
} 
} 

原文: 我无法运行您的程序,但你可以尝试用

boolean repaintNeeded = false; 
while(it.hasNext()) { 
    Line2D selectedLine = it.next(); 
    if(selectedLine.equals(line)) { 
     it.remove(); 
     repaintNeeded = true; 
    } 
} 
if (repaintNeeded) { 
    repaint(); 
} 

UPD1更换

while(it.hasNext()) { 
    Line2D selectedLine = it.next(); 
    if(selectedLine.equals(line)) { 
     it.remove(); 
     repaint(); 
    } 
} 

: 我能够运行代码。 实际上有很多事情要改进。 对于你的问题而言,这2件事导致你的线没有被抽:

@Override 
    public void mouseReleased(MouseEvent e) { 
     pointStart = null; 
    } 

if(pointStart != null) { 

所以每次松开鼠标时,你的代码将不画任何东西。

+0

不幸的是它仍然无法正常工作。仍然和以前一样。 – sw2

+0

你应该在'getClickedLine'函数中修改if语句,不包含第一个按下的点: 'if(selectedLine.intersects(boxX,boxY,width,height)&& selectedLine.getP2()。getX()!= x && selectedLine.getP2()。getY()!= y)' –