Java Swing GUI Development Fundamentals

Swing applications are built using a hierarchy of containers and components. The top-level window is typically represented by JFrame, while intermediate containers like JPanel are used to group components. Atomic controls such as JButton and JLabel are placed within these containers.

Below is an example of setting up a basic window structure:

// Initialize the main application window
JFrame mainWindow = new JFrame("Application Title");
JPanel contentPanel = new JPanel();
mainWindow.setContentPane(contentPanel);

// Add a button component
JButton actionButton = new JButton("Execute");
contentPanel.add(actionButton);

// Add a label for static text
JLabel statusLabel = new JLabel("Ready");
contentPanel.add(statusLabel);

// Attach an action listener using a lambda expression
actionButton.addActionListener(e -> System.out.println("Action triggered"));

// Attach a listener using an anonymous inner class
actionButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Command: " + e.getActionCommand());
    }
});

Extending JFrame

To promote code reuse and encapsulation, it is common practice to create a subclass of JFrame. This allows specific window configurations to be defined within the class constructor.

public class ApplicationWindow extends JFrame {

    public ApplicationWindow(String title, JPanel rootPanel) {
        super(title);
        // Ensure the application exits when the window is closed
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        this.setContentPane(rootPanel);
        this.setSize(800, 500);
    }
}

// Usage
JPanel mainPanel = new JPanel();
ApplicationWindow window = new ApplicationWindow("Demo", mainPanel);
window.setVisible(true);

Text Inputs and Selection Controls

Swing provides various controls for data entry and selection:

  • JTextField: A single-line text input field.
  • JCheckBox: A binary selection component (selected/unselected).
  • JComboBox: A drop-down list that allows the user to select one item from a list.
// Checkbox usage
JCheckBox agreeBox = new JCheckBox("I agree to terms");
agreeBox.setSelected(true); // Set initial state
if (agreeBox.isSelected()) { /* Logic here */ }

// Generic JComboBox usage
JComboBox<String> colorSelector = new JComboBox<>();
colorSelector.addItem("Red");
colorSelector.addItem("Blue");
colorSelector.addItem("Green");

String selected = (String) colorSelector.getSelectedItem();

Layout Management

Layout managers determine the position and size of components within a container. By default, JPanel uses FlowLayout, which arranges components left-to-right.

BorderLayout

BorderLayout divides the container into five regions: NORTH, SOUTH, EAST, WEST, and CENTER.

contentPanel.setLayout(new BorderLayout());
contentPanel.add(new JLabel("North"), BorderLayout.NORTH);
contentPanel.add(new JLabel("South"), BorderLayout.SOUTH);

Custom Layout Managers

For complex interfaces, you can implement LayoutManager2. The layoutContainer method is responsible for calculating the bounds (x, y, width, height) for every child component.

public class SimpleGridLayout implements LayoutManager2 {
    @Override
    public void layoutContainer(Container parent) {
        int w = parent.getWidth();
        int h = parent.getHeight();
        
        // Example logic: grid layout calculation
        for (Component comp : parent.getComponents()) {
            comp.setBounds(0, 0, w, h);
        }
    }
    // Other interface implementations...
}

Color Models

Colors in Swing are represented by the Color class, typically using the RGB model.

// Solid RGB color
Color redColor = new Color(255, 0, 0);

// RGBA color with transparency (Alpha 0-255)
Color translucentBlue = new Color(0, 0, 255, 128);

Custom Rendering

To create custom visual components, extend JPanel and override the paintComponent method. This method provides a Graphics object (the "canvas") for drawing shapes and text.

public class CustomPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // Crucial for clearing background
        
        int w = getWidth();
        int h = getHeight();
        
        // Draw a background rectangle
        g.setColor(Color.YELLOW);
        g.fillRect(0, 0, w, h);
        
        // Draw an arc (pie slice)
        g.setColor(Color.CYAN);
        g.fillArc(50, 50, 100, 100, 0, 90);
    }
}

Geometric Primitives

The Graphics class supports various drawing operations:

  • fillRect(x, y, w, h): Draws a filled rectangle.
  • drawOval(x, y, w, h): Draws the outline of an ellipse.
  • fillArc(x, y, w, h, startAngle, arcAngle): Draws a filled sector.
  • drawLine(x1, y1, x2, y2): Draws a straight line.

Image Handling

Images are loaded using javax.imageio.ImageIO. To display an image while maintaining its aspect ratio, calculations are required to fit the image within the component bounds.

public class ImageView extends JPanel {
    private BufferedImage sourceImage;

    public void setImage(File imgFile) throws IOException {
        sourceImage = ImageIO.read(imgFile);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (sourceImage != null) {
            int panelW = getWidth();
            int panelH = getHeight();
            int imgW = sourceImage.getWidth();
            int imgH = sourceImage.getHeight();

            // Calculate aspect ratio
            double scale = Math.min((double) panelW / imgW, (double) panelH / imgH);
            int drawW = (int) (imgW * scale);
            int drawH = (int) (imgH * scale);

            // Center the image
            int x = (panelW - drawW) / 2;
            int y = (panelH - drawH) / 2;
            
            g.drawImage(sourceImage, x, y, drawW, drawH, null);
        }
    }
}

Mouse Event Handling

Interactions are handled via listeners. MouseAdapter is a convenience class that implements all listener interfaces with empty methods, allowing you to override only the events you need.

public class InteractivePanel extends JPanel {
    public InteractivePanel() {
        MyMouseListener handler = new MyMouseListener();
        addMouseListener(handler);
        addMouseMotionListener(handler);
    }

    private class MyMouseListener extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            System.out.println("Pressed at: " + e.getPoint());
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            System.out.println("Dragging to: " + e.getPoint());
        }
    }
}

Freheand Drawing Example

To implement a drawing tool, record coordinates in a list during mouseDragged and render lines connecting them in paintComponent.

public class SketchPad extends JPanel {
    private List<Point> points = new ArrayList<>();

    public SketchPad() {
        MouseAdapter dragHandler = new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                points.add(e.getPoint());
                repaint();
            }
            
            @Override
            public void mousePressed(MouseEvent e) {
                points.clear();
                points.add(e.getPoint());
            }
        };
        addMouseListener(dragHandler);
        addMouseMotionListener(dragHandler);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.RED);
        for (int i = 1; i < points.size(); i++) {
            Point p1 = points.get(i - 1);
            Point p2 = points.get(i);
            g.drawLine(p1.x, p1.y, p2.x, p2.y);
        }
    }
}

Styling with Borders

Visual separation is achieved using borders. BorderFactory provides static methods to create standard borders.

LineBorder lineBorder = new LineBorder(Color.BLUE, 2);
component.setBorder(lineBorder);

// Compound borders (nesting borders)
Border outer = BorderFactory.createEmptyBorder(5, 5, 5, 5);
Border inner = BorderFactory.createLineBorder(Color.BLACK);
Border combined = BorderFactory.createCompoundBorder(outer, inner);
component.setBorder(combined);

Dialogs and File Selection

JOptionPane offers standard pre-built dialogs for alerts, confirmations, and inputs. For file system interactions, JFileChooser is used.

// Simple message dialog
JOptionPane.showMessageDialog(this, "Operation Complete");

// File Open Dialog
JFileChooser fileChooser = new JFileChooser();
int userSelection = fileChooser.showOpenDialog(this);

if (userSelection == JFileChooser.APPROVE_OPTION) {
    File selectedFile = fileChooser.getSelectedFile();
    System.out.println("Selected: " + selectedFile.getAbsolutePath());
}

Context Menus

JPopupMenu is used for right-click context menus. It is typically triggered on a mouse press event.

JPopupMenu contextMenu = new JPopupMenu();
JMenuItem saveItem = new JMenuItem("Save");
saveItem.addActionListener(e -> performSave());
contextMenu.add(saveItem);

// In the mouse listener
component.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        if (e.isPopupTrigger()) {
            contextMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }
});

Tags: java swing gui Layout Manager Graphics2D

Posted on Wed, 13 May 2026 07:36:08 +0000 by DannyM