paintComponent() isn't called after calling repaint()
Recently, i was practicing to make a small plugin. the simplified logic is probably as follows:
@Override
public void actionPerformed(AnActionEvent e) {
Loading loading = new Loading();
loading.show();
//some other operations
XXX;
loading.hide();
Methods methods = new Methods();
methods.showMethodsDialog(methods, dataSource, project.getBasePath());
}
Loading.show() is simplified as follows:
public void show() {
JFrame frame = new JFrame();
LoadingPanel loadingPanel = new LoadingPanel();
frame.setContentPane(content);
frame.setSize(220, 240);
loadingPanel.setSize(200, 200);
content.add(loadingPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
loadingPanel.start();
}
LoadingPanel is a custom ring progress bar from google, it's core method is enable a thread to invoke the repaint() method recursively, as shown below:
@Override
public void run() {
//other logic
XXX;
while (!Thread.interrupted()) {
//other logic
XXX;
repaint();
try {
Thread.sleep(inRamp ? 10 : (int) (1000 / fps));
} catch (InterruptedException e) {
break;
}
Thread.yield();
}
}
The problem now is that the LoadingPanel in Loading dialog does not display until Methods dialog shows. When i debugged, i found that the override paintComponent() is not invoked until the Methods dialog displayed, although the repaint() method is invoked all the time. I feel this is strange.
Thank you very much for the help you are about to offer.
Please sign in to leave a comment.
Sorry, there should be no correlation between the two dialog. I found that as long as I do some time consuming operations after dialog display, the drawing of dialog will be delayed.
`actionPerformed` method is called on EDT (aka AWT / Swing) thread.
`JComponent.repaint()` call schedules rendering event on this thread, that cannot be handled until `actionPerformed` call is completed.
(Or until modal dialog is shown, that can dispatch these events)
Consider using `com.intellij.openapi.progress.Task.Modal`, if your "//some other operations" can be safely performed on background thread.
First of all, thank you very mach for your answer. I have tried do my "other operations" in a background thread, but i got a java.lang.Throwable "Read access is allowed from event dispatch thread or inside read-action only", because i called the com.intellij.psi.PsiElement.acceptChildren(new JavaRecursiveElementVisitor() {XXX}) in my "other operations". What should I do?
See https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/general_threading_rules.html