Make transparent JFrame with visible borders - java

I'm trying to create a transparent JFrame, i.e. a window where the interior is completely transparent while the border, which is the top bar with the close button, minimize etc visible. I tried creating a new Jpanel and then using panel.setOpaque(false);, but it did not help.
I'm extremely new to swing and Java GUI and would love to get some help.

What you want to do is possible, but not in the way you're imagining it...
If you want your standard operating system's window decorations (i.e. window border, close, maximize, minimize buttons), it's impossible. Transparency cannot be applied to 'decorated' frames.
However, this can be done by using Java's default window decorations. Try out the code below:
public static void main(String[] args) {
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.RED);
g.drawRect(32,32,32,32);
}
};
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame f = new JFrame();
f.add(panel);
f.setSize(256,256);
// The following two statements cause the window-transparency:
f.setUndecorated(true);
f.setBackground(new Color(0,255,0,0));
f.setVisible(true);
}
I personally don't find the Java window decorations very nice looking... Apart from that, OS-specific features (such as Window's Snap feature by 'half-maximizing' a window by moving it to the side of the screen) don't work... To me this is a deal-breaker, but depending on your needs, it could be an acceptable solution. :)

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.

Java - How to fill a Windows L&F button with color instead of just the border?

I'm doing a few GUI tests with Java on Windows 7. I would like to use the Windows Look & Feel because Java's default "Metal" UI is really ugly IMO. When I set the background color of a button, it just colors the border around the button rather than fill its whole background.
public class GUITest {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {} // I know, not a good idea, but it's just a test
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JButton button = new JButton("Windows L&F");
button.setFocusable(false);
button.setBackground(Color.GREEN.darker());
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
The result is this:
Whereas I'm aiming for something like this (but without using the Metal L&F):
Is there a way to do that with the Windows L&F, or is it simply not built in?
Some PLAFs support (custom) colored buttons. Others don't.
One way to achieve what you seem to want is to write the button text in an image with green BG and use the image for an icon of a button without text.
If you want green filled in the button simply use
button.setBorderPainted(false);
which will fill the whole button with your color as shown in your second picture.

Disable maximise in jFrame and resizeable using mouse

JFrame with hidden or no maximize button but should be able to re-size using mouse(clicking and dragging on jFrame border). setResizable(false) is only disabling the minimize button but not able to re-size using mouse.
I personally can't think of a reason to allow resize and not allow maximize but here is an example of how to prevent maximizing a JFrame while still allowing resize and minimize. Tested in windows, untested on all other platforms. Full screen flash is minimized using setMaximizedBounds().
final JFrame jFrameNoMax = new JFrame() {
{
setMaximizedBounds(new Rectangle(0, 0));
addWindowStateListener(new WindowStateListener() {
public void windowStateChanged(final WindowEvent e) {
if (e.getNewState() == MAXIMIZED_BOTH) {
setExtendedState(NORMAL);
}
}
});
}
};
// Tester
jFrameNoMax.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrameNoMax.setSize(300, 300);
jFrameNoMax.setLocation(300, 300);
jFrameNoMax.setVisible(true);
You can take the following steps:
-Right click on JFrame
-Select properties
-Uncheck the resizable checkbox
-Close properties
-Run the program
See the attached illustration:
One option could be to use a JDialog instead of a JFrame. This allows the window to be manually resizeable but not maximizeable. The only problem with doing this is that you lose both the minimize and maximize buttons. This may or may not be a problem for your application.

Can you put JFrames inside Full Screen Exclusive Mode?

To be honest, I didn't quite know how to express my question in the title. So if someone has a clearer idea of what i'm trying to ask, then please be so kind as to edit it, for the greater good of mankind.
I have the following code:
public class Main {
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
JFrame frame = new JFrame();
Window window = new Window(frame);
JButton btn = new JButton("Quit");
window.add(btn);
if(gd.isFullScreenSupported())
gd.setFullScreenWindow(window);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setFullScreenWindow(null);
}
});
}
}
What I want to do is make a library system, illustrated in full screen mode. Inside the full screen mode, there should be simple frame windows with text fields in them and so on... No heavy 2D/3D graphics required here...
My problem is, the quit button is resized to fit the entire screen. I've tried to use setBounds, setSize, etc, on the frame, window and even button... But it doesn't seem to let me be able to center the button in the middle.
So my question: Is it possible to make JFrame application windows inside a JFrame application window which is set to full screen exclusive mode? Or is it only possible to use full screen exclusive mode together with 2D/3D methods like drawing?
Note: The only thing I intend to use full screen mode for is to set it to a black background, and have a Jframe window ontop of this black background in the center of the application. It is to give the illusion that the application is actually a system.
Thank you.
P.S. please note that the quit button was merely for my own testing purposes. It won't be part of the actual system, so my question does not revolve around how to resize this particular quit button.
Fullscreen Exclusive Mode is not meant to have Swing components inside. It is meant as a high performance way to draw graphics in Java (and can benefit as much as possible of underlaying hardware if done right).
What you want to do could be done by using an undecorated JDesktopPane and maximize it over the dimensions of the screen. Then proceed with using a JInternalFrame to have a JFrame like window inside that JDesktopPane.
I've included links to the respective API sections, they should get you started.
I think that what you are after is an MDI Application. If that is what you are after you could take a look here.
Your problem is that you do not use layout manager correctly.
Learn about layout managers - the modules that put and size/resize the visual components on screen. Then decide how do you want your button to look like and then decide which layout manager to use. It will do its job.
You know what i also had the exact same problem and the only thing i know from my experience is that you can use jinternal frame and set its property undecorated to true then add your custom title bar according to your requirement.

Preserve border after removing title bar from JFrame

I want to remove title bar from JFrame, so I call setUndecorated(true) on that JFrame, but I would like to preserve border (nifty gradient) on that JFrame, which is present when decoration is on? Can I do that? Something like getting border instance for LookAndFeel default or make gradient border myself?
The default system LookAndFeel window borders are drawn by system, not Java, so there is no way to remove title bar from the window alone. The only thing you can do is undecorate your window and draw border by yourself (and yes, to fully copy system border you will have to put a lot of effort into it).
Maybe something like that could be available in SWT, but to use it you will have to abandon standart Swing.
You can accomplish this visually by creating a JPanel and giving it a border, then setting the panel as your frame's content.
public class Undecorated {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel borderedPanel = new JPanel();
//Use any border you want, eg a nice blue one
borderedPanel.setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5, Color.BLUE));
frame.setContentPane(borderedPanel);
frame.setUndecorated(true);
frame.setSize(new Dimension(200, 200));
frame.setVisible(true);
}
}

Categories

Resources