Workaround for bug_id = 4806603 regarding getBounds () and setBounds () on Linux?

On the Linux platform, Frame :: getBounds and Frame :: setBounds do not work sequentially. This was already reported in 2003 (!). See here:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4806603

For convenience, I simplified the specified code, which leads to an error and inserts it as:

import java.awt.Button; import java.awt.Frame; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** Demonstrates a bug in the java.awt.Frame.getBounds() method. * @author Mirko Raner, PTSC * @version 1.0 (2003-01-22) **/ public class GetBoundsBug extends Frame implements ActionListener { public static void main(String[] arg) { GetBoundsBug frame = new GetBoundsBug(); Button button = new Button("Click here!"); button.addActionListener(frame); frame.add(button); frame.setSize(300, 300); frame.setVisible(true); } @Override public void actionPerformed(ActionEvent event) { Rectangle bounds = getBounds(); bounds.y--; setBounds(bounds); bounds.y++; setBounds(bounds); } } 

Unexpected behavior:. When the button is pressed, the window shifts a little lower! (My system has 28 pixels each click.)

Here is the screen recording: https://youtu.be/4qOf99LJOf8

This behavior was about 13 years old, therefore, probably, there will be no changes from the official side.

Does anyone have a workaround for this error? In particular, I would like to reliably store and restore the window / frame / dialog in the previous location on all platforms.

PS: My installation of java jdk1.8.0_102 for amd64 Oracle on Ubuntu 16 Linux. Since I recently migrated from Windows to Ubuntu, I know that on Windows the code above works as expected.

Adapting to Swing using SwingWorker has the same effect:

 import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingWorker; public class GetBoundsBug extends JFrame implements ActionListener { public static void main(String[] arg) { GetBoundsBug myJFrame = new GetBoundsBug(); JButton myJButton = new JButton("Click here!"); myJButton.addActionListener(myJFrame); myJFrame.setContentPane(myJButton); myJFrame.setSize(300, 300); myJFrame.setVisible(true); } @Override public void actionPerformed(ActionEvent event) { SwingWorker<Void, Void> mySwingWorker = new SwingWorker<Void, Void>() { @Override public Void doInBackground() { Rectangle myRectangle = getBounds(); myRectangle.y--; setBounds(myRectangle); myRectangle.y++; setBounds(myRectangle); return null; } }; mySwingWorker.execute(); } } 
+7
java linux
source share
2 answers

Well, in the original error database entry, this is marked as “Not fixed” and explained as a fad in the window manager, not in the JDK.

What window manager are you using?

+1
source share

One more note. I noticed that your code did not really affect Thread Dispatch Thread. All Java drawing APIs are single-threaded in design, which means you cannot expect your application to work correctly unless you send GUI updates to the Dispatch stream.

This means that you need (at its core) to create a new Runnable, which, when evaluated, will present your widgets and send it to EDT.

In addition, your action provider updates the state of the component in action, bypassing the redraw request and ignoring the typical security measures necessary to ensure sending to the EDT.

In both of these cases, the code is invalid GUI code in the Java environment, and the error you find may not have any relation to your behavior, since your program violates the design of the GUI toolkit before you even know that the error affects it.

In addition, awt only wraps components. If the components are lying, then false is leaking in Java. Not much can be done about this (but I no longer think this is the main thing to worry about). If you don't like this, use Swing, which is much more reasonable / stable.

+1
source share

All Articles