| Home > Core Java FAQ
> Abstract Window Toolkit FAQ |
| Abstract
Window Toolkit |
| Components,
Containers, and Peers(20) * Windows,
Frames, and Dialogs (19) * Miscellaneous
(31) |
| |
|
Q . How do I specify where a window is to be placed?
|
Ans :
In the JDK
1.1, use setBounds,
setSize, or setLocation;
in the JDK 1.0.2 use the older method names reshape,
resize, or move.
The
Window subclasses, such as Frame and Dialog,
all inherit from the AWT's Component class, which
defines the basic methods for moving and sizing user-interface
elements. The fundamental method for specifying both location and
size of any component in the JDK 1.1 is setBounds,
which takes either four int parameters or one Rectangle
parameter:
setBounds(int x, int y, int width, int height)
setBounds(Rectangle r)
For convenience, Component
provides additional methods for changing only the location or size
of a component:
setSize(int width, int height)
setSize(Dimension d)
setLocation(int x, int y)
setLocation(Point p)
All
of these method names were introduced in the JDK 1.1, as part of a
broad effort to make AWT method names more systematic and
property-like. They supersede the names in the JDK 1.0.2, as shown
in Table 5.2.
Table
5.2: Sample AWT Renamings
| JDK
1.1 name |
JDK
1.0.2 name |
setBounds |
reshape |
setSize |
resize |
setLocation |
move |
These
methods use absolute coordinates specified in screen units. The
origin, point (0, 0), lies at the top left of the
screen, x values increase rightward, and y
values increase downward. One screen unit equals one screen pixel.
You can also use information about
the user's screen size and resolution when positioning your
application's windows. The java.awt.Toolkit class
provides methods for obtaining the current screen size (pixels)
and resolution (pixels per inch):
/* methods in java.awt.Toolkit: */
getScreenResolution();
getScreenSize();
This allows
positioning by inches, for instance, or by proportion of available
screen space.
|
|
Q .
How do I close a Java window by using the icon in the upper right hand corner of a window?
|
Ans
:
Create an event handler class to extend WindowAdapter. Then
override WindowAdapter's windowClosing() to do the actions you want
when a window's "close" action is clicked. Then add that to the listeners for that window.
import java.awt.*;
import java.awt.event.*;
public class MyFrame extends Frame {
public MyFrame(String s) {super(s);
}
public class WL extends WindowAdapter {
public void windowClosing(WindowEvent e) {System.exit(0);}
}
// do your other Frame stuff
}
Somewhere in your initialization code, put:
f1.addWindowListener( f1. new WL() );
This last syntax is not commonly known to many people yet, it's another wacky artifact of inner classes.
Alternatively, combining the inner class and setting the handler in one go, you could do this:
MyFrame f1 = new f("wave");
f1.addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// and/or setVisible(false) and/or dispose()
System.exit(0);
}
});
|
|
Q . How can I draw at the top-left corner of a frame without it being covered by the frame's border?
|
Ans
:
Inset
values specify how much of a container's space is reserved for a
border, inside of which the container's components are arranged;
you set these values by overriding getInsets
(or insets in JDK 1.0.2) in your own
Container subclasses.
Each
container, for example a Frame instance, Panel
instance, or Applet instance, provides a rectangular
space in which to position the container's components. In the
default case, the components in a container can occupy the full
space of the container. Inset values, represented as an instance
of the Insets class, allow you to specify an amount
of space at one or more margins—a boundary inside which all
components must be placed. For example, a top inset of 10 means
that a component's top edge can be placed no higher than 10 units
(the space covered by 10 pixels) from the top of the container.
Inset values are useful for
containers that have border material surrounding their content
area. The Frame class, for instance, provides
top-level windows that have a title bar. The space for the title
bar is figured into the Insets instance, so that any
components placed in the Frame instance will neither
overlap nor lie underneath the title bar. Layout managers in
general take into account a container's inset
|
|
Q .
How do I create a borderless window?
|
Ans
:
Create an
instance of the Window class, give it a size, and
show it on screen.
The
JDK 1.0.2 includes the Window class, which creates
borderless windows affiliated with some top-level frame. You can
use a Window subclass, for example, to implement tool
tips, warning panels, or popup menus. (The JDK 1.1 provides a
ready-made PopupMenu class, but other uses for Window
remain.)
The Window constructor
requires one argument: a Frame instance. This frame
is conceptually the anchor or owner of the window instance,
although the window is not constrained to lie inside the frame.
Windows by default are not visible. After creating one, you must
give it a size and invoke its show method in order to
bring it on screen:
Frame aFrame = ...
Window aWindow = new Window(aFrame);
aWindow.setLayout(new FlowLayout());
aWindow.add(new Button("Press me."));
aWindow.add(new Label("A Window instance"));
aWindow.reshape(50, 50, 200, 200);
aWindow.show();
|
|
Q . How do I allow for the size of the title bar and border when I draw a Frame?
|
Ans
:
Use MyFrame.getInsets(). This returns a java.awt.Insets object
which has four ints: top, left, bottom, right, giving the number of
pixels each of those margins are inset from the top. You can use these
value to adjust the Dimension object returned by component.getSize().
If you are doing this in the constructor you need to ensure that the Frame's peer object is created first. Otherwise the Insets object
returned by getInsets() will have all zero values. Make a call to
Frame.addNotify() to have the peer created.
|
|
Q . How can my program tell when a window is resized?
|
Ans :
Override the setBounds(int,int,int,int) method of Component to do
what you want. Of course, have it call super.setBounds() as well. Note
that setBounds() replaces reshape() which is deprecated.
Note the new APIs call the deprecated APIs instead of the other way round. For example, Component.setBounds calls
Component.reshape, instead of reshape calling setBounds. This is because the AWT sometimes
needs to call these for its own purposes. If it called the old one which then called the new one, and you overrode the new one, the AWT
would (wrongly) not call your routine. By having the AWT call the new
one (and then the new one call the old one), any overrides of the new
one will correctly be called by the AWT as needed. If that didn't make
sense, forget I mentioned it.
|
|
Q .
Why doesn't my window close when I click on the X in the title bar?
|
Ans
: Here's how to make your program do that.
o JDK 1.0.2: Handle Event.WINDOW_DESTROY to do a hide() and dispose() on the Frame.
o JDK 1.1:
+ Listen for WindowEvent and do hide(); dispose(); in
windowClosing() - this really ought to be the
"default"
behaviour, so was made so for a Swing JFrame.
+ Enable AWTEvent.WINDOW_CLOSING and do the hide() and
dispose() in processWindowEvent().
o JDK 1.2: The Component JFrame does a close by default.
|
|
Q .
When I click on a Java window frame, it doesn't close!
|
Ans
: You need to add the code to listen for a window closing event, and
take the appropriate action (hide the window, exit the program if the
top level frame, etc).
The window closing event handler is simple:
Frame mf = new Frame("binky");
mf.addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0); // or setVisible(false); etc.
} });
This really should be the default behavior of an AWT Frame. So you'll be delighted to hear that JavaSoft has "made it so" for the JFrame
Swing component. That leads to a slightly different problem.
|
|
Q .
How can iconify/deiconify a window in Java?
|
Ans
:
JDK 1.1 had no way to write code to force a window to iconify or
deiconify. Support was added in JDK 1.2.
MyFrame.setState( Frame.ICONIFIED );
MyFrame.setState( Frame.NORMAL );
will do the trick. There is a corresponding getState();
|
|
Q . Is it possible to have a Java window float above all other windows.
|
Ans
: On MS Windows, a Window object floats above all other windows,
unlike a Frame, which is layered in with ordinary windows. This behavior yields a "floating" effect. Whether a Window object is really
supposed to float is another question entirely.
On Mac, a Window object is either layered in with other windows, just like a Frame is, or else it is entirely modal - depending on which VM
you use. In Java - there appears to be no easy way to get floating
behavior. If anyone knows otherwise, please send in your comments.
|
|
Q .
How do I detect a resize of a Frame or other Component?
|
Ans
:
If you are using JDK 1.0.2, you can override the reshape(int,
int, int, int) method of Component to do what you want; of course, have it
call super.reshape() as well. In JDK 1.1.x, setBounds() replaces reshape(), which is deprecated -
however, there is a better way of detecting the resize using the new
event model, than overriding setBounds(). Note the new APIs call the depecated one.
The proper way to detect the resize in 1.1.x is to register a ComponentListener on the Frame, like this:
import java.awt.*;
import java.awt.event.*;
class MyFrame extends Frame {
public MyFrame() {
addComponentListener(new CmpAdapter());
}
class CmpAdapter extends ComponentAdapter {
public void componentResized(ComponentEvent evt) {
//doSomething();
}
}
}
Alternatively, the same effect can be achieved like this:
class MyFrame extends Frame implements ComponentListener {
public MyFrame() {
addComponentListener(this);
}
public componentHidden(ComponentEvent evt) { }
public componentMoved(ComponentEvent evt) { }
public componentShown(ComponentEvent evt) { }
public componentResized(ComponentEvent evt) {
//doSomething
}
}
Or even with an anonymous inner class
public MyFrame() {
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent evt) {
// doSomething;
}
} );
}
|
|
Q . Why can't I see all the components I added to a Frame?
|
Ans
:
Frame myframe = new Frame("Child Frame");
myframe.resize(512,384);
myframe.add(new Label("Child"));
myframe.show();
The default layout manager for Frame is BorderLayout. Components positioned with a BorderLayout should include a positioning constant to
be correct. If you don't include one, "-1" is assumed, which causes the
component to go to the end of the list, and possibly be buried (in
terms of z-order) under any other components you add. So, change the
add to
myframe.add("Center", new Label("Child"));
and all will be well.
|
|
Q . How do I change the icon on my Frame or JFrame from the Java coffee cup to my own icon?
|
Ans
:
f.setIconImage( Toolkit.getDefaultToolkit().getImage(iconfilename) );
|
|
Q . How do I center a dialog box?
|
Ans
:
You cannot currently get the applet's absolute screen coordinates.
Its location (0,0) is relative to the browser, not the screen itself.
But you can center something that it pops up or displays centered on
the screen with code like this:
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
my_window.move(
( screen.width - my_window.size().width ) / 2,
( screen.height - my_window.size().height ) / 2 );
my_window.show().
In a related fashion, you can center something on its parent like this. Note the intelligent use of APIs like translate() to do the work for
you.
void center(Component parent) {
pack();
Point p = parent.getLocation();
Dimension d = parent.getSize();
Dimension s = getSize();
p.translate((d.width - s.width) / 2,
(d.height - s.height) / 2);
setLocation(p);
}
|
|
Q . Why aren't popup menus working cross-platform for me?
|
Ans
:
On Windows, the pop-up trigger is a mouse release (except in
certain programs like Netscape Communicator). On Unix, the pop-up trigger is a mouse press.
Therefore you need to ask the question isPopupTrigger() in both the
mousePressed() and mouseReleased() methods when implementing the MouseListener interface. Alternatively override Component's
processMouseEvent as a central place for handling mouse input.
|
|
Q . Why don't Dialogs work the way I want them to?
|
Ans
: Modal dialogs (dialog windows that stay up until you click on them)
are buggy in many browsers and in the 1.0.2 JDK. One bug is that the
dialog is not necessarily put on top when it is displayed. Most of the
modal dialog bugs are fixed in JDK 1.1.
|
|
Q .
Several operations in the AWT, such as setting the cursor (in JDK 1.0.2) or creating a dialog box, require specifying a Frame instance-how do I determine the Frame instance containing the current component?
|
Ans
:
You can
write your own method to search up the containment hierarchy and
stop when it reaches a Frame
instance (or null).
The
JDK (1.0.2 and 1.1) API provides no direct way to ask for the
top-level window that contains a given component. To find the Frame
instance that contains your component, follow the parent chain
upward until you reach a frame or you run out of parents:
public static Frame getFrame(Component comp) {
for (Component c = comp; c != null; c = c.getParent()) {
if (c instanceof Frame) {
return (Frame) c;
}
}
return null;
}
|
|
Q . How do I use a FileDialog object in my applet or application?
|
Ans
:
Create a FileDialog
instance, invoke show on it, and
query it for values after show
returns.
The
FileDialog class provides a window with which the
user can browse the local file system to select a file for either
loading or saving. The window is modal—once it is placed on
screen, it will block all other AWT input until the window is
dismissed.
To use a FileDialog in
your program, you need to create a FileDialog
instance, specify any default choices you wish it to present to
the user, and then show it on screen:
Frame myFrame = ...;
FileDialog dialog = new FileDialog(myFrame,
"Load File",
FileDialog.LOAD);
dialog.setFile("FileDialogExample.java");
dialog.show();
When
the dialog's show method returns, you know the user
has either selected a file or canceled the entire operation. If
the user cancels the operation, getFile returns null.
Otherwise, a file and directory are selected, which your program
can query and use:
String fileName = dialog.getFile();
String fileDirectory = dialog.getDirectory();
if (fileName != null && fileDirectory != null) {
// ... process the given file name and directory
// ... full path = fileDirectory + fileName
}
|
|
Q . Can I create nonresizable windows?
|
Ans
:
Yes and no;
the setResizable method (in class Frame)
exists in the JDK 1.0.2 API but is not implemented until the JDK
1.1.
The
AWT represents top-level bordered windows with the Frame
class. The setResizable method is designed to control
whether a top-level window can be resized under user control (that
is, by dragging on the window boundary with the mouse). The setResizable
method exists in the JDK 1.0.2 API but is unimplemented in that
release (a bug). The JDK 1.1 contains a working version of setResizable.
|