You are previewing Learning Java, 4th Edition.

Learning Java, 4th Edition

Cover of Learning Java, 4th Edition by Daniel Leuck... Published by O'Reilly Media, Inc.
  1. Learning Java
  2. Preface
    1. Who Should Read This Book
    2. New Developments
      1. New in This Edition (Java 6 and 7)
    3. Using This Book
    4. Online Resources
    5. Conventions Used in This Book
    6. Using Code Examples
    7. Safari® Books Online
    8. How to Contact Us
    9. Acknowledgments
  3. 1. A Modern Language
    1. Enter Java
      1. Java’s Origins
      2. Growing Up
    2. A Virtual Machine
    3. Java Compared with Other Languages
    4. Safety of Design
      1. Simplify, Simplify, Simplify...
      2. Type Safety and Method Binding
      3. Incremental Development
      4. Dynamic Memory Management
      5. Error Handling
      6. Threads
      7. Scalability
    5. Safety of Implementation
      1. The Verifier
      2. Class Loaders
      3. Security Managers
    6. Application and User-Level Security
    7. A Java Road Map
      1. The Past: Java 1.0–Java 1.6
      2. The Present: Java 7
      3. The Future
      4. Availability
  4. 2. A First Application
    1. Java Tools and Environment
    2. Configuring Eclipse and Creating a Project
      1. Importing the Learning Java Examples
    3. HelloJava
      1. Classes
      2. The main() Method
      3. Classes and Objects
      4. Variables and Class Types
      5. HelloComponent
      6. Inheritance
      7. The JComponent Class
      8. Relationships and Finger Pointing
      9. Package and Imports
      10. The paintComponent() Method
    4. HelloJava2: The Sequel
      1. Instance Variables
      2. Constructors
      3. Events
      4. The repaint() Method
      5. Interfaces
    5. HelloJava3: The Button Strikes!
      1. Method Overloading
      2. Components
      3. Containers
      4. Layout
      5. Subclassing and Subtypes
      6. More Events and Interfaces
      7. Color Commentary
      8. Static Members
      9. Arrays
      10. Our Color Methods
    6. HelloJava4: Netscape’s Revenge
      1. Threads
      2. The Thread Class
      3. The Runnable Interface
      4. Starting the Thread
      5. Running Code in the Thread
      6. Exceptions
      7. Synchronization
  5. 3. Tools of the Trade
    1. JDK Environment
    2. The Java VM
    3. Running Java Applications
      1. System Properties
    4. The Classpath
      1. javap
    5. The Java Compiler
    6. JAR Files
      1. File Compression
      2. The jar Utility
      3. The pack200 Utility
    7. Policy Files
      1. The Default Security Manager
      2. The policytool Utility
      3. Using a Policy File with the Default Security Manager
  6. 4. The Java Language
    1. Text Encoding
      1. Javadoc Comments
    3. Types
      1. Primitive Types
      2. Reference Types
      3. A Word About Strings
    4. Statements and Expressions
      1. Statements
      2. Expressions
    5. Exceptions
      1. Exceptions and Error Classes
      2. Exception Handling
      3. Bubbling Up
      4. Stack Traces
      5. Checked and Unchecked Exceptions
      6. Throwing Exceptions
      7. try Creep
      8. The finally Clause
      9. Try with Resources
      10. Performance Issues
    6. Assertions
      1. Enabling and Disabling Assertions
      2. Using Assertions
    7. Arrays
      1. Array Types
      2. Array Creation and Initialization
      3. Using Arrays
      4. Anonymous Arrays
      5. Multidimensional Arrays
      6. Inside Arrays
  7. 5. Objects in Java
    1. Classes
      1. Accessing Fields and Methods
      2. Static Members
    2. Methods
      1. Local Variables
      2. Shadowing
      3. Static Methods
      4. Initializing Local Variables
      5. Argument Passing and References
      6. Wrappers for Primitive Types
      7. Autoboxing and Unboxing of Primitives
      8. Variable-Length Argument Lists
      9. Method Overloading
    3. Object Creation
      1. Constructors
      2. Working with Overloaded Constructors
      3. Static and Nonstatic Initializer Blocks
    4. Object Destruction
      1. Garbage Collection
      2. Finalization
      3. Weak and Soft References
    5. Enumerations
      1. Enum Values
      2. Customizing Enumerations
  8. 6. Relationships Among Classes
    1. Subclassing and Inheritance
      1. Shadowed Variables
      2. Overriding Methods
      3. Special References: this and super
      4. Casting
      5. Using Superclass Constructors
      6. Full Disclosure: Constructors and Initialization
      7. Abstract Methods and Classes
    2. Interfaces
      1. Interfaces as Callbacks
      2. Interface Variables
      3. Subinterfaces
    3. Packages and Compilation Units
      1. Compilation Units
      2. Package Names
      3. Class Visibility
      4. Importing Classes
    4. Visibility of Variables and Methods
      1. Basic Access Modifiers
      2. Subclasses and Visibility
      3. Interfaces and Visibility
    5. Arrays and the Class Hierarchy
      1. ArrayStoreException
    6. Inner Classes
      1. Inner Classes as Adapters
      2. Inner Classes Within Methods
  9. 7. Working with Objects and Classes
    1. The Object Class
      1. Equality and Equivalence
      2. Hashcodes
      3. Cloning Objects
    2. The Class Class
    3. Reflection
      1. Modifiers and Security
      2. Accessing Fields
      3. Accessing Methods
      4. Accessing Constructors
      5. What About Arrays?
      6. Accessing Generic Type Information
      7. Accessing Annotation Data
      8. Dynamic Interface Adapters
      9. What Is Reflection Good For?
    4. Annotations
      1. Using Annotations
      2. Standard Annotations
      3. The apt Tool
  10. 8. Generics
    1. Containers: Building a Better Mousetrap
      1. Can Containers Be Fixed?
    2. Enter Generics
      1. Talking About Types
    3. “There Is No Spoon”
      1. Erasure
      2. Raw Types
    4. Parameterized Type Relationships
      1. Why Isn’t a List<Date> a List<Object>?
    5. Casts
    6. Writing Generic Classes
      1. The Type Variable
      2. Subclassing Generics
      3. Exceptions and Generics
      4. Parameter Type Limitations
    7. Bounds
      1. Erasure and Bounds (Working with Legacy Code)
    8. Wildcards
      1. A Supertype of All Instantiations
      2. Bounded Wildcards
      3. Thinking Outside the Container
      4. Lower Bounds
      5. Reading, Writing, and Arithmetic
      6. <?>, <Object>, and the Raw Type
      7. Wildcard Type Relationships
    9. Generic Methods
      1. Generic Methods Introduced
      2. Type Inference from Arguments
      3. Type Inference from Assignment Context
      4. Explicit Type Invocation
      5. Wildcard Capture
      6. Wildcard Types Versus Generic Methods
    10. Arrays of Parameterized Types
      1. Using Array Types
      2. What Good Are Arrays of Generic Types?
      3. Wildcards in Array Types
    11. Case Study: The Enum Class
    12. Case Study: The sort() Method
    13. Conclusion
  11. 9. Threads
    1. Introducing Threads
      1. The Thread Class and the Runnable Interface
      2. Controlling Threads
      3. Death of a Thread
    2. Threading an Applet
      1. Issues Lurking
    3. Synchronization
      1. Serializing Access to Methods
      2. Accessing class and instance Variables from Multiple Threads
      3. The wait() and notify() Methods
      4. Passing Messages
      5. ThreadLocal Objects
    4. Scheduling and Priority
      1. Thread State
      2. Time-Slicing
      3. Priorities
      4. Yielding
    5. Thread Groups
      1. Working with ThreadGroups
      2. Uncaught Exceptions
    6. Thread Performance
      1. The Cost of Synchronization
      2. Thread Resource Consumption
    7. Concurrency Utilities
      1. Executors
      2. Locks
      3. Synchronization Constructs
      4. Atomic Operations
    8. Conclusion
  12. 10. Working with Text
    1. Text-Related APIs
    2. Strings
      1. Constructing Strings
      2. Strings from Things
      3. Comparing Strings
      4. Searching
      5. Editing
      6. String Method Summary
      7. StringBuilder and StringBuffer
    3. Internationalization
      1. The java.util.Locale Class
      2. Resource Bundles
    4. Parsing and Formatting Text
      1. Parsing Primitive Numbers
      2. Tokenizing Text
    5. Printf-Style Formatting
      1. Formatter
      2. The Format String
      3. String Conversions
      4. Primitive and Numeric Conversions
      5. Flags
      6. Miscellaneous
    6. Formatting with the java.text Package
      1. MessageFormat
    7. Regular Expressions
      1. Regex Notation
      2. The java.util.regex API
  13. 11. Core Utilities
    1. Math Utilities
      1. The java.lang.Math Class
      2. Big/Precise Numbers
      3. Floating-Point Components
      4. Random Numbers
    2. Dates and Times
      1. Working with Calendars
      2. Time Zones
      3. Parsing and Formatting with DateFormat
      4. Printf-Style Date and Time Formatting
    3. Timers
    4. Collections
      1. The Collection Interface
      2. Iterator
      3. Collection Types
      4. The Map Interface
      5. Collection Implementations
      6. Hash Codes and Key Values
      7. Synchronized and Unsynchronized Collections
      8. Read-Only and Read-Mostly Collections
      9. WeakHashMap
      10. EnumSet and EnumMap
      11. Sorting Collections
      12. A Thrilling Example
    5. Properties
      1. Loading and Storing
      2. System Properties
    6. The Preferences API
      1. Preferences for Classes
      2. Preferences Storage
      3. Change Notification
    7. The Logging API
      1. Overview
      2. Logging Levels
      3. A Simple Example
      4. Logging Setup Properties
      5. The Logger
      6. Performance
    8. Observers and Observables
  14. 12. Input/Output Facilities
    1. Streams
      1. Basic I/O
      2. Character Streams
      3. Stream Wrappers
      4. Pipes
      5. Streams from Strings and Back
      6. Implementing a Filter Stream
    2. File I/O
      1. The Class
      2. File Streams
      3. RandomAccessFile
      4. Resource Paths
    3. The NIO File API
      1. FileSystem and Path
      2. NIO File Operations
      3. Directory Operations
      4. Watching Paths
    4. Serialization
      1. Initialization with readObject()
      2. SerialVersionUID
    5. Data Compression
      1. Archives and Compressed Data
      2. Decompressing Data
      3. Zip Archive As a Filesystem
    6. The NIO Package
      1. Asynchronous I/O
      2. Performance
      3. Mapped and Locked Files
      4. Channels
      5. Buffers
      6. Character Encoders and Decoders
      7. FileChannel
      8. Scalable I/O with NIO
  15. 13. Network Programming
    1. Sockets
      1. Clients and Servers
      2. author="pat” timestamp="20120926T110720-0500” comment="one of those sections I hate to get rid of but is less relevant in terms of the example... should probably find a more modern example...”The DateAtHost Client
      3. The TinyHttpd Server
      4. Socket Options
      5. Proxies and Firewalls
    2. Datagram Sockets
      1. author="pat” timestamp="20120926T141346-0500” comment="I actually rewrote this as a standalone client but then decided to leave it as an applet”The HeartBeat Applet
      2. InetAddress
    3. Simple Serialized Object Protocols
      1. A Simple Object-Based Server
    4. Remote Method Invocation
      1. Real-World Usage
      2. Remote and Nonremote Objects
      3. An RMI Example
      4. RMI and CORBA
    5. Scalable I/O with NIO
      1. Selectable Channels
      2. Using Select
      3. LargerHttpd
      4. Nonblocking Client-Side Operations
  16. 14. Programming for the Web
    1. Uniform Resource Locators (URLs)
    2. The URL Class
      1. Stream Data
      2. Getting the Content as an Object
      3. Managing Connections
      4. Handlers in Practice
      5. Useful Handler Frameworks
    3. Talking to Web Applications
      1. Using the GET Method
      2. Using the POST Method
      3. The HttpURLConnection
      4. SSL and Secure Web Communications
      5. URLs, URNs, and URIs
    4. Web Services
      1. XML-RPC
      2. WSDL
      3. The Tools
      4. The Weather Service Client
  17. 15. Web Applications and Web Services
    1. Web Application Technologies
      1. Page-Oriented Versus “Single Page” Applications
      2. JSPs
      3. XML and XSL
      4. Web Application Frameworks
      5. Google Web Toolkit
      6. HTML5, AJAX, and More...
    2. Java Web Applications
      1. The Servlet Lifecycle
      2. Servlets
      3. The HelloClient Servlet
      4. The Servlet Response
      5. Servlet Parameters
      6. The ShowParameters Servlet
      7. User Session Management
      8. The ShowSession Servlet
      9. The ShoppingCart Servlet
      10. Cookies
      11. The ServletContext API
      12. Asynchronous Servlets
    3. WAR Files and Deployment
      1. Configuration with web.xml and Annotations
      2. URL Pattern Mappings
      3. Deploying HelloClient
      4. Error and Index Pages
      5. Security and Authentication
      6. Protecting Resources with Roles
      7. Secure Data Transport
      8. Authenticating Users
      9. Procedural Authorization
    4. Servlet Filters
      1. A Simple Filter
      2. A Test Servlet
      3. Declaring and Mapping Filters
      4. Filtering the Servlet Request
      5. Filtering the Servlet Response
    5. Building WAR Files with Ant
      1. A Development-Oriented Directory Layout
      2. Deploying and Redeploying WARs with Ant
    6. Implementing Web Services
      1. Defining the Service
      2. Our Echo Service
      3. Using the Service
      4. Data Types
    7. Conclusion
  18. 16. Swing
    1. Components
      1. Peers and Look-and-Feel
      2. The MVC Framework
      3. Painting
      4. Enabling and Disabling Components
      5. Focus, Please
      6. Other Component Methods
      7. Layout Managers
      8. Insets
      9. Z-Ordering (Stacking Components)
      10. The revalidate() and doLayout() Methods
      11. Managing Components
      12. Listening for Components
      13. Windows, Frames and Splash Screens
      14. Other Methods for Controlling Frames
      15. Content Panes
      16. Desktop Integration
    2. Events
      1. Event Receivers and Listener Interfaces
      2. Event Sources
      3. Event Delivery
      4. Event Types
      5. The java.awt.event.InputEvent Class
      6. Mouse and Key Modifiers on InputEvents
      7. Focus Events
    3. Event Summary
      1. Adapter Classes
      2. Dummy Adapters
    4. The AWT Robot!
    5. Multithreading in Swing
  19. 17. Using Swing Components
    1. Buttons and Labels
      1. HTML Text in Buttons and Labels
    2. Checkboxes and Radio Buttons
    3. Lists and Combo Boxes
    4. The Spinner
    5. Borders
    6. Menus
    7. Pop-Up Menus
      1. Component-Managed Pop Ups
    8. The JScrollPane Class
    9. The JSplitPane Class
    10. The JTabbedPane Class
    11. Scrollbars and Sliders
    12. Dialogs
      1. File Selection Dialog
      2. The Color Chooser
  20. 18. More Swing Components
    1. Text Components
      1. The TextEntryBox Application
      2. Formatted Text
      3. Filtering Input
      4. Validating Data
      5. Say the Magic Word
      6. Sharing a Data Model
      7. HTML and RTF for Free
      8. Managing Text Yourself
    2. Focus Navigation
      1. Trees
      2. Nodes and Models
      3. Save a Tree
      4. Tree Events
      5. A Complete Example
    3. Tables
      1. A First Stab: Freeloading
      2. Round Two: Creating a Table Model
      3. Round Three: A Simple Spreadsheet
      4. Sorting and Filtering
      5. Printing JTables
    4. Desktops
    5. Pluggable Look-and-Feel
    6. Creating Custom Components
      1. Generating Events
      2. A Dial Component
      3. Model and View Separation
  21. 19. Layout Managers
    1. FlowLayout
    2. GridLayout
    3. BorderLayout
    4. BoxLayout
    5. CardLayout
    6. GridBagLayout
      1. The GridBagConstraints Class
      2. Grid Coordinates
      3. The fill Constraint
      4. Spanning Rows and Columns
      5. Weighting
      6. Anchoring
      7. Padding and Insets
      8. Relative Positioning
      9. Composite Layouts
    7. Other Layout Managers
    8. Absolute Positioning
  22. 20. Drawing with the 2D API
    1. The Big Picture
    2. The Rendering Pipeline
    3. A Quick Tour of Java 2D
      1. Filling Shapes
      2. Drawing Shape Outlines
      3. Convenience Methods
      4. Drawing Text
      5. Drawing Images
      6. The Whole Iguana
    4. Filling Shapes
      1. Solid Colors
      2. Color Gradients
      3. Textures
      4. Desktop Colors
    5. Stroking Shape Outlines
    6. Using Fonts
      1. Font Metrics
    7. Displaying Images
      1. The Image Class
      2. Image Observers
      3. Scaling and Size
    8. Drawing Techniques
      1. Double Buffering
      2. Limiting Drawing with Clipping
      3. Offscreen Drawing
    9. Printing
  23. 21. Working with Images and Other Media
    1. Loading Images
      1. ImageObserver
      2. MediaTracker
      3. ImageIcon
      4. ImageIO
    2. Producing Image Data
      1. Drawing Animations
      2. BufferedImage Anatomy
      3. Color Models
      4. Creating an Image
      5. Updating a BufferedImage
    3. Filtering Image Data
      1. How ImageProcessor Works
      2. Converting an Image to a BufferedImage
      3. Using the RescaleOp Class
      4. Using the AffineTransformOp Class
    4. Saving Image Data
    5. Simple Audio
    6. Java Media Framework
  24. 22. JavaBeans
    1. What’s a Bean?
      1. What Constitutes a Bean?
    2. The NetBeans IDE
      1. Installing and Running NetBeans
    3. Properties and Customizers
    4. Event Hookups and Adapters
      1. Taming the Juggler
      2. Molecular Motion
    5. Binding Properties
      1. Constraining Properties
    6. Building Beans
      1. The Dial Bean
      2. Design Patterns for Properties
    7. Limitations of Visual Design
    8. Serialization Versus Code Generation
    9. Customizing with BeanInfo
      1. Getting Properties Information
    10. Handcoding with Beans
      1. Bean Instantiation and Type Management
      2. Working with Serialized Beans
      3. Runtime Event Hookups with Reflection
    11. BeanContext and BeanContextServices
    12. The Java Activation Framework
    13. Enterprise JavaBeans and POJO-Based Enterprise Frameworks
  25. 23. Applets
    1. The Politics of Browser-Based Applications
    2. Applet Support and the Java Plug-in
    3. The JApplet Class
      1. Applet Lifecycle
      2. The Applet Security Sandbox
      3. Getting Applet Resources
      4. The <applet> Tag
      5. Attributes
      6. Parameters
      7. ¿Habla Applet?
      8. The Complete <applet> Tag
      9. Loading Class Files
      10. Packages
      11. appletviewer
    4. Java Web Start
    5. Conclusion
  26. 24. XML
    1. The Butler Did It
    2. A Bit of Background
      1. Text Versus Binary
      2. A Universal Parser
      3. The State of XML
      4. The XML APIs
      5. XML and Web Browsers
    3. XML Basics
      1. Attributes
      2. XML Documents
      3. Encoding
      4. Namespaces
      5. Validation
      6. HTML to XHTML
    4. SAX
      1. The SAX API
      2. Building a Model Using SAX
      3. XMLEncoder/Decoder
    5. DOM
      1. The DOM API
      2. Test-Driving DOM
      3. Generating XML with DOM
      4. JDOM
    6. XPath
      1. Nodes
      2. Predicates
      3. Functions
      4. The XPath API
      5. XMLGrep
    7. XInclude
      1. Enabling XInclude
    8. Validating Documents
      1. Using Document Validation
      2. DTDs
      3. XML Schema
      4. The Validation API
    9. JAXB Code Binding and Generation
      1. Annotating Our Model
      2. Generating a Java Model from an XML Schema
      3. Generating an XML Schema from a Java Model
    10. Transforming Documents with XSL/XSLT
      1. XSL Basics
      2. Transforming the Zoo Inventory
      3. XSLTransform
      4. XSL in the Browser
    11. Web Services
    12. The End of the Book
  27. A. The Eclipse IDE
    1. The IDE Wars
    2. Getting Started with Eclipse
      1. Importing the Learning Java Examples
    3. Using Eclipse
      1. Getting at the Source
      2. The Lay of the Land
      3. Running the Examples
      4. Building the Ant-Based Examples
      5. Loner Examples
    4. Eclipse Features
      1. Coding Shortcuts
      2. Autocorrection
      3. Refactoring
      4. Diffing Files
      5. Organizing Imports
      6. Formatting Source Code
    5. Conclusion
  28. B. BeanShell: Java Scripting
    1. Running BeanShell
    2. Java Statements and Expressions
      1. Imports
    3. BeanShell Commands
    4. Scripted Methods and Objects
      1. Scripting Interfaces and Adapters
    5. Changing the Classpath
    6. Learning More . . .
  29. Glossary
  30. Index
  31. About the Authors
  32. Colophon
  33. Copyright


GridBagLayout is a very flexible layout manager that allows you to position components relative to one another using constraints. With GridBagLayout (and a fair amount of effort), you can create almost any imaginable layout. Components are arranged at logical coordinates on an abstract grid. We call them “logical” coordinates because they designate positions in the space of rows and columns formed by the set of components. Rows and columns of the grid stretch to different sizes, based on the sizes and constraints of the components they hold.

A row or column in a GridBagLayout expands to accommodate the dimensions and constraints of the largest component it contains. Individual components may also be told to span more than one row or column. Components that aren’t as large as their grid cell can be anchored (positioned to one side) within their cell. They can also be set to fill or expand their size in either dimension. Extra area in the grid rows and columns can be parceled out according to the weight constraints of the components. In this way, you can control how various components will grow and stretch when a window is resized.

GridBagLayout is much easier to use in a graphical WYSIWYG GUI builder environment. That’s because working with GridBag is kind of like messing with the old rabbit-ears antennae on your television. It’s not particularly difficult to get the results that you want through trial and error, but writing out hard and fast rules for how to go about it is difficult. In short, GridBagLayout is complex and has some quirks. It is also simply a bit ugly both in model and implementation. Remember that you can do a lot with nested panels and by composing simpler layout managers within one another. If you look back through this chapter, you’ll see some examples of composite layouts; it’s up to you to determine how far you should go before making the break from simpler layout managers to a more complex all-in-one layout manager like GridBagLayout.

The GridBagConstraints Class

Having stated that GridBagLayout is complex and a bit ugly, we’re going to contradict ourselves a little and say that its API is surprisingly simple. There is only one constructor with no arguments—GridBagLayout()—and there aren’t a lot of fancy methods to control how the display works.

The appearance of a grid bag layout is controlled by sets of GridBagConstraints, and that’s where things get hairy. Each component that is managed by a GridBagLayout is associated with a GridBagConstraints object. GridBagConstraints holds the following variables, which we’ll describe in detail shortly:

int gridx
int gridy

Controls the position of the component on the layout’s grid

int weightx
int weighty

Controls how additional space in the row or column is allotted to the component

int fill

Controls whether the component expands to fill the allotted space

int gridheight
int gridwidth

Controls the number of rows or columns the component spans

int anchor

Controls the position of the component if there is extra room within the allotted space

int ipadx
int ipady

Controls padding between the component and the borders of its area

Insets insets

Controls padding between the component and neighboring components

To make a set of constraints for a component or components, create a new instance of GridBagConstraints and set these public variables to the appropriate values. (There is also a large constructor that takes all 11 arguments.)

The easiest way to associate a set of constraints with a component is to use the version of add() that takes both a component object and a layout object as arguments. This puts the component in the container and associates the GridBagConstraints object with it:

    Container content = getContentPane();
    JComponent component = new JLabel("constrain me, please...");
    GridBagConstraints constraints = new GridBagConstraints();
    constraints.gridx = x;
    constraints.gridy = y;
    content.add(component, constraints);

You can also add a component to a GridBagLayout using the single argument add() method and then calling the layout’s setConstraints() method directly to pass it the GridBagConstraints object for that component:

    myGridBagLayout.setConstraints(component, constraints);

In either case, the set of constraints is copied when it is applied to the component. It’s the individual constraints that apply to the component, not the GridBagConstraints object. Therefore, you’re free to create a single set of GridBagConstraints, modify it as needed, and apply it as needed to different objects. You might want to create a helper method that sets the constraints appropriately, then adds the component with its constraints to the layout. That’s the approach we’ll take in our examples; our helper method is called addGB(), and it takes a component plus a pair of coordinates as arguments. These coordinates become the gridx and gridy values for the constraints. We could expand upon this later and overload addGB() to take more parameters for other constraints that we often change from component to component.

Grid Coordinates

One of the biggest surprises in the GridBagLayout is that there’s no way to specify the size of the grid. There doesn’t have to be. The grid size is determined implicitly by the constraints of all the objects; the layout manager picks dimensions large enough so that everything fits. Thus, if you put one component in a layout and set its gridx and gridy constraints each to 25, the layout manager creates a virtual 25 × 25 grid, with rows and columns numbered from 0 to 24. If you then add a second component with a gridx of 30 and a gridy of 13, the virtual grid’s dimensions change to 30 × 25. You don’t have to worry about setting up an appropriate number of rows and columns. The layout manager does it automatically as you add components.

With this knowledge, we’re ready to create some simple displays. We’ll start by arranging a group of components in a cross shape. We maintain explicit x and y local variables, setting them as we add the components to our grid. This is partly for clarity, but it can be a handy technique when you want to add a number of components in a row or column. You can simply increment gridx or gridy before adding each component. This is a simple and problem-free way to achieve relative placement. (Later, we’ll describe GridBagConstraints’s RELATIVE constant, which performs relative placement automatically.) The following code shows the first layout (see Figure 19-7):

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class GridBag1 extends JPanel {
      GridBagConstraints constraints = new GridBagConstraints();

      public GridBag1() {
        setLayout(new GridBagLayout());
        int x, y;  // for clarity
        addGB(new JButton("North"),  x = 1, y = 0);
        addGB(new JButton("West"),   x = 0, y = 1);
        addGB(new JButton("Center"), x = 1, y = 1);
        addGB(new JButton("East"),   x = 2, y = 1);
        addGB(new JButton("South"),  x = 1, y = 2);

      void addGB(Component component, int x, int y) {
        constraints.gridx = x;
        constraints.gridy = y;
        add(component, constraints);

      public static void main(String[] args) {
        JFrame frame = new JFrame("GridBag1");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setSize(225, 150);
        frame.setLocation(200, 200);
        frame.setContentPane(new GridBag1());
A simple GridBagLayout

Figure 19-7. A simple GridBagLayout

The buttons in this example are “clumped” together in the center of their display area. Each button is displayed at its preferred size, without stretching to fill the available space. This is how the layout manager behaves when the “weight” constraints are left unset. We’ll talk more about weights in the next two sections.

The fill Constraint

Let’s make the buttons expand to fill the entire JFrame window. To do so, we must take two steps: we must set the fill constraint for each button to the value BOTH, and we must set the weightx and weighty to nonzero values, as shown in this example:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class GridBag2 extends JPanel {
      GridBagConstraints constraints = new GridBagConstraints();

      public GridBag2() {
        setLayout(new GridBagLayout());
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.fill = GridBagConstraints.BOTH;
        int x, y;  // for clarity
        addGB(new JButton("North"),  x = 1, y = 0);
        addGB(new JButton("West"),   x = 0, y = 1);
        addGB(new JButton("Center"), x = 1, y = 1);
        addGB(new JButton("East"),   x = 2, y = 1);
        addGB(new JButton("South"),  x = 1, y = 2);

      void addGB(Component component, int x, int y) {
        constraints.gridx = x;
        constraints.gridy = y;
        add(component, constraints);

      public static void main(String[] args) {
        JFrame frame = new JFrame("GridBag2");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setSize(225, 150);
        frame.setLocation(200, 200);
        frame.setContentPane(new GridBag2());

Figure 19-8 shows the resulting layout.

Making buttons fill the available space

Figure 19-8. Making buttons fill the available space

BOTH is one of the constants of the GridBagConstraints class; it tells the component to fill the available space in both directions. Here are the constants you can use to set the fill field:


Fill the available horizontal space.


Fill the available vertical space.


Fill the available space in both directions.


Don’t fill the available space; display the component at its preferred size.

We set the weight constraints to 1.0; in this example, it doesn’t matter what they are, provided each component has the same nonzero weight. Filling doesn’t occur if the component’s weight in the direction you’re filling is 0, which is the default value.

Spanning Rows and Columns

One of the most important features of GridBaglayout is that it lets you create arrangements in which components span two or more rows or columns. To do so, set the gridwidth and gridheight variables of the GridBagConstraints. The following example creates such a display; button one spans two columns vertically and button four spans two horizontally. Figure 19-9 shows the resulting layout.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class GridBag3 extends JPanel {
      GridBagConstraints constraints = new GridBagConstraints();

      public GridBag3() {
        setLayout(new GridBagLayout());
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.fill = GridBagConstraints.BOTH;
        int x, y;  // for clarity
        constraints.gridheight = 2; // span two rows
        addGB(new JButton("one"),   x = 0, y = 0);
        constraints.gridheight = 1; // set it back
        addGB(new JButton("two"),   x = 1, y = 0);
        addGB(new JButton("three"), x = 2, y = 0);
        constraints.gridwidth = 2; // span two columns
        addGB(new JButton("four"),  x = 1, y = 1);
        constraints.gridwidth = 1; // set it back

      void addGB(Component component, int x, int y) {
        constraints.gridx = x;
        constraints.gridy = y;
        add(component, constraints);

      public static void main(String[] args) {
        JFrame frame = new JFrame("GridBag3");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setSize(200, 200);
        frame.setLocation(200, 200);
        frame.setContentPane(new GridBag3());
Making components span rows and columns

Figure 19-9. Making components span rows and columns

The size of each element is controlled by the gridwidth and gridheight values of its constraints. For button one, we set gridheight to 2; therefore, it is two cells high. Its gridx and gridy positions are both 0, so it occupies cell (0,0) and the cell directly below it, (0,1). Likewise, button four has a gridwidth of 2 and a gridheight of 1, so it occupies two cells horizontally. We place this button in cell (1,1), so it occupies that cell and its neighbor, (2,1).

In this example, we set the fill to BOTH and weightx and weighty to 1 for all components. By doing so, we tell each button to occupy all the space available and give them all equal weighting. Strictly speaking, this isn’t necessary. However, it makes it easier to see exactly how much space each button occupies.


The weightx and weighty variables of a GridBagConstraints object determine how “extra” space in the container is distributed among the columns or rows in the layout. As long as you keep things simple, the effect these variables have is fairly intuitive: the larger the weight, the greater the amount of space allocated to the component, relative to its peers. Figure 19-10 shows what happens if we vary the weightx constraint from 0.1 to 1.0 as we place three buttons in a row.

Here’s the code:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class GridBag4 extends JPanel {
      GridBagConstraints constraints = new GridBagConstraints();

      public GridBag4() {
        setLayout(new GridBagLayout());
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1.0;
        int x, y; // for clarity
        constraints.weightx = 0.1;
        addGB(new JButton("one"),   x = 0, y = 0);
        constraints.weightx = 0.5;
        addGB(new JButton("two"),   ++x,   y);
        constraints.weightx = 1.0;
        addGB(new JButton("three"), ++x,   y);

      void addGB(Component component, int x, int y) {
        constraints.gridx = x;
        constraints.gridy = y;
        add(component, constraints);

      public static void main(String[] args) {
        JFrame frame = new JFrame("GridBag4");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setSize(300, 100);
        frame.setLocation(200, 200);
        frame.setContentPane(new GridBag4());
Using weight to control component size

Figure 19-10. Using weight to control component size

The specific values of the weights are not meaningful; it is only their relative proportions that matter. After the preferred sizes of the components (including padding and insets—see the next section) are determined, any extra space is doled out in proportion to the component’s weights. For example, if each of our three components had the same weight, each would receive a third of the extra space. To make this more obvious, you may prefer to express the weights for a row or column as fractions totaling 1.0—for example: 0.25, 0.25, 0.50. Components with a weight of 0 receive no extra space.

The situation is a bit more complicated when there are multiple rows or columns and when there is even the possibility of components spanning more than one cell. In the general case, GridBagLayout calculates an effective overall weight for each row and column and then distributes the extra space to them proportionally. Note that the previous single-row example is just a special case where the columns each have one component. The gory details of the calculations follow.

Calculating the weights of rows and columns

For a given row or column (“rank”), GridBagLayout first considers the weights of all the components contained strictly within that rank—ignoring those that span more than one cell. The greatest individual weight becomes the overall weight of the row or column. Intuitively, this means that GridBagLayout is trying to accommodate the needs of the weightiest component in that rank.

Next, GridBagLayout considers the components that occupy more than one cell and things get a little weird. GridbagLayout wants to evaluate them to see whether they affect the determination of the largest weight in a row or column. However, because these components occupy more than one cell, GridBagLayout divides their weight among the ranks (rows or columns) that they span.

GridBagLayout tries to calculate an effective weight for the portion of the component that occupies each row or column. It does this by trying to divide the weight of the component among the ranks in the same proportions that the length (or height) of the component will be shared by the ranks. But how does it know what the proportions will be before the whole grid is determined? That’s what it’s trying to calculate, after all. It simply guesses based on the row or column weights already determined. GridBagLayout uses the weights determined by the first round of calculations to split up the weight of the component over the ranks that it occupies. For each row or column, it then considers that fraction of the weight to be the component’s weight for that rank. That weight then contends for the “heaviest weight” in the row or column, possibly changing the overall weight of that row or column, as we described earlier.


If a component is smaller than the space available for it, it is centered by default. But centering isn’t the only possibility. The anchor constraint tells a grid bag layout how to position a component within its cell in the grid. Possible values are GridBagConstraints.CENTER, NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, and NORTHWEST. For example, an anchor of GridBagConstraints.NORTH centers a component at the top of its display area; SOUTHEAST places a component at the bottom-right corner of its area.

Padding and Insets

Another way to control the behavior of a component in a grid bag layout is to use padding and insets. Padding is determined by the ipadx and ipady fields of GridBagConstraints. They specify horizontal and vertical “growth factors” for the component. In Figure 19-11, the West button is larger because we have set the ipadx and ipady values of its constraints to 25. Therefore, the layout manager gets the button’s preferred size and adds 25 pixels in each direction to determine the button’s actual size. The sizes of the other buttons are unchanged because their padding is set to 0 (the default), but their spacing is different. The West button is unnaturally tall, which means that the middle row of the layout must be taller than the others.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class GridBag5 extends JPanel {
      GridBagConstraints constraints = new GridBagConstraints();

      public GridBag5() {
        setLayout(new GridBagLayout
        int x, y;  // for clarity
        addGB(new JButton("North"),  x = 1, y = 0);
        constraints.ipadx = 25;  // add padding
        constraints.ipady = 25;
        addGB(new JButton("West"),   x = 0, y = 1);
        constraints.ipadx = 0;   // remove padding
        constraints.ipady = 0;
        addGB(new JButton("Center"), x = 1, y = 1);
        addGB(new JButton("East"),   x = 2, y = 1);
        addGB(new JButton("South"),  x = 1, y = 2);

      void addGB(Component component, int x, int y) {
        constraints.gridx = x;
        constraints.gridy = y;
        add(component, constraints);

      public static void main(String[] args) {
        JFrame frame = new JFrame("GridBag5");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        frame.setSize(250, 250);
        frame.setLocation(200, 200);
        frame.setContentPane(new GridBag5());
Using padding and insets in a layout

Figure 19-11. Using padding and insets in a layout

Notice that the horizontal padding, ipadx, is added on both the left and right sides of the button. Therefore, the button grows horizontally by twice the value of ipadx. Likewise, the vertical padding, ipady, is added on both the top and the bottom.

Insets add space between the edges of the component and its cell. They are stored in the insets field of GridBagConstraints, which is an Insets object. An Insets object has four fields to specify the margins on the component’s top, bottom, left, and right. The relationship between insets and padding can be confusing. As shown in Figure 19-12, padding is added to the component itself, increasing its size. Insets are external to the component and represent the margin between the component and its cell.

The relationship between padding and insets

Figure 19-12. The relationship between padding and insets

Padding and weighting have an odd interaction with each other. If you use padding, it’s best to use the default weightx and weighty values for each component.

Relative Positioning

In all our grid bag layouts so far, we have specified the gridx and gridy coordinates of each component explicitly using its constraints. Another alternative is relative positioning.

Conceptually, relative positioning is simple: we just say, “put this component to the right of (or below) the previous component.” To do so, you can set gridx or gridy to the constant GridBagConstraints.RELATIVE. Unfortunately, it’s not as simple as this. Here are a couple of warnings:

  • To place a component to the right of the previous one, set gridx to RELATIVEand use the same value for gridy that you used for the previous component.

  • Similarly, to place a component below the previous one, set gridy to RELATIVEand leave gridx unchanged.

  • Setting both gridx and gridy to RELATIVE places all the components in one row, not in a diagonal line, as you might expect. (This is the default.)

In other words, if gridx or gridy is RELATIVE, you had better leave the other value unchanged. RELATIVE makes it easy to arrange a lot of components in a row or a column. That’s what it was intended for; if you try to do something else, you’re fighting against the layout manager, not working with it.

GridBagLayout allows another kind of relative positioning in which you specify where, in a row or a column, the component should be placed overall using the gridwidth and gridheight fields of GridBagConstraints. Setting either of these to the constant REMAINDER says that the component should be the last item in its row or column and, therefore, should occupy all the remaining space. Setting either gridwidth or gridheight to RELATIVE says that it should be the second to the last item in its row or column. Unfortunately, you can use these constants to create constraints that can’t possibly be met; for example, you can say that two components must be the last component in a row. In these cases, the layout manager tries to do something reasonable, but it will almost certainly be something you don’t want done.

Composite Layouts

Sometimes things don’t fall neatly into little boxes. This is true of layouts as well as life. For example, if you want to use some of GridBagLayout’s weighting features for part of your GUI, you could create separate layouts for different parts of the GUI and combine them with yet another layout. That’s how we’ll build the pocket calculator interface in Figure 19-13. We will use three grid bag layouts: one for the first row of buttons (C, %, +), one for the last (0, ., =) and one for the window itself. The master layout (the window’s) manages the text field we use for the display, the panels containing the first and last rows of buttons, and the 12 buttons in the middle.[43]

The Calculator application

Figure 19-13. The Calculator application

Here’s the code for the Calculator example. It implements only the user interface (i.e., the keyboard); it collects everything you type in the display field until you press C (clear). Figuring out how to connect the GUI to some other code that would perform the operations is up to you. One strategy would be to send an event to the object that does the computation whenever the user presses the equals sign. That object could read the contents of the text field, parse it, do the computation, and display the results.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class Calculator extends JPanel implements ActionListener {
      GridBagConstraints gbc = new GridBagConstraints();
      JTextField theDisplay = new JTextField();

      public Calculator() {
        gbc.weightx = 1.0;  gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        ContainerListener listener = new ContainerAdapter() {
          public void componentAdded(ContainerEvent e) {
            Component comp = e.getChild();
            if (comp instanceof JButton)
        gbc.gridwidth = 4;
        addGB(this, theDisplay, 0, 0);
        // make the top row
        JPanel topRow = new JPanel();
        gbc.gridwidth = 1;
        gbc.weightx = 1.0;
        addGB(topRow, new JButton("C"), 0, 0);
        gbc.weightx = 0.33;
        addGB(topRow, new JButton("%"), 1, 0);
        gbc.weightx = 1.0;
        addGB(topRow, new JButton("+"), 2, 0 );
        gbc.gridwidth = 4;
        addGB(this, topRow, 0, 1);
        gbc.weightx = 1.0;  gbc.gridwidth = 1;
        // make the digits
        for(int j=0; j<3; j++)
            for(int i=0; i<3; i++)
                addGB(this, new JButton("" + ((2-j)*3+i+1) ), i, j+2);
        // -, x, and divide
        addGB(this, new JButton("-"), 3, 2);
        addGB(this, new JButton("x"), 3, 3);
        addGB(this, new JButton("\u00F7"), 3, 4);
        // make the bottom row
        JPanel bottomRow = new JPanel();
        gbc.weightx = 1.0;
        addGB(bottomRow, new JButton("0"), 0, 0);
        gbc.weightx = 0.33;
        addGB(bottomRow, new JButton("."), 1, 0);
        gbc.weightx = 1.0;
        addGB(bottomRow, new JButton("="), 2, 0);
        gbc.gridwidth = 4;
        addGB(this, bottomRow, 0, 5);

      void addGB(Container cont, Component comp, int x, int y) {
        if ((cont.getLayout() instanceof GridBagLayout) == false)
          cont.setLayout(new GridBagLayout());
        gbc.gridx = x; gbc.gridy = y;
        cont.add(comp, gbc);

      public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("C"))
                             + e.getActionCommand());

      public static void main(String[] args) {
        JFrame frame = new JFrame("Calculator");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setSize(200, 250);
        frame.setLocation(200, 200);
        frame.setContentPane(new Calculator());

Once again, we use an addGB() helper method to add components with their constraints to the layout. Before discussing how to build the layout, let’s take a look at addGB(). We said earlier that three layout managers are in our user interface: one for the application panel itself, one for the panel containing the first row of buttons (topRow), and one for the panel containing the bottom row of buttons (bottomRow). We use addGB() for all three layouts; its first argument specifies the container to which to add the component. Thus, when the first argument is this, we’re adding an object to the content pane of the JFrame. When the first argument is topRow, we’re adding a button to the first row of buttons. addGB() first checks the container’s layout manager and sets it to GridBagLayout if it isn’t already set properly. It sets the object’s position by modifying a set of constraints, gbc, and then uses these constraints to add the object to the container.

We use a single set of constraints throughout the example, modifying fields as we see fit. The constraints are initialized in Calculator’s constructor. Before calling addGB(), we set any fields of gbc for which the defaults are inappropriate. Thus, for the answer display, we set the grid width to 4 and add the answer display directly to the application panel (this). The add() method, which is called by addGB(), makes a copy of the constraints, so we’re free to reuse gbc throughout the application.

The first and last rows of buttons motivate the use of multiple GridBagLayout containers, each with its own grid. These buttons appear to straddle grid lines, but you really can’t accomplish this using a single grid. Therefore, topRow has its own layout manager, with three horizontal cells, allowing each button in the row to have a grid width of 1. To control the size of the buttons, we set the weightx variables so that the clear and plus buttons take up more space than the percent button. We then add the topRow as a whole to the application, with a grid width of 4. The bottom row is built similarly.

To build the buttons for the digits 1–9, we use a doubly nested loop. There’s nothing particularly interesting about this loop, except that it’s probably a bit too cute. The minus, multiply, and divide buttons are also simple: we create a button with the appropriate label and use addGB() to place it in the application. It’s worth noting that we used a Unicode constant to request a real division sign rather than wimping out and using a slash.

That’s it for the user interface; what’s left is event handling. Each button generates action events; we need to register listeners for these events. We’ll make the application panel, the Calculator, the listener for all the buttons. To register the Calculator as a listener, we’ll be clever. Whenever a component is added to a container, the container generates a ContainerEvent. We use an anonymous inner class ContainerListener to register listeners for our buttons. This means that the Calculator must register as a ContainerListener for itself and for the two panels, topRow and bottomRow. The componentAdded() method is very simple. It calls getChild() to find out what component caused the event (i.e., what component was added). If that component is a button, it registers the Calculator as an ActionListener for that button.

actionPerformed() is called whenever the user presses any button. It clears the display if the user pressed the C button; otherwise, it appends the button’s action command (in this case, its label) to the display.

Combining layout managers is an extremely useful trick. Granted, this example verges on overkill. You won’t often need to create a composite layout using multiple grid bags. Composite layouts are common, however, with BorderLayout; you’ll frequently use different layout managers for each of a border layout’s regions. For example, the CENTER region might be a ScrollPane, which has its own special-purpose layout manager; the EAST and SOUTH regions might be panels managed by grid layouts or flow layouts, as appropriate.

[43] If you’re curious, this calculator is based on the ELORG-801, encountered in an online “calculator museum”.

The best content for your career. Discover unlimited learning on demand for around $1/day.