Create a rounded JFrame / ContentPane - java

I'm creating a login window with rounded corners in java. Everything is OK, see pic, but i'm having challenges making the JFrame / ContentPane transparent. There are white areas at each corner (shown by the arrows) that i seem not to be able to remove since i can't set opague to false for the JFrame or ContentPane.
Any ideas of how i can remove these white areas

Since Java 1.3 there's a trick which allows to make partially transparent windows, or windows fading in (I usually use this for my splash screens), or special FX (such as shadows):
Before opening the window, programmatically take a screenshot of the region where your window is going to be (using java.awt.Robot.createScreenCapture())
Set the screenshot as the background of your root container (JPanel with custom paintComponent() routine)
Now you can add all kinds of transparent components, or paint another semitransparent image on top of the background.
Example which creates a window with a semitransparent shadow using this technique:
http://www.eclipsezone.com/eclipse/forums/t17720.html

Not much help to you but Java7 will support transparent and shaped windows: More info here. These are available already in Java 6u10 but not publicly, ie, you need to use an unsupported com.sun... class that might change in future and break your program.

try this. its work :)
yourframe.setBackground(new Color(0, 0, 0, 180));
yourframe.setUndecorated(true);
yourframe.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 80, 80));
}
});

JFrame can not be made transparent as it is a heavyweight component. Only lightweight components such as JWindow can be made transparent.

Related

How to Remove Black Rectangle on Window Resize?

I am developing a JFrame window with Swing and AWT, and when I resize the window, it looks like this:
Window resize
(I apologize for the low frame rate, stackoverflow wouldn't accept a larger file size)
As you can see, a lot of times when I resize the window, it shows a black rectangle where it is being resized and it doesn't go away until you pause for a moment. Additionally, the circle doesn't always update accurately with my resize event:
frame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent componentEvent) {
width = frame.getWidth();
height = frame.getHeight();
springLayout.putConstraint(SpringLayout.SOUTH, panel, height, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, panel, width, SpringLayout.WEST, frame.getContentPane());
panel.repaint();
}
});
That's beside the point (though it is possible the two problems are linked). I have only ever encountered this problem when using Swing. JavaFX has never given me this problem. Is there any way I can remove the black rectangle when the window is resized?
I have only tested this on Windows 10.
This apparently has to do with the native window decorations of the window that hosts the JFrame. When disabling the native window decorations, you can remove the stuttering resizes and the black background bleeding through. See the documentation for JFrame.setDefaultLookAndFeelDecorated(boolean):
Provides a hint as to whether or not newly created JFrames should have their Window decorations (such as borders, widgets to close the window, title...) provided by the current look and feel. If defaultLookAndFeelDecorated is true, the current LookAndFeel supports providing window decorations, and the current window manager supports undecorated windows, then newly created JFrames will have their Window decorations provided by the current LookAndFeel. Otherwise, newly created JFrames will have their Window decorations provided by the current window manager.
Thus, you have two options. Either set the property once before you create your JFrame:
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
Or do it after the creation of the JFrame:
JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.setWindowDecorationStyle(JRootPane.FRAME);
Note that in either case, you are bound to use Swing's Look and Feel for the window decorations. The title bar and handles of the window are therefore going to look different than before.

Transparent JFrame

I have a JFrame that holds a JPanel. I want to make the frame completely transparent and the panel slightly transparent.
I'm using the following code to do so:
frame.setBackground(new Color(0, 0, 0, 0));
panel.setBackground(new Color(51, 51, 51, 190));
The desired effect is achieved, however, when I make the JFrame transparent using this method it distorts all of the other components.
The following image demonstrates this better than I can explain.
On the left is an example with no transparency and the text appears clearly. On the right the panel and the frame are set using the code above, and the text is distorted.
What am I missing?
however, when I make the JFrame transparent using this method it distorts all of the other components.
The problem is Swing thinks the component is opaque so it doesn't paint the background first so you get painting artifacts.
Check out Background With Transparency. It has two simple solutions:
paint the background yourself
use a wrapper container to do the painting for you

JScrollPane with transparent background and content

In my app, I show a popup dialog to show a large list of cards. I display them as images in many JLabel components in a JPanel subclass. I then put that object in a JScrollPane to allow for horizontal scrolling through the cards.
I want the unused space to be transparent with a dark background to show that what's behind it is disabled. I used setBackground(new Color(50, 50, 50, 200)) to achieve the look I want, but the content behind it does not redraw, so I get artifacting.
Here's what it looks like:
How would I go about fixing this? How do I get the content behind it to redraw when I scroll?
Thanks in advance.
Taking the window out of the equation for the momement.
The JScrollPane contains a JViewport which then contains you content. So you need to set your content pane to transparent, the viewport to transparent and then the scroll pane to transparent.
You can achieve this by using setOpaque(false) on each of these containers.
This will ensure that the repaint manager will now paint through the background.
The next problem is, Swing doesn't actually support "semi-transparent" components (that is, either it's opaque or transparent).
You can implement this by overriding the paintComponent method of the main component (the one on the viewport is probably sufficient)
Try the following...might give you some relief during scrolling.
You likely also have a problem when the main frame is maximized
or restored. You will need a listener for those events and a
similar fix.
jScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(final AdjustmentEvent e) {
sevenWondersframe.repaint();
}
});
jScrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(final AdjustmentEvent e) {
sevenWondersframe.repaint();
}
});

Is GC drawing on top of an SWT_AWT Bridged frame possible?

I am trying to do something of this sort with no luck.
Composite c = new Composite(shell);
JFrame frame = SWT_AWT.new_Frame(c);
GC gc = new GC(c);
c.fillRectangle(0, 0, 100, 100);
code runs fine but I can't get the rectangle to show on top. I think the frame hides it. Is there a way to put the GC drawings on top?
Thanks,
-Hadi
Apparently, in SWT, transparency is not possible. There are some options available that might lead you to think they're built for this effect but all they do does is either not render say the canvas background or render it using alpha value without rendering the composites bellow it. In other words, SWT doesn't allow you to have see through components.

Changing The Underlying Background Color Of A Swing Window

As discussed here, when resizing a Swing application in Vista (and Windows 7, which is what I'm using) you get a black background in the right/bottom corner while Swing's repaint catches up to the changes.
Playing with other applications (Windows Explorer (Native), Firefox (C++?), and Eclipse (Java)) I notice that they all have this same problem - contrary to what the folks in the link above say - but they minimize the problem by having a grey fill color, which is far less visually jarring than the black that appears in Swing.
I'm wondering if there's some way to change this so that Swing behaves like these other applications? I tried setting the background color of the JFrame, but to no avail.
Additional Info
Jonas discovered (see their informative answer below) that this is an issue with JFrames, but not AWT Frames - maybe that will help someone figure this out.
I have noticed the same problem. This color is gray at IE, in Opera it's black, and in Eclipse it's gray. It seam to be more visible in Swing, because it seam to be little slower at repainting and the color is as you said, black. This problem is more visible if you use the upper left corner to resize.
I coded an example and tried to understand where this black color is defined. A JFrame has many layers, so I set a different background on every layer.
import java.awt.Color;
import javax.swing.JFrame;
public class BFrame {
public static void main(String[] args) {
new JFrame() {{
super.setBackground(Color.CYAN);
this.getRootPane().setBackground(Color.BLUE);
this.getLayeredPane().setBackground(Color.RED);
this.getContentPane().setBackground(Color.YELLOW);
this.setSize(400,340);
this.setVisible(true);
}};
}
}
But this example didn't help. And maybe the color is set by a superclass to Frame.
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
My teory is that, since Swing paints itself, but uses a native Window, then is the native background painted before the resize, and the background of Swing is painted after the resize. But for native applications, the background is painted before the resize.
UPDATE: I tried with a Frame now, and it's not having the same problem. The background seam to be painted before the resize.
import java.awt.Color;
import java.awt.Frame;
public class B2Frame extends Frame {
public static void main(String[] args) {
new Frame() {{
setBackground(Color.YELLOW);
setSize(400,340);
setVisible(true);
}};
}
}
The frame is responsible for painting its background so you need to make sure you let it do its job.
You demonstrate this by setting:
System.setProperty("sun.awt.noerasebackground", "true");
This will cause the background to always be black on resize expansions. (So don't do it.)
The following worked for me:
(AWT only) Set up double buffering using createBufferStrategy(2) - wrapped in addNotify() otherwise you'll run into exceptions during Frame creation
(Step 1 is only necessary in AWT as Swing is double buffered by default.)
Always (important) call super() in your Frame.paint() implementation
Set the background colour with setBackground() then the background should always be the same colour when expanding the frame
Sample code:
class InnerFrame extends Frame {
public void addNotify() {
super.addNotify();
// Buffer
createBufferStrategy(2);
strategy = getBufferStrategy();
}
public void paint(Graphics g) {
super(g);
//...
}
//...
}
I also noticed this. For me this issue was solved with changing layout manager (I've used Free Form Layout before) and it worked pretty well (system color painting).
But eventually I switched back to FFL. Also some well known apps face this problem (f.e. SKYPE), but I actually don't mind it ...

Categories

Resources