In Java 6 below code is running as expected but in Java 8 it is taking much more time. The interesting part is that components use the same method setEnable()
for e
I haven't had a chance to understand exactly, but it seems like event handling might have changed in 8. Disabling the parent first speeds up the process:
getContentPane().setEnabled(false);
for (Component c : getContentPane().getComponents()) {
c.setEnabled(false);
}
getContentPane().setEnabled(true);
According to my profiler, the operation spends most of the time in the method Thread.holdsLock
, which can be indeed a costly operation, which is called by Component.checkTreeLock
which is called indirectly by Component.updateCursorImmediately
.
Generally, you can avoid costly visual updates when updating multiple components by calling getContentPane().setVisible(false);
right before the operation and getContentPane().setVisible(true);
right afterwards, e.g.
private void disableAll() {
long m = System.currentTimeMillis();
System.out.println("Disabling");
getContentPane().setVisible(false);
for (Component c : getContentPane().getComponents()) {
c.setEnabled(false);
}
getContentPane().setVisible(true);
m = System.currentTimeMillis() - m;
System.out.println("Disabled in " + m + " ms");
}
You will see, such problems will vanish, regardless of which kind of visual update causes the problem in detail.
So you don’t need to think about how to benchmark correctly here, not that it matters when the operation takes seconds, but I recommend learning the difference between System.currentTimeMillis()
and System.nanoTime() as the latter is the right tool for measuring elapsed time.