Recreate Windows Look-and-Feel border of JFrame or JDialog? - java

I need to recreate the translucent border of JFrame or JDialog that appears when setting the windows look and feel in swing.
I need it because Windows LaF does not let you access the title bar (on the border). In fact, I need to apply a MouseAdapter to the JDialog that gets notified when it is dragged/pressed/released. In windows laf, as you cannot get access to the bar component, you can only apply a ComponentListener which gives you notification only when moving (so you don't capture anything when the user has grabbed it but hasn't moved yet, or either when the user "releases" it).
Therefore, I decided to go with undecorated dialogs and apply the listeners to my custom bar. However I want the custom dialog looks exactly as in windows laf (it means I need to recreate the border).
I'm not very experienced in Graphics2D to override the paintBorder() method, so I'm asking for your help.
Has anyone ever faced this problem and has a tested solution?

As of the Java Platform, Standard Edition 6 (Java SE 6) Update 10 release, you can add translucent and shaped windows to your Swing applications.
This means that you can have your JFrame emulate a native window with the rounded corners and transparency.
In your case, your approach would be in the JFrame level instead of the border level because the border is painted on top of the JFrame (or JDialog, for that matter). Therefore, if the JFrame is not already rounded, for instance, the paintBorder() method will still be painting on top of a rectangular area of the screen.
Check this tutorial from Oracle covering shaped and translucent JFrame.

Related

Emulate This SWT Shell in Swing

I've been experiencing with SWT (GUI lib Eclipse uses) and I'm wanting to create the following using Swing.
The previous screenshot is done by the following code using SWT
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display, SWT.RESIZE);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
I was wondering, how could I possible emulate this in Swing?
P.S The border around this Shell is currently the native border for my windows color scheme, I don't wanna just create a MatteBorder and emulate the color, I'd like to use the native border for windows.
So the question is: Can native-styled windows with borders only be created using Swing?
Shortly: No. Unfortunately it is impossible to do this using Swing.
Also: Same "No" goes for the tool windows which can also be created using SWT.
Now let me explain why.
Swing uses pure-Java written rendering to paint any components and custom decorations within your application. Window decoration in Swing is a bit different topic though - by default JFrame and JDialog are decorated using native style - basically when window instance is created in your system from Java application - that window is asked to have default decoration for either frame or dialog (plus some other possible options). After that this window is used to render Swing components on it. But Swing code has no real control over the system-provided decoration, it can only switch it on/off and configure a few options in it. Unfortunately the option you are looking for is not there - most probably wasn't not implemented as not very popular one.
Though Swing allows custom component/window styling through custom L&F (Look and Feel). L&F which supports custom window decorations simply provides its own way to paint and control window decoration. In case such L&F is installed - Swing uses undecorated frames/dialogs by default and simply asks L&F to do the decoration. Anyone can write their own L&F which means anyone can create custom decorations.
So as #camickr mentioned before you have only one option if you want to create such frame (like on the screenshot in your post) in Swing - use either JDialog/JFrame with setUndecorated set to true or JWindow which is undecorated by default and "paint your way through". Graphics2D provided for all painting operations will allow you to create any custom decoration of your window, even the one on your screenshot.
I won't lie - creating custom window decoration is pretty difficult - it requires a lot of knowledge in Swing and large amount of written code, not only painting code. So I really doubt you will choose that option unless you are passionate about UI creation.
In the end - you have to choose between SWT and Swing (or even JavaFX) as each of these UI frameworks offer totally different sets of features and options. Window decoration is just a tip of the large iceberg.
EDIT:
Since JDK 7 it is actually prossible to create tool windows, all you need is to set your window type to Window.Type.UTILITY. Though it is still not possible to create a window with native borders only without any title bar.
Use an undecorated JDialog. Then you can add a MatteBorder to the root pane of the dialog. Or you can always implement you own custom Border to emulate the LAF Border.
On Eclipse I'm pretty sure it's done with an org.eclipse.swt.widgets.Shell with SWT.Border as the style. I can't think of a way to do this in Swing. You could write one yourself but it wouldn't have the system LAF.
If this is really important I would suggest using SWT instead, but that might require a re-write. Otherwise you could use a SWT Shell with Swing components embedded in it, but in my experience this is extremely fiddly and hard to debug.

PopupMenu freezing parent frame

I'm using a AWT PopupMenu on a frame that constantly repaints (it's a game), but whenever the PopupMenu shows, the parent frame freezes. Is there a way to disable this?
I assume the rest of the application is in made in Swing and you are using the AWT popmenu in combination with Swing components.
I've had my fair share of AWT PopMenu problems. Do you need to show the Popmenu outside the bounds of your application ? If you only need to be able to show it inside your application (JFrame) you are probably beter off with just putting a JComponent on top of all your other panels (with a JLayredPane) and draw your own pop menu there.
Even easier is to use JLayer in Java 7 for the same effect (or JXLayer if your not on Java 7 but on Java 5 or 6).
The above method is also way more powerful then the AWT popmenu because you control the drawing. So for example making it translucent or giving it round edges becomes a breeze.

ToolTip flicker in Java if outside JFrame?

I am implementing ToolTip in Java as to make users having an easier time to use the product. Though tooltip that are at the borders of the JFrame and ends up outside the JFrame starts to "flicker". I've tried lots of things (like moving the tooltip so it should be inside the Jframe, controlling the painting so it ends up within the JFrame and so on) though it doesn't work.
Anyone got any expertise within the field that know how to avoid this problem?
Cheers,
Skarion
When a tooltip is displayed in a JFrame, Swing does not create a floating window, it simply paints the tooltip in the graphic context of the JFrame. This does not generate any flickering.
On the other hand, when a tooltip is outside the boundaries of the JFrame, it becomes heavyweight: a window is created to host the tooltip component. Flickering occurs when the tooltip window appears.
Maybe setting "-Dsun.awt.noerasebackground=true" would help because it prevents one step of background repainting of the hosting window.

Java (Swing) - Drag two windows at once

How can I have one window move with another? i.e., I'd like a JDialog to follow a JFrame when the JFrame is being dragged. If the JFrame moves by (+5, +20), the JDialog needs to move the same.
I've tried using ComponentListeners, but I only receive drag events in chunks which causes the JDialog window to be jumpy while dragging the main JFrame. I've tried using MouseListeners, but I can't figure out how to detect events on the actual frame of the JFrame.
AFAIK here is no move multiple windows in AWT. To get the moves to be called at a similar time, I guess you want the JFrame decorations to be PL&F rendered. Put in a PL&F-specific hack to do the moves yourself, moving both windows at almost the same time. You may still have a problem with exposing bits of windows only to cover them up causing some performance degradation.
Try using the ComponentListener.componentMoved event instead of monitoring drag events on the JFrame.
The component listener method works perfectly.
I did something like this:
Point p = this.getLocation();
p.x += this.getWidth() + 10;
this.getOwner().setLocation(p);
Where the '10' is the space between the current window(a JDialog) and its owner which is to its right.

How to show a shape or graphic in java with no window frame?

I'm having a hard time trying to make a Java program with just a shape (e.g rectangle) as main window. I don't want the shape to be inside the 'OS-window' (with buttons to close and minimize etc..)
I don't know if you can draw directly on the screen in Java (I tend to think you can't). But you could create a JDialog (which doesn't appear in the taskbar) and call setUndecorated(true) on it (to get rid of the title bar). Then you can do whatever custom painting you want with it.
Edit: kts points out that JWindow will work even better for this purpose. From the Javadocs:
It does not have the title bar, window-management buttons, or other trimmings associated with a JFrame, but it is still a "first-class citizen" of the user's desktop, and can exist anywhere on it.
And there's even a no-argument constructor, so you don't have to worry about passing in a null owner!
For more exotic shapes: translucent and shaped windows. Works only in 6u10 and later.

Categories