Size 1x1 modal JDialog

Problem

In our stand-alone Swing application, a modal JDialog is displayed for certain events (button press, etc.). The dialog contains some other Swing components (JLabels, JButtons, ...). Instead, I explicitly set its size through the JDialog.setBounds(...) method, which we call JDialog.pack() (or the JOptionPane showDialog(...) methods, invokes it implicitly). The size calculated by the pack() method is always constant (for example, 300x100 px.) Unfortunately, sometimes the real dimension of the visible dialog is 1x1 px ( JDialog.getSize().equals(new Dimension(1, 1)) ).

Initializing JDialog

There are two ways to initialize JDialog in our application. We verified that both initialization methods are always called from EventDispatchThread.

First method

We simply create an instance of ADialog , which is a subclass of JDialog . Here is a snippet of our initialization procedure:

 ADialog dialog = new ADialog(); dialog.setContentPane(content); dialog.setVisible(true); 

Here is our implementation of ADialog :

 public class ADialog extends JDialog implements ComponentListener { public JfosDialog(Frame owner) { super(owner); init(); } private void init() { super.addComponentListener(this); } @Override public void componentShown(ComponentEvent e) { // Calling pack() at this place is really weird, but we // have to do it since some subclasses put their // content to dialog in overriden componentShown(). pack(); } @Override public void componentMoved(ComponentEvent e) { /** not interested */ } @Override public void componentResized(ComponentEvent e) { /** not interested */ } } 

Second method

 public JOptionPane showDialog(...) { JOptionPane jop = new JOptionPane(message, msgType, option, null, textMessages); JDialog dialog = jop.createDialog(owner, titleMsg); setDialogTraversal(dialog); dialog.setVisible(true); dialog.dispose(); return jop; } 

Reproducibility

Environment

  • Ubuntu 12.04., JRE 1.6 / JRE 1.7 / OpenJDK 1.6
  • Windows XP, JRE 1.6.u16

Reproducing a problem using the first initialization method

We just show and then hide the dialog N times (0 <N <1000), and once by the size of the time dialog box - 1x1 (sign of a problem with the stream, race condition). Since the nature of this problem is very stochastic, we wrote a simple java.awt.Robot script that shows and hides the dialog in a loop. It is simply more convenient than doing it manually.

Reproducing a problem with the second initialization method

The steps are the same as in the first method: just show and then hide the dialog N times. Unfortunately, we cannot reproduce it in our development environment, but it can be easily reproduced on a production PC (in our development environment there is another processor, some kind of antivirus that constantly creates a system boot, etc.)

So far, we cannot reproduce the problem in some test / sample project. This may mean that something is wrong with our application. However, it seems that the problem may be somewhere in the native Swing code (see the Tracing section).

Tracing

We traced the cause of our problem in the 64-bit OpenJDK 1.6.0_24. We found that the dimension of JDialog changes to XConfigureEvent released by XToolkit . The event is built in the event loop of the XToolkit.run(boolean) method after returning from the built-in method call.

To simplify things, I am only XToolkit code snippet here illustrating the XToolkit event loop mechanism with our trace results. You can also see the full source code here .

 public class XToolkit ... { ... public void run(boolean loop) { XEvent ev = new XEvent(); while(true) { awtLock(); try { if (loop == SECONDARY_LOOP) { ... } else { ... // =========================================== // The following invocation of native method sometimes // updates ev object in a way that ev.get_type() method returns value 22 // indicating that the event type is XConfigureEvent. // In such case, as I mentioned in text above, the value of // ev.get_xconfigure().get_width() / .get_height() // is sometimes 1. XlibWrapper.XNextEvent(getDisplay(),ev.pData); // <----- // =========================================== } ... // The XConfigureEvent with get_width() == 1 and // get_heigth() == 1 is dispatcher here: dispatchEvent(ev); // <----- ... } catch (...) { ... } } } ... } 

Do you have ideas on how to fix this error / track it deeper / reproduce it more confidently ...?

I appreciate any ideas, as this mistake is a real pain.

+4
source share
1 answer

pack () should comply with the preferred (or minimum size, depending on the template manager) of your components.

Try explicitly setting the minimum and preferred component size in your dialog box and see if this fixes the problem.

As for the conditions of the race, this may well be incorrect initialization in your code. Most components will satisfy their content (for example, JLabel text) when the layout manager asks for their preferred (or minimum size). So perhaps the code that populates your components does not always work in the same order. Have you forced to create a dialog and all the components contained in it in the AWT stream?

+6
source

Source: https://habr.com/ru/post/1415473/


All Articles