首頁 >Java >java教程 >當我調整 Java 視窗大小時,為什麼我的 JButton 表現異常?

當我調整 Java 視窗大小時,為什麼我的 JButton 表現異常?

Barbara Streisand
Barbara Streisand原創
2024-12-14 17:21:15460瀏覽

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

版面似乎有問題,JButton 在調整視窗大小時顯示意外行為

所描述的問題涉及Java 應用程式圖形使用者介面(GUI) 的意外行為當調整視窗大小時。調整視窗大小會導致某些 JButton 元件的行為發生變化,包括按鈕的文字和顏色。

問題分析

要理解問題,必須檢查程式碼並了解識別視窗大小和 JButton 元件行為之間的任何依賴關係。問題可能在於元件的佈局方式或其屬性的管理方式。

查看程式碼

提供的程式碼使用 ComponentAdapter 來偵測元件大小的變化繪圖區域元件。當尺寸改變時,會觸發以下操作:

  • 計時器重新啟動。
  • 「開始/停止」按鈕上的文字改為「停止」。
  • isTimerRunning 設定為 true。

這些操作無疑是為了確保計時器啟動當調整視窗大小時。但是,該程式碼不處理其他元件(例如 JButton 元件)的大小調整。

意外行為的原因

意外行為可能是由 JButton 組件的佈局方式引起的以及他們的財產是如何管理的。調整視窗大小時,佈局管理器可能會重新排列元件,這可能會影響它們的屬性。例如,按鈕上的文字可能會被截斷或顏色可能會改變。

可能的解決方案

要解決此問題,請考慮以下建議:

  1. 使用可以更好地處理調整大小的佈局管理器:將GridLayout 替換為更適合處理的佈局管理器調整大小,例如GridBagLayout 或SpringLayout。
  2. 使用絕對定位: 您可以使用絕對定位手動指定 JButton 元件的大小和位置,而不是使用佈局管理器。這種方法可確保無論視窗大小如何,元件都會保留其所需的屬性。
  3. 為佈局管理器新增屬性:如果您想使用特定的佈局管理器,可以向其新增屬性來控制調整視窗大小時它的行為。這允許您自訂佈局管理器以滿足您的特定要求。
  4. 使用 SwingWorker: SwingWorker 可用於在單獨的執行緒中執行長時間運行的任務,這有助於防止 GUI在調整大小期間防止凍結。

範例實作

這是一個範例實現,使用 GridBagLayout 來管理佈局並確保 JButton 元件保留其所需的屬性:

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) {

以上是當我調整 Java 視窗大小時,為什麼我的 JButton 表現異常?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn