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.
Related
I am developing a Java Swing-based application with different perspectives. For the "main menu" perspective I do not want the window (JFrame) to be decorated, while in other perspective I do want the window to be decorated. In other words, I need want to change the decoration attribute dynamically.
I have tried to use setUndecorated(false) and setUndecorated(true), but I seems I can only set this once, before actually showing the window.
Is there a way to achieve this?
From the javadoc:
Disables or enables decorations for this frame. This method can only be called while the frame is not displayable.
Therefore, once the JFrame is packed and/or displayed, you can no longer change that value. If you want to change the undecorated state of a JFrame you will need to dispose() it first, then change the state and eventually make it visible again.
After all, I had to take a different approach.
The former solution did work, as I stated in my last comment.
However, it was showing the default LAF window decoration, while I was using a different LAF.
So the result was graphically inconsistent with the rest of the LAF. Finally, I came with the right solution, I used setUndecorate(true) for my frame. Then, when I had to change my perspective to one using decorations I simply had to use the following code
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
And when I had to revert to the non decorate perspective, I use
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
This approach didn't need to dispose the window and show it again (which actually produced a brief but still visible hide/show of the window)
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.
I'm trying to create a slide down (If that's the correct term) in Java.
I can't seem to find a fitting Swing control to achieve this.
This is the effect I would try to reach.
Like the menu of "Swing Containers" and "Swing menus" is visible, but the menu of "Swing Windows" is just a simple bar with a + sign.
Anyone an idea how I get this layout with the GUI editor of Netbeans?
From the posted example, you're looking for a collapsible component.
You could spend the time making your own, things to look out for are the layout manager that the component resides in, if it does not honour the preferred size of the components, it won't work (ie BorderLayout would not be a good choice to host this type of component in)
Personally, I use the JXCollapsiblePane from the SwingX libraries, normally in combination with a VerticalLayout from the same library.
I am developing a Java Swing-based application with different perspectives. For the "main menu" perspective I do not want the window (JFrame) to be decorated, while in other perspective I do want the window to be decorated. In other words, I need want to change the decoration attribute dynamically.
I have tried to use setUndecorated(false) and setUndecorated(true), but I seems I can only set this once, before actually showing the window.
Is there a way to achieve this?
From the javadoc:
Disables or enables decorations for this frame. This method can only be called while the frame is not displayable.
Therefore, once the JFrame is packed and/or displayed, you can no longer change that value. If you want to change the undecorated state of a JFrame you will need to dispose() it first, then change the state and eventually make it visible again.
After all, I had to take a different approach.
The former solution did work, as I stated in my last comment.
However, it was showing the default LAF window decoration, while I was using a different LAF.
So the result was graphically inconsistent with the rest of the LAF. Finally, I came with the right solution, I used setUndecorate(true) for my frame. Then, when I had to change my perspective to one using decorations I simply had to use the following code
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
And when I had to revert to the non decorate perspective, I use
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
This approach didn't need to dispose the window and show it again (which actually produced a brief but still visible hide/show of the window)
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.