简体   繁体   English

MouseMoved上的Java重新绘制会导致延迟

[英]Java Repaint on MouseMoved causes lag

I'm trying to make my java app repaint each time the mouse has been moved to update the screen when the user moved over a diagram ( -> display the name of the diagram ) and when the user does not move over a diagram ( -> do not display any name of a diagram ). 每当用户将鼠标移到图表上时(->显示图表的名称)和用户没有移到图表上时(-- >不显示图表的任何名称)。 But this causes a huge lag when running the application ( I see the screen been repainted very slow, laggy, the screen is white empty for like a second each time before it's repainted; takes long to repaint ). 但这在运行应用程序时会造成巨大的滞后(我看到屏幕的重新绘制非常缓慢,缓慢,在每次重新绘制之前,屏幕都是空白的,大约一秒钟;重新绘制需要很长时间)。

These are the the parts of the code which it's about: 这些是有关代码的部分:

 public void mouseMoved(MouseEvent e) {
  this.checkDiagramHovered(e.getX(),e.getY());
 }

Which calls to a function that checks whether diagram was hovered and set variables whether a diagram was hovered and if so: which diagram was hovered (name to display, x and y position to do) and then repaint the app. 哪个调用了一个函数,该函数检查是否悬停了图表,并设置了变量是否悬停了图表以及是否悬停:悬停了哪个图表(要显示的名称,要执行的x和y位置),然后重新绘制应用程序。 So it basicly repaints the app each time a mousemovement was made to be sure it displays the name of a diagram ONLY when the user moved over it. 因此,从根本上说,每次进行鼠标移动时,它都会重新绘制应用程序,以确保仅当用户将鼠标移过它时才显示图的名称。 But this causes the screen to lag a lot, choppy repainting. 但这会导致屏幕滞后很多,断断续续的重新粉刷。

Now I was wondering: what's the best way to solve this? 现在我在想:解决此问题的最佳方法是什么? Should I implement some kind of delay for checking the mousemovement or something if that can be done? 我是否应该执行某种延迟来检查鼠标移动,或者可以这样做?

Thanks in advance, 提前致谢,

Skyfe. Skyfe。

I'm assuming you're using Java Swing. 我假设您正在使用Java Swing。

You have to take the checkDiagramedHovered method out of the user interface thread, so the UI remains responsive. 您必须从用户界面线程中取出checkDiagramedHovered方法,以便UI保持响应。

public void mouseMoved(MouseEvent e) {
   Thread thread = new Thread(new Runnable()
       public void run() {
           this.checkDiagramHovered(e.getX(),e.getY());
       }
    );
    thread.start();
}

If checkDiagramedHovered has any UI methods, you're have to run them in the UI thread. 如果checkDiagramedHovered具有任何UI方法,则必须在UI线程中运行它们。

SwingUtilities.invokeLater(new Runnable()
    public void run() {
        (UI method call)
    }
);

Well, I would use Swing, not AWT. 好吧,我会使用Swing,而不是AWT。 Swing is an extension to AWT that everybody uses these days. Swing是当今所有人都在使用的AWT的扩展。 Then you can use a Tool Tip . 然后,您可以使用工具提示 You would need to override the getToolTipText(...) method for your component that displays the image. 您需要为显示图像的组件覆盖getToolTipText(...)方法。

in swing and awt, all events (mouse, keyboard) and painting are happening in the same thread. 在swing和awt中,所有事件(鼠标,键盘)和绘画都在同一线程中发生。 when you are calling repaint you submit a new job to that thread, that will actually call paint eventually. 当您调用重新绘制时,您向该线程提交了一个新作业,最终实际上将调用绘制。 if the paint function takes too long, that thread (AWT Event queue thread) gets too busy to process mouse events and you see lag. 如果paint函数花费的时间太长,则该线程(AWT事件队列线程)变得太忙而无法处理鼠标事件,并且您会看到延迟。 the problem of the flickering you described also suggest slow paint function. 您描述的闪烁问题也暗示了绘画功能缓慢。

there are several things you can do: 1. use double buffering. 您可以执行以下几项操作:1.使用双重缓冲。 this will solve the flicker but not the lag. 这将解决闪烁,但不会解决延迟。 2. do the actual rendering in a different thread, and have the awt thread draw an offscreen image prepared by that thread. 2.在其他线程中进行实际渲染,并让awt线程绘制该线程准备的屏幕外图像。 this will solve both problems. 这将解决两个问题。

in short, double buffering means you create an offscreen image and paint to it, and then paint the whole image at once using Graphics.drawImage() 简而言之,双重缓冲意味着您可以创建一个屏幕外图像并对其进行绘制,然后使用Graphics.drawImage()一次绘制整个图像

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM