Creating Buttons in Java Swing
A BufferedImage is an in-memory canvas with a fixed width, height and type, and Graphics2D is the tool that paints onto it.
Predicting a Button Icon Before the Trace
This article starts with a working Java Swing example rather than a list of rules. The example comes from a calculator style interface in which a Clear the Display button carries a small X icon next to its text label. Your job is to watch what each step produces, because noticing which line causes each visible change is the skill you will use when a button does not look the way you expected. You do not need to understand every call yet.
What do you think happens?
Before reading on, predict the size of the square canvas on which the X icon is drawn. The X is two thick diagonal lines on a light gray background. What width and height do you expect the canvas to have?
Reveal answer
The canvas is 24 by 24 pixels.
The source describes the icon as drawn on a square canvas of 24 by 24 pixels. The coordinates used in the drawing calls must fall inside that fixed size, so every line the artist draws has to start and stop within those 24 by 24 positions.
The Canvas and the Painter
A BufferedImage is an in-memory canvas with a fixed width, height and type. Graphics2D is the tool that paints onto that canvas.
The two classes do separate jobs. The BufferedImage holds the picture and never changes its size after it is created. The Graphics2D object is the painter: you ask it to fill rectangles, set a color, choose a line thickness, and draw lines, and each call changes the pixels of the canvas. Because the canvas is in memory, nothing appears on the screen until the image is later handed to a component.
Every drawing call uses pixel coordinates. The canvas has a fixed number of columns and rows, and each position is named by an x value (the column) and a y value (the row). In Java's standard drawing system the origin (0, 0) is the top-left pixel, x grows to the right, and y grows downward. The last usable position on a 24 by 24 canvas is (23, 23), because counting starts at zero.
Tracing the X Icon Build
The source trace follows the same sequence every time: first an image is created and painted, then that image is handed to a button, and finally the text placement is adjusted. The code below is an illustrative reconstruction that follows those steps. It is not the source's exact listing, so treat the specific coordinates as examples of the technique rather than as the original values.
- The canvas is created with the fixed size 24 by 24.
- Graphics2D is the painter attached to that canvas.
- The background is filled first, so later lines sit on top of it.
- The stroke width controls how thick the diagonal lines look.
- Two diagonal lines together form the X.
- The image is wrapped in an ImageIcon and passed to the
JButtonconstructor with the text Clear.
Following the build one step at a time
Trace how the X icon moves from a blank canvas to a button with a label.
- 1Create the canvas
The BufferedImage is created at 24 by 24 pixels. It is blank until something is painted on it.
- 2Paint the background
Graphics2D fills the whole canvas with light gray, so every pixel now has a color.
- 3Set the pen
The color is set to black and the stroke is set to a thick width, which affects every line drawn afterwards.
- 4Draw the X
Two diagonal lines are drawn using coordinates that must lie inside the 24 by 24 canvas.
- 5Wrap the image
ImageIcon takes the finished image and makes it usable as an icon.
- 6Build the button
The
JButtonconstructor receives the text and the icon together, so both appear on the button.
A button showing a small gray square with a black X and the word Clear next to it.
Wrapping the Icon and Placing the Text
An ImageIcon wraps the finished image so that a JButton can accept it as an icon alongside its text. The wrapping step does not repaint anything. It simply gives the button an icon object to display, which is why the drawing must be complete before the wrapping happens.
Once the icon and label both exist, the relative layout is controlled by two setters: setHorizontalTextPosition and setVerticalTextPosition. These change where the text sits relative to the icon. They do not change the text itself, so the words Clear stay the same no matter what position values you choose.
- The horizontal setter moves the text to the left of the icon in this example.
- The vertical setter keeps the text centered against the icon's height.
- The label string Clear is untouched by either call.
Finding the Line Where the Button Goes Wrong
When an icon looks wrong, trace the problem in order: canvas size, drawing coordinates, stroke, then the wrapping and constructor. Working through these in sequence stops you from changing the wrong line. A canvas that is too small will clip the drawing no matter how carefully the coordinates were chosen, so check the size first.
Common mistake Changing the label text to fix an icon's position
What it looks likeEditing the string Clear to move it beside the icon
Why it failsThe text placement is controlled by the position setters, and the label string is separate from where it is drawn.
Do this insteadAdjust setHorizontalTextPosition or setVerticalTextPosition instead of editing the text.
Common mistake Drawing with coordinates outside the canvas
What it looks likeCalling drawLine with an x value of 30 on a 24 pixel wide canvas
Why it failsThe canvas has a fixed width and height, and pixels past its edge do not exist on the image.
Do this insteadKeep every coordinate between 0 and the canvas size minus one.
Common mistake Assuming the stroke is only cosmetic
What it looks likeLeaving the default thin line when the design needs a thick X
Why it failsThe stroke decides how thick each line is, so a thin stroke can make the X look faint or broken.
Do this insteadSet the stroke before drawing the lines and check its width against the intended design.
Common mistake Wrapping the image after the button is built, so the icon is missing from the button
Tracing a Mismatched Icon
Suppose a learner expected a black X inside a light gray square, but the button shows a thin, faint cross with its text placed on the wrong side. Using the trace order from the source, work through the sequence of steps and identify the first place where the output stops matching the intention.
Using the build sequence from this article, explain which line you would check first if the X looks faint, and which line you would check if the text appears on the wrong side of the icon. Name the method involved in each case.
Hints
- Faintness points toward the drawing steps, so think about the stroke.
- Text side points toward the position setters, not the label string.
- Start from the top of the trace order and move down only if the earlier step looks correct.
Recap of the Build Sequence
A button with an icon is built in a fixed order: a BufferedImage provides the canvas, Graphics2D paints it, ImageIcon wraps the finished picture, and the JButton constructor receives both the label and the icon. The text position setters then control the layout without touching the text.
Key Takeaways
- A BufferedImage is an in-memory canvas with a fixed width, height and type, and Graphics2D is the tool that paints onto it.
- An ImageIcon wraps the finished image so that a
JButtoncan accept it as an icon alongside its text. setHorizontalTextPositionandsetVerticalTextPositionchange where the text sits relative to the icon without changing the text itself.- When an icon looks wrong, trace the problem in order: canvas size, drawing coordinates, stroke, then the wrapping and constructor.