Java 如何强制重新粉刷玻璃窗格?

Java 如何强制重新粉刷玻璃窗格?,java,swing,glasspane,Java,Swing,Glasspane,我有一个Swing应用程序,地图上方有一个玻璃窗格 它在某些位置画点。当我单击地图上的某个位置时,玻璃窗格收到消息CONTROLLER\u NEW\u POLYGON\u MARKI 希望在事件数据中指定的位置显示一个额外的点(请参见MyGlassPane.propertyChange) 玻璃窗格类称为MyGlassPane。使用调试器,我验证了addPointToMark实际上是在propertyChange中调用的 但屏幕上不会出现其他点 如何更改代码,以便在触发事件(IEventBus.C

我有一个Swing应用程序,地图上方有一个玻璃窗格

它在某些位置画点。当我单击地图上的某个位置时,玻璃窗格收到消息
CONTROLLER\u NEW\u POLYGON\u MARK
I 希望在事件数据中指定的位置显示一个额外的点(请参见
MyGlassPane.propertyChange

玻璃窗格类称为
MyGlassPane
。使用调试器,我验证了
addPointToMark
实际上是在
propertyChange
中调用的

但屏幕上不会出现其他点

如何更改代码,以便在触发事件(
IEventBus.CONTROLLER\u NEW\u POLYGON\u MARK
)时调用
PointSetMarkingGlassPane.paintComponent

public class PointSetMarkingGlassPane extends JComponent implements IGlassPane {
    private final ILatLongToScreenCoordinatesConverter latLongToScreenCoordinatesConverter;
    private final List<Point.Double> pointsToMark = new LinkedList<Point.Double>();

    public PointSetMarkingGlassPane(final ILatLongToScreenCoordinatesConverter aConverter) {
        this.latLongToScreenCoordinatesConverter = aConverter;
    }

    protected void addPointToMark(final Point.Double aPoint)
    {
        if (aPoint != null)
        {
            pointsToMark.add(aPoint);
        }
    }

    @Override
    protected void paintComponent(final Graphics aGraphics) {
        for (final Point.Double pointToMark : pointsToMark)
        {
            final Point positionInScreenCoords = latLongToScreenCoordinatesConverter.getScreenCoordinates(pointToMark);
            drawCircle(aGraphics, positionInScreenCoords, Color.red);
        }
    }

    private void drawCircle(Graphics g, Point point, Color color) {
        g.setColor(color);
        g.fillOval(point.x, point.y, 10, 10);
    }

}

public class MyGlassPane extends PointSetMarkingGlassPane implements PropertyChangeListener {
    public MyGlassPane(ILatLongToScreenCoordinatesConverter aConverter) {
        super(aConverter);

        addPointToMark(DemoGlassPane.ARTYOM);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (IEventBus.CONTROLLER_NEW_POLYGON_MARK.equals(evt.getPropertyName()))
        {
            addPointToMark((Point.Double)evt.getNewValue());
            invalidate();
        }
    }
}
公共类PointSetMarkingGlassPane扩展JComponent实现IGlassPane{
专用最终ILATlongtoscreen坐标转换器LATLONgtoscreen坐标转换器;
private final List pointToMark=new LinkedList();
公共点集标记玻璃窗格(最终ILATLONGTO屏幕坐标转换器A转换器){
this.LatLongtosScreen CoordinatedConverter=a转换器;
}
受保护的无效添加点标记(终点。双点)
{
如果(aPoint!=null)
{
添加点标记(aPoint);
}
}
@凌驾
受保护的组件(最终图形失写){
对于(最后一点。双点标记:点标记)
{
最终点位置ScreenCoords=LatlongtoScreenCoordinationConverter.GetScreenCoordinations(指向标记);
画圈(失写、位置、字词、颜色、红色);
}
}
专用空心绘制圆(图形g、点、颜色){
g、 设置颜色(颜色);
g、 圆角(点x,点y,10,10);
}
}
公共类MyGlassPane扩展PointSetMarkingGlassPane实现PropertyChangeListener{
公共MyGlassPane(iLatlongtoScreen坐标转换器A转换器){
super(aConverter);
添加指向标记(DemoGlassPane.ARTYOM);
}
@凌驾
公共作废属性更改(属性更改事件evt){
if(IEventBus.CONTROLLER\u NEW\u POLYGON\u MARK.equals(evt.getPropertyName()))
{
addPointToMark((Point.Double)evt.getNewValue());
使无效();
}
}
}

我认为
invalidate()
只标记组件以检查大小和布局。您应该调用
repaint()
重新绘制窗格


我还想知道为什么您使用propertyChangeListener进行鼠标单击。我更喜欢简单的鼠标监听器+MouseAdapter和MouseEvent x,y按钮状态。

正如我认为的
invalidate()
只标记组件以检查大小和布局。您应该调用
repaint()
重新绘制窗格

我还想知道为什么您使用propertyChangeListener进行鼠标单击。我更喜欢简单的鼠标监听器+MouseAdapter和MouseEvent x,y按钮状态。

invalidate()
可能对您没有帮助,因为它为布局更改标记组件,而不是绘制更改。为什么不调用
repaint()

为了获得更好的性能,您可以调用
repait
方法,该方法采用一个矩形(或四个int表示一个矩形),以便只重新绘制新添加的点;我建议将
addPointToMark
的返回类型从void改为java.awt.Point,并让它返回
latlongtoscreenCoordinateConverter.getScreenCoordinations
,这样MyGlassPane就可以从该点派生一个矩形,然后将其传递给重新绘制方法。

invalidate()
可能对您没有帮助,因为它会标记组件以进行布局更改,而不是绘制更改。为什么不调用
repaint()


为了获得更好的性能,您可以调用
repait
方法,该方法采用一个矩形(或四个int表示一个矩形),以便只重新绘制新添加的点;我建议将
addPointToMark
的返回类型从void更改为java.awt.Point,并让它返回
latLongToScreenCoordinatesConverter.getScreenCoordinations
的结果,因此,MyGlassPane可以从该点派生一个矩形,然后将该矩形传递给重新绘制方法。

如果在JFrame中工作,则在GlassPane或JViewport中放置时,这不是原因,确保在没有SSCCE的情况下,这里的一切都是关于猜测的。如果JFrame中有工作,这不是为什么不在GlassPane或JViewport中的情况下,请确保在没有SSCCE的情况下,这里的一切都是关于猜测或super.paintComponent()的,正如我所理解的,super.paintComponent仅对具有UI委托的组件的子类是必需的,而对JComponent的直接子类不是严格要求的。实际上,我从未对此进行过测试,尽管.alone repaint()只在没有super.paintComponent()或super.paintComponent()的情况下进行绘制,但据我所知,super.paintComponent只需要具有UI委托的组件的子类,而不是JComponent的直接子类。实际上,我从未对此进行过测试,尽管.alone repaint()只在没有super.paintComponent()的情况下进行绘制,@mKorbel No,您不应该显式调用
super.paintComponent()
。绘制组件应该在事件线程中进行,因为swing不是线程安全的。单独重新绘制()只能在没有super的情况下进行绘制。paintComponent()@mKorbel您可以扩展该注释吗?你说的“沟通痛苦”是什么意思?没有super.paintComponent()?super.paintComponent()删除所有以前的绘制,有关查看java+swing+paintComponent(此处)标记的帖子的更多信息,特别是camickr、HFOE、MadProgrammer的帖子,但OPs代码(AFAIK)中还有另一个问题,因为PropertyChangeListener将通知在