###############
InvisibleComponentTest.java Placement of buttons in a BoxLayout using rigid areas, struts, and glue
###############
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
/** Example of using rigid areas, struts, and glue to
* produce the effect of invisible components.
*
******************
public class InvisibleComponentTest extends JPanel {
Component spacer;
public InvisibleComponentTest() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
// Place a rigid invisible component 25 pixels wide and
// 75 pixels tall between the two buttons
JPanel p1= new JPanel();
spacer = Box.createRigidArea(new Dimension(20,75));
setUpPanel(p1, "Rigid Area - 20x75 pixels", spacer);
// Separate two buttons by a 60-pixel horizontal strut
JPanel p2= new JPanel();
spacer = Box.createHorizontalStrut(60);
setUpPanel(p2, "Horizontal Strut - 60 pixels", spacer);
// Horizontal glue in FlowLayout - not useful
JPanel p3= new JPanel();
spacer = Box.createHorizontalGlue();
setUpPanel(p3, "Horizontal Glue - FlowLayout", spacer);
// Add glue to fill all remaining horizontal space between
// the two buttons. Glue not supported by default FlowLayout
// of JPanel. Change layout of JPanel to BoxLayout.
JPanel p4= new JPanel();
p4.setLayout(new BoxLayout(p4,BoxLayout.X_AXIS));
spacer = Box.createHorizontalGlue();
setUpPanel(p4, "Horizontal Glue - BoxLayout", spacer);
add(p1);
add(p2);
add(p3);
add(p4);
}
// Helper to set the border and add components
private void setUpPanel(JPanel p, String title,
Component spacer) {
p.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(),title,
TitledBorder.TOP,TitledBorder.CENTER));
p.setBackground(Color.white);
p.add(new JButton("Left"));
p.add(spacer);
p.add(new JButton("Right"));
}
public static void main(String[] args) {
String title = "Using Invisible Components";
WindowUtilities.setNativeLookAndFeel();
WindowUtilities.openInJFrame(new InvisibleComponentTest(),
350, 325, title);
}
}
Aug 26
Placement of buttons in a BoxLayout using rigid areas, struts, and glue
Aug 26
Adds typing to the freehand drawing.
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
/** A better whiteboard that lets you enter
* text in addition to freehand drawing.
*
******************
public class Whiteboard extends SimpleWhiteboard {
protected FontMetrics fm;
public void init() {
super.init();
Font font = new Font("Serif", Font.BOLD, 20);
setFont(font);
fm = getFontMetrics(font);
addKeyListener(new CharDrawer());
}
private class CharDrawer extends KeyAdapter {
// When user types a printable character,
// draw it and shift position rightwards.
public void keyTyped(KeyEvent event) {
String s = String.valueOf(event.getKeyChar());
getGraphics().drawString(s, lastX, lastY);
record(lastX + fm.stringWidth(s), lastY);
}
}
}
Aug 26
java Nested container where the top-level panels are positioned by hand
######################
ButtonCol.java Nested container where the top-level panels are positioned by hand
######################
import java.applet.Applet;
import java.awt.*;
/** An example of a layout performed manually. The top-level
* panels are positioned by hand, after you determine the size
* of the applet. Since applets can't be resized in most
* browsers, setting the size once when the applet is created
* is sufficient.
*
***************************
public class ButtonCol extends Applet {
public void init() {
setLayout(null);
int width1 = getSize().width*4/10,
width2 = getSize().width - width1,
height = getSize().height;
Panel buttonPanel = new Panel();
buttonPanel.setBounds(0, 0, width1, height);
buttonPanel.setLayout(new GridLayout(6, 1));
buttonPanel.add(new Label("Buttons", Label.CENTER));
buttonPanel.add(new Button("Button One"));
buttonPanel.add(new Button("Button Two"));
buttonPanel.add(new Button("Button Three"));
buttonPanel.add(new Button("Button Four"));
buttonPanel.add(new Button("Button Five"));
add(buttonPanel);
Panel everythingElse = new Panel();
everythingElse.setBounds(width1+1, 0, width2, height);
everythingElse.add(new Label("Everything Else"));
add(everythingElse);
}
}
Aug 26
Layout of complicated GUI by taking advantage of nested containers
#################
NestedLayout.java Layout of complicated GUI by taking advantage of nested containers. Uses WindowUtilities.java and ExitListener.java.
##################
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
/** An example demonstrating the use of nested containers
* to lay out the components. See GridBagTest.java for
* implementation by a single layout manager, GridBagLayout.
*
*******************
*/
public class NestedLayout extends JPanel {
private JTextArea textArea;
private JButton bSaveAs, bOk, bExit;
private JTextField fileField;
public NestedLayout() {
setLayout(new BorderLayout(2,2));
setBorder(BorderFactory.createEtchedBorder());
textArea = new JTextArea(12,40); // 12 rows, 40 cols
bSaveAs = new JButton("Save As");
fileField = new JTextField("C:\\Document.txt");
bOk = new JButton("OK");
bExit = new JButton("Exit");
add(textArea,BorderLayout.CENTER);
// Set up buttons and textfield in bottom panel.
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(2,1));
JPanel subPanel1 = new JPanel();
JPanel subPanel2 = new JPanel();
subPanel1.setLayout(new BorderLayout());
subPanel2.setLayout(new FlowLayout(FlowLayout.RIGHT,2,2));
subPanel1.add(bSaveAs,BorderLayout.WEST);
subPanel1.add(fileField,BorderLayout.CENTER);
subPanel2.add(bOk);
subPanel2.add(bExit);
bottomPanel.add(subPanel1);
bottomPanel.add(subPanel2);
add(bottomPanel,BorderLayout.SOUTH);
}
public static void main(String[] args) {
WindowUtilities.setNativeLookAndFeel();
JFrame frame = new JFrame("Nested Containers");
frame.setContentPane(new NestedLayout());
frame.addWindowListener(new ExitListener());
frame.pack();
frame.setVisible(true);
}
}
##########################
Aug 26
A demo providing multiple buttons to select a playing card-A Panel, using CardLayout control which of four possible subpanels, holding a different card, to display
#######################
# CardDemo.java A demo providing multiple buttons to select a playing card. A Panel, using CardLayout control which of four possible subpanels, holding a different card, to display.Uses the following class and images:
* CardPanel.java A Panel that displays a playing card.
* ImageLabel.java A Canvas for displaying images.
* Ace.gif, King.gif, Queen.gif, Jack.gif.
#####################
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
/** An example of CardLayout. The right side of the window holds
* a Panel that uses CardLayout to control four possible
* subpanels (each of which is a CardPanel that shows a
* picture of a playing card). The buttons on the left side
* of the window manipulate the "cards" in this layout by
* calling methods in the right-hand panel's layout manager.
*
*********************************
public class CardDemo extends Applet implements ActionListener {
private Button first, last, previous, next;
private String[] cardLabels = { "Jack","Queen","King","Ace" };
private CardPanel[] cardPanels = new CardPanel[4];
private CardLayout layout;
private Panel cardDisplayPanel;
public void init() {
setBackground(Color.white);
setLayout(new BorderLayout());
addButtonPanel();
addCardDisplayPanel();
}
private void addButtonPanel() {
Panel buttonPanel = new Panel();
buttonPanel.setLayout(new GridLayout(9, 1));
Font buttonFont = new Font("SansSerif", Font.BOLD, 18);
buttonPanel.setFont(buttonFont);
for(int i=0; inot use CardLayout. Rather, instances of CardPanel
* are contained in another window used in the CardDemo
* example. It is this enclosing window that uses CardLayout
* to manipulate which CardPanel it shows.
*
*************************
public class CardPanel extends Panel {
private Label name;
private ImageLabel picture;
public CardPanel(String cardName,
URL directory, String imageFile) {
setLayout(new BorderLayout());
name = new Label(cardName, Label.CENTER);
name.setFont(new Font("SanSerif", Font.BOLD, 50));
add(name, BorderLayout.NORTH);
picture = new ImageLabel(directory, imageFile);
Panel picturePanel = new Panel();
picturePanel.add(picture);
add(picturePanel, BorderLayout.CENTER);
setSize(getPreferredSize());
}
public Label getLabel() {
return(name);
}
public ImageLabel getImageLabel() {
return(picture);
}
}
*******************
ImageLabel.java A Canvas for displaying images.
*******************
import java.awt.*;
import java.net.*;
/** A class for displaying images. It places the Image
* into a canvas so that it can moved around by layout
* managers, will get repainted automatically, etc.
* No mouseXXX or action events are defined, so it is
* most similar to the Label Component.
*
* By default, with FlowLayout the ImageLabel takes
* its minimum size (just enclosing the image). The
* default with BorderLayout is to expand to fill
* the region in width (North/South), height
* (East/West) or both (Center). This is the same
* behavior as with the builtin Label class. If you
* give an explicit setSize or
* setBounds call before adding the
* ImageLabel to the Container, this size will
* override the defaults.
*
* Here is an example of its use:
*
*
* public class ShowImages extends Applet {
* private ImageLabel image1, image2;
*
* public void init() {
* image1 = new ImageLabel(getCodeBase(),
* "some-image.gif");
* image2 = new ImageLabel(getCodeBase(),
* "other-image.jpg");
* add(image1);
* add(image2);
* }
* }
*
*
*/
public class ImageLabel extends Canvas {
// Instance variables.
// The actual Image drawn on the canvas.
private Image image;
// A String corresponding to the URL of the image you will
// get if you call the constructor with no arguments.
private static String defaultImageString
= "http://java.sun.com/lib/images/" +
"logo.java.color-transp.55x60.gif";
// The URL of the image. But sometimes we will use an existing
// image object (e.g. made by createImage) for which this info
// will not be available, so a default string is used here.
private String imageString = "";
// Turn this on to get verbose debugging messages.
private boolean debug = false;
/** Amount of extra space around the image. */
private int border = 0;
/** If there is a non-zero border, what color should it be?
* Default is to use the background color of the Container.
*/
private Color borderColor = null;
// Width and height of the Canvas. This is the
// width/height of the image plus twice the border.
private int width, height;
/** Determines if it will be sized automatically. If the user
* issues a setSize() or setBounds()call before adding the
* label to the Container, or if the LayoutManager resizes
* before drawing (as with BorderLayout), then those sizes
* override the default, which is to make the label the same
* size as the image it holds (after reserving space for the
* border, if any). This flag notes this, so subclasses that
* override ImageLabel need to check this flag, and if it is
* true, and they draw modified image, then they need to draw
* them based on the width height variables, not just blindly
* drawing them full size.
*/
private boolean explicitSize = false;
private int explicitWidth=0, explicitHeight=0;
// The MediaTracker that can tell if image has been loaded
// before trying to paint it or setSize based on its size.
private MediaTracker tracker;
// Used by MediaTracker to be sure image is loaded before
// paint & setSize, since you can't find out the size until it
// is done loading.
private static int lastTrackerID=0;
private int currentTrackerID;
private boolean doneLoading = false;
private Container parentContainer;
/** Create an ImageLabel with the default image.
*
* @see #getDefaultImageString
* @see #setDefaultImageString
*/
// Remember that the funny "this()" syntax calls
// constructor of same class
public ImageLabel() {
this(defaultImageString);
}
/** Create an ImageLabel using the image at URL
* specified by the string.
*
* @param imageURLString A String specifying the
* URL of the image.
*/
public ImageLabel(String imageURLString) {
this(makeURL(imageURLString));
}
/** Create an ImageLabel using the image at URL
* specified.
*
* @param imageURL The URL of the image.
*/
public ImageLabel(URL imageURL) {
this(loadImage(imageURL));
imageString = imageURL.toExternalForm();
}
/** Create an ImageLabel using the image in the file
* in the specified directory.
*
* @param imageDirectory Directory containing image
* @param file Filename of image
*/
public ImageLabel(URL imageDirectory, String file) {
this(makeURL(imageDirectory, file));
imageString = file;
}
/** Create an ImageLabel using the image specified. The other
* constructors eventually call this one, but you may want
* to call it directly if you already have an image (e.g.
* created through createImage).
*
* @param image The image
*/
public ImageLabel(Image image) {
this.image = image;
tracker = new MediaTracker(this);
currentTrackerID = lastTrackerID++;
tracker.addImage(image, currentTrackerID);
}
/** Makes sure that the Image associated with the Canvas is
* done loading before returning, since loadImage spins off
* a separate thread to do the loading. Once you get around
* to drawing the image, this will make sure it is loaded,
* waiting if not. The user does not need to call this at
* all, but if several ImageLabels are used in the same
* Container, this can cause several repeated layouts, so
* users might want to explicitly call this themselves before
* adding the ImageLabel to the Container. Another
* alternative is to start asynchronous loading by calling
* prepareImage on the ImageLabel's image (see getImage).
*
* @param doLayout Determines if the Container should be
* re-laid out after you are finished waiting. This
* should be true when called from user functions,
* but is set to false when called from getPreferredSize
* to avoid an infinite loop. This is needed when using
* BorderLayout, which calls getPreferredSize
* before calling paint.
*/
public void waitForImage(boolean doLayout) {
if (!doneLoading) {
debug("[waitForImage] - Resizing and waiting for "
+ imageString);
try { tracker.waitForID(currentTrackerID); }
catch (InterruptedException ie) {}
catch (Exception e) {
System.out.println("Error loading "
+ imageString + ": "
+ e.getMessage());
e.printStackTrace();
}
if (tracker.isErrorID(0))
new Throwable("Error loading image "
+ imageString).printStackTrace();
doneLoading = true;
if (explicitWidth != 0)
width = explicitWidth;
else
width = image.getWidth(this) + 2*border;
if (explicitHeight != 0)
height = explicitHeight;
else
height = image.getHeight(this) + 2*border;
setSize(width, height);
debug("[waitForImage] - " + imageString + " is "
+ width + "x" + height + ".");
// If no parent, you are OK, since it will have
// been resized before being added. But if
// parent exists, you have already been added,
// and the change in size requires re-layout.
if (((parentContainer = getParent()) != null)
&& doLayout) {
setBackground(parentContainer.getBackground());
parentContainer.doLayout();
}
}
}
/** Moves the image so that it is centered at
* the specified location, as opposed to the setLocation
* method of Component which places the top left
* corner at the specified location.
*
* Note: The effects of this could be undone
* by the LayoutManager of the parent Container, if
* it is using one. So this is normally only used
* in conjunction with a null LayoutManager.
*
* @param x The X coord of center of the image
* (in parent's coordinate system)
* @param y The Y coord of center of the image
* (in parent's coordinate system)
* @see java.awt.Component#setLocation
*/
public void centerAt(int x, int y) {
debug("Placing center of " + imageString + " at ("
+ x + "," + y + ")");
setLocation(x - width/2, y - height/2);
}
/** Determines if the x and y (in the ImageLabel's
* own coordinate system) is inside the
* ImageLabel. Put here because Netscape 2.02 has
* a bug in which it doesn't process contains() and
* locate() tests correctly.
*/
public synchronized boolean contains(int x, int y) {
return((x >= 0) && (x <= width)
&& (y >= 0) && (y <= height));
}
/** Draws the image. If you override this in a
* subclass, be sure to call super.paint.
*/
public void paint(Graphics g) {
if (!doneLoading)
waitForImage(true);
else {
if (explicitSize)
g.drawImage(image, border, border,
width-2*border, height-2*border,
this);
else
g.drawImage(image, border, border, this);
drawRect(g, 0, 0, width-1, height-1,
border, borderColor);
}
}
/** Used by layout managers to calculate the usual
* size allocated for the Component. Since some
* layout managers (e.g. BorderLayout) may
* call this before paint is called, you need to
* make sure that the image is done loading, which
* will force a setSize, which determines the values
* returned.
*/
public Dimension getPreferredSize() {
if (!doneLoading)
waitForImage(false);
return(super.getPreferredSize());
}
/** Used by layout managers to calculate the smallest
* size allocated for the Component. Since some
* layout managers (e.g. BorderLayout) may
* call this before paint is called, you need to
* make sure that the image is done loading, which
* will force a setSize, which determines the values
* returned.
*/
public Dimension getMinimumSize() {
if (!doneLoading)
waitForImage(false);
return(super.getMinimumSize());
}
// LayoutManagers (such as BorderLayout) might call
// setSize or setBounds with only 1 dimension of
// width/height non-zero. In such a case, you still
// want the other dimension to come from the image
// itself.
/** Resizes the ImageLabel. If you don't setSize the
* label explicitly, then what happens depends on
* the layout manager. With FlowLayout, as with
* FlowLayout for Labels, the ImageLabel takes its
* minimum size, just enclosing the image. With
* BorderLayout, as with BorderLayout for Labels,
* the ImageLabel is expanded to fill the
* section. Stretching GIF/JPG files does not always
* result in clear looking images. So just as
* with builtin Labels and Buttons, don't
* use FlowLayout if you don't want the Buttons to
* get resized. If you don't use any
* LayoutManager, then the ImageLabel will also
* just fit the image.
*
* Note that if you setSize explicitly, you must do
* it before the ImageLabel is added to the
* Container. In such a case, the explicit size
* overrides the image dimensions.
*
* @see #setBounds
*/
public void setSize(int width, int height) {
if (!doneLoading) {
explicitSize=true;
if (width > 0)
explicitWidth=width;
if (height > 0)
explicitHeight=height;
}
super.setSize(width, height);
}
/** Resizes the ImageLabel. If you don't setSize the
* label explicitly, then what happens depends on
* the layout manager. With FlowLayout, as with
* FlowLayout for Labels, the ImageLabel takes its
* minimum size, just enclosing the image. With
* BorderLayout, as with BorderLayout for Labels,
* the ImageLabel is expanded to fill the
* section. Stretching GIF/JPG files does not always
* result in clear looking images. So just as
* with builtin Labels and Buttons, don't
* use FlowLayout if you don't want the Buttons to
* get resized. If you don't use any
* LayoutManager, then the ImageLabel will also
* just fit the image.
*
* Note that if you setSize explicitly, you must do
* it before the ImageLabel is added to the
* Container. In such a case, the explicit size
* overrides the image dimensions.
*
* @see #setSize
*/
public void setBounds(int x, int y,
int width, int height) {
if (!doneLoading) {
explicitSize=true;
if (width > 0)
explicitWidth=width;
if (height > 0)
explicitHeight=height;
}
super.setBounds(x, y, width, height);
}
// You can't just set the background color to
// the borderColor and skip drawing the border,
// since it messes up transparent gifs. You
// need the background color to be the same as
// the container.
/** Draws a rectangle with the specified OUTSIDE
* left, top, width, and height.
* Used to draw the border.
*/
protected void drawRect(Graphics g,
int left, int top,
int width, int height,
int lineThickness,
Color rectangleColor) {
g.setColor(rectangleColor);
for(int i=0; i
Aug 26
BorderLayout divides the window into five regions
# BorderTest.java Five buttons arranged by BorderLayout
BorderLayout divides the window into five regions: NORTH, SOUTH, EAST, WEST, and CENTER.
/./././././././././././././
import java.applet.Applet;
import java.awt.*;
/** An example of BorderLayout.
*
&&&&&&&&&&&&&&&&&&&&&&&&&&&
public class BorderTest extends Applet {
public void init() {
setLayout(new BorderLayout());
add(new Button("Button 1"), BorderLayout.NORTH);
add(new Button("Button 2"), BorderLayout.SOUTH);
add(new Button("Button 3"), BorderLayout.EAST);
add(new Button("Button 4"), BorderLayout.WEST);
add(new Button("Button 5"), BorderLayout.CENTER);
}
}
&&&&&&&&&&&&&&&&&&&&
Aug 26
Checkboxes
Checkboxes.java Inherits from CloseableFrame.java.
******************
import java.awt.*;
/./././././././././
public class Checkboxes extends CloseableFrame {
public static void main(String[] args) {
new Checkboxes();
}
public Checkboxes() {
super("Checkboxes");
setFont(new Font("SansSerif", Font.BOLD, 18));
setLayout(new GridLayout(0, 2));
Checkbox box;
for(int i=0; i<12; i++) {
box = new Checkbox("Checkbox " + i);
if (i%2 == 0) {
box.setState(true);
}
add(box);
}
pack();
setVisible(true);
}
}
Aug 26
Places a Panel holding 100 buttons in a ScrollPane
import java.applet.Applet;
import java.awt.*;
/** Places a Panel holding 100 buttons in a ScrollPane that is
* too small to hold it.
*
*/
public class ScrollPaneTest extends Applet {
public void init() {
setLayout(new BorderLayout());
ScrollPane pane = new ScrollPane();
Panel bigPanel = new Panel();
bigPanel.setLayout(new GridLayout(10, 10));
for(int i=0; i<100; i++) {
bigPanel.add(new Button("Button " + i));
}
pane.add(bigPanel);
add(pane, BorderLayout.CENTER);
}
}
Aug 26
Five buttons arranged by FlowLayout
FlowTest.java
*************
FlowTest.java Five buttons arranged by FlowLayout
By default, FlowLayout arranges components in rows, left to right, and centered.
/././././././././././././
import java.applet.Applet;
import java.awt.*;
/** FlowLayout puts components in rows.
*
************************************
public class FlowTest extends Applet {
public void init() {
for(int i=1; i<6; i++) {
add(new Button("Button " + i));
}
}
}
Aug 26
A Frame that lets you draw circles with mouse clicks
SavedFrame.java
****************
A Frame that lets you draw circles with mouse clicks
//**************
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/** A Frame that lets you draw circles with mouse clicks
* and then save the Frame and all circles to disk.
*
public class SavedFrame extends CloseableFrame
implements ActionListener {
/** If a saved version exists, use it. Otherwise create a
* new one.
*/
public static void main(String[] args) {
SavedFrame frame;
File serializeFile = new File(serializeFilename);
if (serializeFile.exists()) {
try {
FileInputStream fileIn =
new FileInputStream(serializeFile);
ObjectInputStream in = new ObjectInputStream(fileIn);
frame = (SavedFrame)in.readObject();
frame.setVisible(true);
} catch(IOException ioe) {
System.out.println("Error reading file: " + ioe);
} catch(ClassNotFoundException cnfe) {
System.out.println("No such class: " + cnfe);
}
} else {
frame = new SavedFrame();
}
}
private static String serializeFilename ="SavedFrame.ser";
private CirclePanel circlePanel;
private Button clearButton, saveButton;
/** Build a frame with CirclePanel and buttons. */
public SavedFrame() {
super("SavedFrame");
setBackground(Color.white);
setFont(new Font("Serif", Font.BOLD, 18));
circlePanel = new CirclePanel();
add("Center", circlePanel);
Panel buttonPanel = new Panel();
buttonPanel.setBackground(Color.lightGray);
clearButton = new Button("Clear");
saveButton = new Button("Save");
buttonPanel.add(clearButton);
buttonPanel.add(saveButton);
add(buttonPanel, BorderLayout.SOUTH);
clearButton.addActionListener(this);
saveButton.addActionListener(this);
setSize(300, 300);
setVisible(true);
}
/** If "Clear" clicked, delete all existing circles. If "Save"
* clicked, save existing frame configuration (size,
* location, circles, etc.) to disk.
*/
public void actionPerformed(ActionEvent event) {
if (event.getSource() == clearButton) {
circlePanel.removeAll();
circlePanel.repaint();
} else if (event.getSource() == saveButton) {
try {
FileOutputStream fileOut =
new FileOutputStream("SavedFrame.ser");
ObjectOutputStream out =
new ObjectOutputStream(fileOut);
out.writeObject(this);
out.flush();
out.close();
} catch(IOException ioe) {
System.out.println("Error saving frame: " + ioe);
}
}
}
}
****************
