Home > Java > javaTutorial > Why are my JButtons behaving unexpectedly when I resize my Java window?

Why are my JButtons behaving unexpectedly when I resize my Java window?

Barbara Streisand
Release: 2024-12-14 17:21:15
Original
453 people have browsed it

Why are my JButtons behaving unexpectedly when I resize my Java window?

Something seems wrong with the layout, JButton showing unexpected behaviour at resize of the window

The issue described involves unexpected behaviour of a Java application's graphical user interface (GUI) when the window is resized. Resize the window causes the behaviour of certain JButton components to change, including the text and colour of the button.

Analysis of the Problem

To understand the problem, it's essential to examine the code and identify any dependencies between the window's size and the behaviour of the JButton components. The problem may lie in the way the components are laid out or in the way their properties are managed.

Reviewing the Code

The provided code uses a ComponentAdapter to detect changes in the size of the DrawingArea component. When the size changes, the following actions are triggered:

  • The timer is restarted.
  • The text on the "Start/Stop" button is changed to "Stop".
  • isTimerRunning is set to true.

These actions are undoubtedly intended to ensure that the timer starts when the window is resized. However, the code does not handle the resizing of other components, such as the JButton components.

Cause of Unexpected Behaviour

The unexpected behaviour is likely caused by the way the JButton components are laid out and how their properties are managed. When the window is resized, the layout manager may be rearranging the components, which could affect their properties. For example, the text on the buttons may be truncated or the colours may change.

Possible Solutions

To address the issue, consider the following suggestions:

  1. Use a layout manager that handles resizing better: Replace the GridLayout with a layout manager that is more suited to handling resizing, such as GridBagLayout or SpringLayout.
  2. Use absolute positioning: Instead of using a layout manager, you could manually specify the size and position of the JButton components using absolute positioning. This approach ensures that the components retain their desired properties regardless of window size.
  3. Add properties to the layout manager: If you want to use a specific layout manager, you can add properties to it to control how it behaves when the window is resized. This allows you to customize the layout manager to meet your specific requirements.
  4. Use SwingWorker: SwingWorker can be used to perform long-running tasks in a separate thread, which can help prevent the GUI from freezing during resizing.

Example Implementation

Here's an example implementation that uses a GridBagLayout to manage the layout and ensures that the JButton components retain their desired properties:

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

public class BallAnimation {

    private int x;
    private int y;
    private boolean positiveX;
    private boolean positiveY;
    private boolean isTimerRunning;
    private int speedValue;
    private int diameter;
    private DrawingArea drawingArea;
    private Timer timer;
    private Queue<Color> clut = new LinkedList<>(Arrays.asList(
        Color.BLUE.darker(),
        Color.MAGENTA.darker(),
        Color.BLACK,
        Color.RED.darker(),
        Color.PINK,
        Color.CYAN.darker(),
        Color.DARK_GRAY,
        Color.YELLOW.darker(),
        Color.GREEN.darker()));
    private Color backgroundColour;
    private Color foregroundColour;

    private ActionListener timerAction = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            x = getX();
            y = getY();
            drawingArea.setXYColourValues(x, y, backgroundColour, foregroundColour);
        }
    };

    private JPanel buttonPanel;
    private JButton startStopButton;
    private JButton speedIncButton;
    private JButton speedDecButton;
    private JButton resetButton;
    private JButton colourButton;
    private JButton exitButton;

    public BallAnimation() {
        x = y = 0;
        positiveX = positiveY = true;
        speedValue = 1;
        isTimerRunning = false;
        diameter = 50;
        backgroundColour = Color.white;
        foregroundColour = clut.peek();
        timer = new Timer(10, timerAction);
    }

    private void createAndDisplayGUI() {
        JFrame frame = new JFrame("Ball Animation");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        drawingArea = new DrawingArea(x, y, backgroundColour, foregroundColour, diameter);
        drawingArea.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent ce) {
                timer.restart();
                startStopButton.setText("Stop");
                isTimerRunning = true;
            }
        });

        JPanel contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(makeButtonPanel(), BorderLayout.EAST);
        contentPane.add(drawingArea, BorderLayout.CENTER);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JPanel makeButtonPanel() {
        buttonPanel = new JPanel(new GridBagLayout());
        buttonPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;

        startStopButton = makeButton("Start", gbc, 0, 0);
        colourButton = makeButton("Change Color", gbc, 0, 1);
        exitButton = makeButton("Exit", gbc, 0, 2);

        return buttonPanel;
    }

    private JButton makeButton(String text, GridBagConstraints gbc, int row, int column) {
        JButton button = new JButton(text);
        button.setOpaque(true);
        button.setForeground(Color.WHITE);
        button.setBackground(Color.GREEN.DARKER);
        button.setBorder(BorderFactory.createLineBorder(Color.GRAY, 4));
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (button == startStopButton) {
                    if (!isTimerRunning) {
                        startStopButton.setText("Stop");
                        timer.start();
                        isTimerRunning = true;
                    } else {
                        startStopButton.setText("Start");
                        timer.stop();
                        isTimerRunning = false;
                    }
                } else if (button == colourButton) {
                    clut.add(clut.remove());
                    foregroundColour = clut.peek();
                    drawingArea.setXYColourValues(x, y, backgroundColour, foregroundColour);
                    colourButton.setBackground(foregroundColour);
                } else if (button == exitButton) {
                    timer.stop();
                    System.exit(0);
                }
            }
        });
        gbc.gridx = column;
        gbc.gridy = row;
        buttonPanel.add(button, gbc);
        return button;
    }

    private int getX() {
        if (x < 0) {
            positiveX = true;
        } else if (x >= drawingArea.getWidth() - diameter) {
            positiveX = false;
        }
        return calculateX();
    }

    private int calculateX() {
        if (positiveX) {
            return (x += speedValue);
        } else {
            return (x -= speedValue);
        }
    }

    private int getY() {
        if (y < 0) {
            positiveY = true;
        } else if (y >= drawingArea.getHeight() - diameter) {
            positiveY = false;
        }
        return calculateY();
    }

    private int calculateY() {
        if (positiveY) {
            return (y += speedValue);
        } else {
            return (y -= speedValue);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BallAnimation().createAndDisplayGUI());
    }
}

class DrawingArea extends JComponent {

    private int x;
    private int y;
    private int ballDiameter;
    private Color backgroundColor;
    private Color foregroundColor;

    public DrawingArea(int x, int y, Color bColor, Color fColor, int dia) {
        this.x = x;
        this.y = y;
        ballDiameter = dia;
        backgroundColor = bColor;
        foregroundColor = fColor;
        setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5));
    }

    public void setXYColourValues(int x, int y, Color bColor, Color fColor) {
        this.x = x;
        this.y = y;
        backgroundColor = bColor;
        foregroundColor = fColor;
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500, 400);
    }

    @Override
    public void paintComponent(Graphics g) {
Copy after login

The above is the detailed content of Why are my JButtons behaving unexpectedly when I resize my Java window?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template