How can I make a default border for a JWindow?
I have a JWindow object that is created when a button is pressed in a JFrame. I want the JWindow to have the same type of border as the JFrame from which it's created. However, the JWindow is not created automatically with a border as the JFrame is, so I don't know how to set the border abstractly so that whatever border is used for the JFrame, per he default L&F, will also be used for the JWindow.
I tried grabbing the border object from the JFame instance itself, but there is no such field in JFrame or any of its ancestor classes. I looked at UIDefaults, but I have no idea how this class can be used to get what I want. For example, if I use UIDefaults.getBorder(Object obj), what do I specify for the argument?
I'd be happy with an abstract or a concrete solution. That is, either using the default Border for top level containers in the current L&F, or by grabbing an actual Border instance from a JFrame object.
-Mark
# 1
Search the forum for my "ShowUIDefaults.java" source file.Run the program and click on the "RootPane" tab when using the Metal LAF. Maybe one of these Borders is what you are looking for.
# 2
Perhaps I'm not understanding what I'm supposed to do with this. I did as you suggested, and it seems to me that the entry I want is the one where key = RootPane.frameBorder.
So I assume I'm supposed to invoke on the JWindow object
setBorder(UIManager.getBorder(RootPane.frameBorder).
The problem is there is no such class RootPane.
What am I missing?
-Mark
# 3
> The problem is there is no such class RootPane.
If you look at all the properties in the UIManager, none of them are "classes". They are simply keywords used to look up a given property. Basically its a Hashtable, where you have keyword, value pairs.
All I am suggesting is that you can use this Border if you want. I don't know if this will meet your requirements or not, but it the the only way I can think of getting a Border. Borders are Swing concepts and a JFRame is not a Swing component, so you can't just get the Border of the JFrame. Your code would be something like:
JPanel contentPane = (JPanel)yourWindow.getContentPane();
contentPane.setBorder( UIManager.getBorder( "RootPane.frameBorder" ) );
This will only work if you are using the Metal LAF. I don't know what will happen with other LAF's.
# 4
I Guess the javadoc is unclear. it says that the object passed to UIManager.getBorder() must be a Border or it will return null. Apaprently they mean it must be a string that names a Border class.
OK so I appreciate you trying to help me, but I guess I can't do what I want to do. MY app uses the default platform look and feel, cause I don't care much for Metal. So with WIndows classic L&F, for example, the Frame border is a raised bevel border, while with the newer WIndows L&F it's a dark blue line border. SO I was hoping to draw a border for my JWindow that would be whatever the default Frame border is for the current L&F.
So I tried what you suggested and it didn't draw a border on the JWindow at all. I 'm using the Windows L&F, which you warned me would have an unknown result. It seems strange to me that this can't be made to work. The JFrame object has a border. Why can't I just grab it set it as the border for my JWindow? This is what I meant by a concrete vice abstract approach. I tried
myWindow'sContentPane.setBorder(myFrame.getRootPane().getBorder())
but no border appears on the JWindow. Perhaps I should grab the border from a different object inside the JFrame, but I can't see any other classes in the containment hierarchy that have a border field or a getBorder() method.
Also, I'm curious why you said that JFrame is not a swing component. It's in package javax.swing, and the Border interface and implementing classes are in javax.swing.border.
-Mark
# 5
> Also, I'm curious why you said that JFrame is not a swing component.
A Swing component extends JComponent. Basically this means that all the painting of the component is done in Java. You can add Borders to any Swing component. It is called a light weight component. A light weight component cannot exist by itself on the window desktop.
JFrame, JDialog and JWindow are top level components. They can exist on their own on the windows desktop because essentially they are Windows native components. They have been fancied up to make it easy for you to access and add other Swing components to it which is why they are found in the swing package.
A Windows border is not the same thing as a Swing Border and there is no way to access the native windows border and use it in a Swing application (that I know of anyway). Swing Borders are not used in a normal JFrame, the Windows border is used. You can however, turn off the use of Windows decorations and use Swing painted decorations. Read the tutorial on [url http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html#setDefaultLookAndFeelDecorated]Specifying Windows Decorations[/url]. However, this doesn't really help you with your Border problem. If you look at the source code for the FrameBorder, you will find that the "blue" color of the Border is only painted for "active" windows and a JWindow can never be the active window, only the parent JFrame or JDialog is considered active.
Here is a simple program for you to play around with:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class FrameDecorated
{
public static void main(String[] args)
{
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setSize(300, 300);
frame.setVisible(true);
Border border = frame.getRootPane().getBorder();
//Border border = UIManager.getBorder( "RootPane.frameBorder" );
System.out.println( border );
JWindow window = new JWindow(frame);
JPanel contentPane = (JPanel)window.getContentPane();
contentPane.add(new JTextField(), BorderLayout.NORTH);
contentPane.setBorder( border );
window.setSize(300, 300);
window.setLocationRelativeTo( null );
window.setVisible( true );
System.out.println("Window:" + window);
Window ancestor = SwingUtilities.getWindowAncestor(contentPane);
System.out.println("Ancestor:" + ancestor);
System.out.println(ancestor.isActive());
System.out.println(frame.isActive());
}
}
# 6
Thanks for the excellent explanation. That sheds a lot of light on what's going on. And your sample app makes clear why the border won't get painted on the JWindow when I take it from the JFrame, given the implementation of FrameBorder as you pointed out.
So to solve my problem I used a JDialog instead of a JWindow. I wanted to have a matching border (to the JFrame) without the other decorations, but since that's not possible I decided it's better to have all the decorations and a matching border than to have a border by itself that doesn't necessarily match the JFrame.
Not exactly a vital issue, but I wanted to understand what was going on. Thanks for showing me.
-Mark