Concepts / Introduction to Swing Borders

Introduction to Swing Borders

BorderFactory.createEmptyBorder(top, left, bottom, right) creates an empty border that reserves space around the edges of a component.

  • Programming

Why Components Crowd Their Edges

When you lay out a Swing interface, components often end up crowded against the edges of their containers. A panel full of buttons can have its buttons touching the panel's boundary, and a text label can sit flush against the edge of its own area. The fix is not to rearrange the components themselves. Swing gives you a separate tool for the space around the outside of a component, and one of the most practical of those tools is the empty border.

What do you think happens?

Before reading on: which part of a Swing program would you expect to be responsible for drawing or reserving the space around the outside edge of a container?

  • The layout manager, because it places the components

  • A border object attached to the container

  • The operating system, because it draws the window

Reveal answer
Answer:

A border object attached to the container

The source states that layout managers do not handle the border around the outside of a container. Arranging and spacing components apart is the layout manager's job, but the outer edge is a separate concern that Swing solves with border objects.

What an Empty Border Reserves

Definition

BorderFactory.createEmptyBorder(top, left, bottom, right) creates an empty border that reserves space around the edges of a component.

The word empty is literal. The border does not paint a line, a bevel, or a pattern. It only reserves room. Because nothing is drawn in that reserved room, whatever background color the component has will fill the space. The key idea to hold onto is this: the border adds space, and the component's own background shows through that space.

Component boundsthe full area of thecomponentReserved border spacenothing drawn hereContent areawhere text or childcomponents sitBackground colorshows through the reservedspaceouter edge reservesfillsmoves usable area inward
What contains what, and where does the component's background color appear relative to the reserved border space?

Reading the Four Integer Parameters

The method takes four parameters, always given in the same order: top, left, bottom, right. Each parameter is an integer giving the width of the border along that edge of the component. Because the order is fixed, the first number always controls the top edge, the second the left edge, the third the bottom edge, and the fourth the right edge. Mixing up that order is the most common reason a border looks wrong.

topfirst integer: top edgeleftsecond integer: left edgebottomthird integer: bottom edgerightfourth integer: right edgethenthenthen
Which parameter controls which side of the component, and in what order are the four values passed?
java
Notes on the code
  • BorderFactory is a class whose static methods return border objects
  • 10 reserves space along the top edge
  • 20 reserves space along the left edge
  • 5 reserves space along the bottom edge
  • 0 reserves no space along the right edge
Worked example

Reading one call from left to right

What does BorderFactory.createEmptyBorder(10, 20, 5, 0) reserve around a component?

  1. 1
    Identify the order

    The parameters are always top, left, bottom, right.

  2. 2
    Assign the first value

    10 is the top width, so 10 units of space are reserved along the top edge.

  3. 3
    Assign the second value

    20 is the left width, so 20 units of space are reserved along the left edge.

  4. 4
    Assign the third value

    5 is the bottom width, so 5 units of space are reserved along the bottom edge.

  5. 5
    Assign the fourth value

    0 is the right width, so no space is reserved along the right edge.

Result

The component keeps a wider margin on top and left than on the bottom, and has no reserved margin on the right.

Tracing a Panel Before and After a Border

Follow the state of a JPanel that holds other components. Without a border, the components inside the panel can sit right at the panel's edge. Adding an empty border moves the usable area inward, because the reserved space now sits between the panel's outer boundary and the components placed inside it. The panel's background color is still present across the whole panel, including the reserved space.

java
Output
A light gray panel whose components start 10 units in from each edge, with the gray background visible in the margin.
Notes on the code
  • The panel is created first, with no border yet
  • The background color is set so you can see where it shows through
  • A 10-unit empty border is created and attached in one line

Padding a JLabel's Text From Its Edge

The source gives a second common use: a JLabel. Without an empty border, a label has no space between its text and the edge of the label. The text can touch the label's boundary. Adding an empty border creates that space, so the text no longer touches the edge of the label's area.

Worked example

Separating a label's text from its edge

A JLabel with the text Total shows its text flush against the left edge. How can you add space on that side only?

  1. 1
    Choose the side

    The problem is on the left edge, so the left value must be positive.

  2. 2
    Set the other sides

    Top, bottom, and right can be 0 if you do not need space there.

  3. 3
    Pass the four values in order

    createEmptyBorder(0, 8, 0, 0) reserves 8 units on the left and nothing elsewhere.

  4. 4
    Attach the border

    Call setBorder() on the label with the returned border object.

Result

The text starts 8 units in from the left edge, and the label's background color fills the reserved gap.

Why Swing Represents Borders as Objects

Suppose you have already learned how to leave gaps between the components inside a container. Gaps like these separate components from one another. A different question comes up quickly: how do you draw a visible line around the outside edge of a container itself? The source makes a direct point here. Layout managers do not handle the border around the outside of a container. Arranging components and spacing them apart is the layout manager's job, but drawing a border around the outside is a separate concern, and Swing solves it with a different mechanism.

That mechanism is the border object. In Swing, a border is not a setting you type in as a plain number or a word. Borders are represented by objects that you can create, hold in a variable, and hand to a component. A border is something you build first and then attach. Because the border is an object with its own appearance, it can do more than reserve blank space. It can draw something visible, such as a line.

QuestionLayout managerBorder object
What it handlesArranging components and spacing them apartThe outer edge of a component or container
Typical effectGaps between componentsReserved space or a visible line around the edge
How it is providedUsed through the container's layoutCreated with BorderFactory and attached with setBorder()

Separate responsibilities for spacing inside a container and the outer edge of a component

The reach of this idea is broad. A Border object can be added to any JComponent, not just to containers. A label, a button, or a panel can all receive a border in the same way, because the mechanism belongs to JComponent as a general capability.

Creating and Attaching a Line Border

Because borders are objects, you need a way to obtain one. The class javax.swing.BorderFactory provides that. It contains a large number of static methods, and each one returns a border object. Since the methods are static, you call them on the class itself rather than on an instance you have made. Each call hands back a new border object that you can store and use.

java
Notes on the code
  • createLineBorder is a static method on BorderFactory
  • Color.BLACK specifies the color of the line
  • The result is a border object; nothing appears on screen until it is attached

The source's example is BorderFactory.createLineBorder(Color.BLACK), which returns a one-pixel wide black line. Read the call as a request: ask the factory for a line-style border, and specify the color as black. The call's result is a border object. The call itself does not draw anything on the screen yet. It produces an object that represents a border, and attaching that object to a component is a separate step.

Once you have a border object, you still have to connect it to the component it should surround. A border is attached to a JComponent by calling its setBorder() method with the border object as the argument. The component is the object that receives the call, and the border object is the argument you pass in.

java
Notes on the code
  • The JLabel is the component that will receive the border
  • createLineBorder builds the border object in the same statement
  • setBorder attaches it to the label
BorderFactory callcreateLineBorder(Color.BLACK)Border objectheld in a variablesetBorder() callborder passed as argumentJComponentreceives and keeps theborderreturnspassed toattaches to
What happens step by step from creating the border object to it appearing around the component on screen?

Read the pipeline left to right. The factory call produces a border object, that object is passed to setBorder(), and the component receives it. Creating the border and attaching it are two separate actions, each with its own part of the code. Trace one border from start to finish: start with the request, follow the object it produces, and end with the component that keeps it.

Mistakes With Border Setup

  • Common mistake

    Reversing the order of the four parameters

    What it looks like

    createEmptyBorder(0, 20, 0, 0) expected to add space on the top

    Why it fails

    The order is always top, left, bottom, right, so the second value controls the left edge, not the top.

    Do this instead

    Put the top value first: createEmptyBorder(20, 0, 0, 0) reserves space along the top edge.

  • Common mistake

    Expecting createLineBorder to show a line immediately

    What it looks like

    Calling BorderFactory.createLineBorder(Color.BLACK) and expecting a line to appear with no further code

    Why it fails

    The call only returns a border object. Nothing is attached to a component yet.

    Do this instead

    Pass the returned object to the component's setBorder() method.

  • Common mistake

    Assuming an empty border has a color of its own

    What it looks like

    Expecting a gray margin when the panel background is white

    Why it fails

    Nothing is drawn in the reserved space, so the component's own background shows through.

    Do this instead

    Set the component's background color to control what appears in the margin.

  • Common mistake

    Looking for the outer edge in the layout manager

    What it looks like

    Trying to draw a line around a container by changing only its layout settings

    Why it fails

    Layout managers do not handle the border around the outside of a container.

    Do this instead

    Create a border object and attach it to the container with setBorder().

Practice: Reading the Parameters

EASY

A JPanel receives the call BorderFactory.createEmptyBorder(5, 15, 5, 15). Describe which edges have reserved space and how wide each one is. Then explain what color the reserved space will show if the panel's background is set to Color.BLUE.

Hints
  • The four values are always top, left, bottom, right.
  • Think about what the empty border draws, and what fills space that is not drawn.
MEDIUM

Write the Java statements that create a border with a visible one-pixel black line and attach it to a JLabel named status. Then state which step creates the border object and which step attaches it.

Hints
  • Use BorderFactory.createLineBorder with Color.BLACK.
  • Attaching is done with the component's setBorder() method.

Key Takeaways

  • BorderFactory.createEmptyBorder(top, left, bottom, right) reserves space around the edges of a component without drawing anything in that space.
  • The four integer parameters are always passed in the order top, left, bottom, right, and each gives the width of the border along that edge.
  • Because the reserved space is not painted, the component's own background color fills it.
  • Layout managers do not handle the border around the outside of a container, so Swing represents borders as objects that are created with BorderFactory and attached with setBorder().
  • A border such as BorderFactory.createLineBorder(Color.BLACK) is an object that does not appear on screen until it is attached to a JComponent.