【问题标题】:Concurrency Issue with Grahpics2D Draw and JPanel repaintGraphics2D Draw 和 JPanel 重绘的并发问题
【发布时间】:2013-07-12 17:36:46
【问题描述】:

所以,我有一张地图,我希望能够在上面绘制矩形以突出显示一个区域。释放鼠标时,地图上会绘制一个永久矩形,该矩形一直存在,直到再次拖动鼠标以开始创建新矩形。当鼠标被拖动时,矩形轮廓应该随着它的移动而创建。

当鼠标再次点击时,持久的矩形被移除,这意味着应用程序将启动一个新的拖动事件。

发生的情况是第一个矩形被正确绘制并且一切都很好,但是当前正在拖动的后续矩形的角被切断(底部的图像链接)。

如果我在开始拖动之前单击然后等待图像重新绘制,则不存在此问题,以及如果我在开始在 onMouseDragged 中绘制矩形之前休眠线程,以便它有时间重新绘制。

我想要一个比允许在 onMouseDragged 中创建的矩形显示在屏幕上之前重新绘制屏幕的更优雅的解决方案。那么在不破坏绘制矩形的一部分的情况下完成重绘的最佳方法是什么?

请注意,尽管轮廓看起来不错,但绘制的持久矩形是正确的。

这就是矩形的样子

public void onMousePressed(MapMouseEvent ev)
{       

    startPos = new Point(ev.getPoint());
    drawer.removeDrawings(pane.getMapContent());
    pane.repaint();
    pane.setIgnoreRepaint(true);        
}

public void onMouseDragged(MapMouseEvent ev)
{
    super.onMouseDragged(ev);
    if (enabled) {
        ensureGraphics();
        if (dragged)
        {
            // because we're in XOR mode, this has the effect of erases the previous rectangle
            graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
        }
        else
        {


        }
        rect.setFrameFromDiagonal(startPos, ev.getPoint());
        graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
        dragged = true;

    }
}
public void onMouseReleased(MapMouseEvent ev)
{
    super.onMouseReleased(ev);
    if (dragged) {
        ensureGraphics();
        dragged = false;           

        drawer drawable = new drawer();
        drawable.drawRectangle((Graphics2D) parentComponent.getGraphics().create(), rect.x, rect.y, rect.width, rect.height, pane.getMapContent());

        graphics.dispose();
        graphics = null;
        pane.setIgnoreRepaint(false);           
        pane.repaint();

    }
}

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖 SSCCE。还有,你的问题是什么?
  • 我将尝试编写一个简短的可编译示例。实际的问题是如何让屏幕重绘不与正在绘制的矩形混淆,而无需求助于睡眠或明确要求用户单击并按住直到屏幕重绘。
  • 当您将实际问题编辑为问题时,不要忘记添加实际的“?”在末尾。 ;)

标签: java swing concurrency jpanel graphics2d


【解决方案1】:

您需要维护一个List<Rectangle> 并将当前的Rectangle 添加到mouseReleased() 的列表中。 GraphPanel 说明了基本的鼠标处理。在您的情况下,只需渲染图像、任何现有矩形和当前矩形。

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    // render background
    g.drawImage(image, 0, 0, this);
    // render existing rectangles
    for (Rectangle r : list) {
        r.draw(g);
    }
    // render the current dragged rectangle
    if (selecting) {
        g.setColor(Color.darkGray);
        g.drawRect(mouseRect.x, mouseRect.y,
            mouseRect.width, mouseRect.height);
    }
}

在示例中,selecting 是一个布尔值,用于控制是绘制新矩形还是将现有选择拖到新位置。

由于所有渲染都必须在 EDT 上进行,我怀疑您是否需要(或想要)一个新线程。

【讨论】:

    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 2010-09-06
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 2014-04-19
    • 2018-02-25
    相关资源
    最近更新 更多