窗口布局似乎有问题,JButton在调整窗口大小时表现出意外的行为。

15

JRE版本1.7更新3

预期行为

当我运行程序时,一切都按预期进行,一切顺利。当我单击“停止”JButton时,动画停止,并且相同的JButton上的文本更改为“开始”。现在,当我单击“球颜色”JButton时,BALL的颜色会改变,以及BALL颜色 JBUTTON的颜色也会更改为BALL的颜色。如果我按原样运行应用程序而不调整大小,则整个行为都有效。

意外行为

但是,当我通过拉动右侧调整大小我的JFrame时,就会显示出应用程序的意外行为,这意味着如果我按下STOP JButton,然后单击BALL COLOUR按钮,则早先单击的JButton的文本将再次更改为STOP,当它不应该,并且BALL COLOUR JButton的颜色将保持不变或更改为BLUE,当它应该更改为球的颜色。我附加了更多信息的图片。但是,如果您将其调整回原始大小或更接近,则事情将恢复正常。这是为什么?有任何想法或提示将不胜感激。

由于我的应用程序以上面所述的预期行为运行:

Expected Behaviour

这里是意外行为

Unexpected Behaviour

底线:

为什么应用程序在开始时按照预期运行,但当通过拖动其右侧进行调整大小时,则不能按预期运行,但是如果再将其调整为原始大小或更接近,则事情就会恢复正常,它按预期工作?

考虑到情况,我是否做错了什么,还是说这正是我应该使用SwingWorker的情况,或者这是与Layout有关的问题,或者是与Content Pane有关的隐藏问题。请给予一些指导。

这是我使用的代码,我已将其最小化,因为我认为这可以展示我的问题:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

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 int colourCounter;
     Color[] colours = {
                            Color.BLUE.darker(),
                            Color.MAGENTA.darker(),
                            Color.BLACK.darker(),
                            Color.RED.darker(),
                            Color.PINK.darker(),
                            Color.CYAN.darker(),
                            Color.DARK_GRAY.darker(),
                            Color.YELLOW.darker(),
                            Color.GREEN.darker()
                       };

    private Color backgroundColour;
    private Color foregroundColour; 

    private ActionListener timerAction = new ActionListener()
    {
        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;

    private ComponentAdapter componentAdapter = new ComponentAdapter()
    {
        public void componentResized(ComponentEvent ce)
        {
            timer.restart();
            startStopButton.setText("STOP");
            isTimerRunning = true;
        }
    };  

    public BallAnimation()
    {
        x = y = 0;
        positiveX = positiveY = true;
        speedValue = 1;
        colourCounter = 0;
        isTimerRunning = false;
        diameter = 50;
        backgroundColour = Color.WHITE.brighter();
        foregroundColour = colours[colourCounter];
        timer = new Timer(10, timerAction);
    }

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

        drawingArea = new DrawingArea(x, y
                            , backgroundColour, foregroundColour, diameter);
        drawingArea.addComponentListener(componentAdapter);

        frame.add(makeButtonPanel(), BorderLayout.LINE_END);
        frame.add(drawingArea, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);     
    }

    private JPanel makeButtonPanel()
    {
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(0, 1));
        buttonPanel.setBorder(BorderFactory.createLineBorder(
                                    Color.DARK_GRAY, 5, true));

        startStopButton = new JButton("START");
        startStopButton.setBackground(Color.GREEN.darker());
        startStopButton.setForeground(Color.WHITE.brighter());
        startStopButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("START/STOP JButton Clicked!");
                if (!isTimerRunning)
                {
                    startStopButton.setText("STOP");
                    timer.start();
                    isTimerRunning = true;
                    buttonPanel.revalidate();
                    buttonPanel.repaint();
                }
                else if (isTimerRunning)
                {
                    startStopButton.setText("START");
                    timer.stop();
                    isTimerRunning = false;
                    buttonPanel.revalidate();
                    buttonPanel.repaint();
                }
            }
        });
        startStopButton.setBorder(BorderFactory.createLineBorder(
                                    Color.WHITE, 4, true));
        buttonPanel.add(startStopButton);

        colourButton = new JButton("BALL COLOUR");
        colourButton.setBackground(colours[colourCounter]);
        colourButton.setForeground(Color.WHITE);
        colourButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("COLOUR JButton Clicked!");
                //timer.restart();
                colourCounter++;
                if (colourCounter == 9)
                    colourCounter = 0;
                foregroundColour = colours[colourCounter];
                drawingArea.setXYColourValues(x, y, backgroundColour
                                                    , foregroundColour);
                //drawingArea.setForegroundForBall(foregroundColour);
                colourButton.setBackground(foregroundColour);
                colourButton.revalidate();
                colourButton.repaint();
                //timer.start();
            }
        });
        colourButton.setBorder(BorderFactory.createLineBorder(
                                    Color.WHITE, 2, true));
        buttonPanel.add(colourButton);

        exitButton = new JButton("EXIT");
        exitButton.setBackground(Color.RED.darker());
        exitButton.setForeground(Color.WHITE.brighter());
        exitButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("EXIT JButton Clicked!");
                timer.stop();
                System.exit(0);
            }
        });
        exitButton.setBorder(BorderFactory.createLineBorder(
                                    Color.RED.darker().darker(), 4, true));
        buttonPanel.add(exitButton);

        return buttonPanel;
    }

    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)
    {
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                new BallAnimation().createAndDisplayGUI();
            }
        };
        SwingUtilities.invokeLater(runnable);
    }
}

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.darker(), 5, true));
    }

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

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

    public void paintComponent(Graphics g)
    {
        g.setColor(backgroundColor);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(foregroundColor);
        g.fillOval(x, y, ballDiameter, ballDiameter);
    }
}

**最新编辑:**

最新


1
我在这里看不到问题(即使没有最大化1)使用一个1.6 JRE和代码如图所示(删除createLineBorder的第3个参数后!)。你显然正在使用1.7(考虑到第3个参数是在7中引入的)。这可能是正在使用的JRE中的错误吗? - Andrew Thompson
啊哈,我猜可能是个bug,我正在使用1.7更新3,之前我不能在1.7更新1中使用setLayout(new FlowLayout(FlowLayout.LEFT));,你说得对:-),因为如果我最大化窗口,一切都正常,只有当我通过拖动右侧来调整大小时,它才会出现这种奇怪的行为。我可能会再在其他地方测试一下,再次感谢您的帮助 :-) - nIcE cOw
我是指 1)启动应用程序。2)(不要最大化)3)拖动的组合(实际上是“扩展”而不是“拖动”)右侧/颜色更改/停止/开始4)没有可观察到的伪像。 - Andrew Thompson
@AndrewThompson:我切换到JRE版本6,一切都很好,尽管如果我在JRE 1.7上删除每个JButton的整个setBorder(...)语句,即使那样也无法解决问题。但是回到1.6后,问题得到了解决。所以事情已经解决了,但是是什么原因导致的,还是个谜 :-) - nIcE cOw
似乎是边界布局中的“LINE_END”导致了问题,在其他地方,无论您如何扩展窗口,一切都正常,只是在这个位置,出现了问题:( - nIcE cOw
显示剩余3条评论
4个回答

12

你的示例很好,但可能与平台有关。不过我可以提供一些观察:

  • 因为您没有添加或删除组件,所以不需要revalidate()

  • 由于按钮的背景颜色是绑定属性,所以不需要随后调用repaint()

  • 您需要在自定义的DrawingArea中使用repaint(),但您可能希望尝试添加属性更改支持,如此处建议的那样。

  • Color.white无法brighter()Color.black也无法darker()Color.darkGray.darker()Color.black()

  • 下面的变体使用Queue<Color>来简化更改颜色。

屏幕截图

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/** @see https://dev59.com/Z-o6XIcBkEYKwwoYQiS7 */
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<Color>(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;
    private ComponentAdapter componentAdapter = new ComponentAdapter() {

        @Override
        public void componentResized(ComponentEvent ce) {
            timer.restart();
            startStopButton.setText("Stop");
            isTimerRunning = true;
        }
    };

    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);
        frame.setLocationByPlatform(true);

        drawingArea = new DrawingArea(x, y, backgroundColour, foregroundColour, diameter);
        drawingArea.addComponentListener(componentAdapter);

        frame.add(makeButtonPanel(), BorderLayout.LINE_END);
        frame.add(drawingArea, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    private JPanel makeButtonPanel() {
        buttonPanel = new JPanel(new GridLayout(0, 1));
        buttonPanel.setBorder(BorderFactory.createLineBorder(Color.darkGray, 5));

        startStopButton = new JButton("Start");
        startStopButton.setOpaque(true);
        startStopButton.setForeground(Color.white);
        startStopButton.setBackground(Color.green.darker());
        startStopButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                if (!isTimerRunning) {
                    startStopButton.setText("Stop");
                    timer.start();
                    isTimerRunning = true;
                } else if (isTimerRunning) {
                    startStopButton.setText("Start");
                    timer.stop();
                    isTimerRunning = false;
                }
            }
        });
        startStopButton.setBorder(BorderFactory.createLineBorder(Color.gray, 4));
        buttonPanel.add(startStopButton);

        colourButton = new JButton("Change Color");
        colourButton.setOpaque(true);
        colourButton.setForeground(Color.white);
        colourButton.setBackground(clut.peek());
        colourButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //timer.restart();
                clut.add(clut.remove());
                foregroundColour = clut.peek();
                drawingArea.setXYColourValues(x, y, backgroundColour, foregroundColour);
                colourButton.setBackground(foregroundColour);
            }
        });
        colourButton.setBorder(BorderFactory.createLineBorder(Color.gray, 4));
        buttonPanel.add(colourButton);

        exitButton = new JButton("Exit");
        exitButton.setBackground(Color.red);
        exitButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                timer.stop();
                System.exit(0);
            }
        });
        exitButton.setBorder(BorderFactory.createLineBorder(Color.red.darker(), 4));
        buttonPanel.add(exitButton);

        return buttonPanel;
    }

    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) {
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                new BallAnimation().createAndDisplayGUI();
            }
        };
        SwingUtilities.invokeLater(runnable);
    }
}

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) {
        g.setColor(backgroundColor);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(foregroundColor);
        g.fillOval(x, y, ballDiameter, ballDiameter);
    }
}

那些例子像往常一样非常棒 :-) ,实际上我写了那些 revalidate()repaint() 的东西来整理事情,尽管它们不在我的实际程序中。我已经找到了问题的原因,但我真的不知道如何纠正它,问题出现在 Timer 实例处于 RUNNING 状态时。当它停止时,就不会出现问题。我曾尝试在 colourButtonactionPerformed(...) 方法中设置 timer.stop,但没有用。哈哈。天知道现在该怎么办 :-) 再次感谢您提供的精彩链接和友善的帮助 :-) - nIcE cOw
抱歉,我脑海中没有任何想法。我已添加了最近的变化以供参考。 - trashgod
我切换到JRE版本6,一切都很好,但是如果我在JRE 1.7上删除每个JButton的整个setBorder(...)语句,即使那样也无法解决问题。但是回到1.6就可以解决问题了。所以事情已经解决了,但是是如何解决的,仍然是一个谜:)所以看起来这是JDK 1.7更新3中的一个错误:( - nIcE cOw
不是JDK 1.7更新2,而是更新3 :-) - nIcE cOw
奇怪,我看到更新3是最新的,但我的Java控制面板显示我当前使用1.7.0_02版本。抱歉,我不是Windows专家。 :-) - trashgod
显示剩余2条评论

7
似乎BorderLayout.LINE_END有问题,只有当我将buttonPanel放在LINE_END上时,才会出现不良结果。我尝试使用一个JButton而不是三个,作为最新措施来解决问题。现在通过将JButton面板的位置更改为LINE_START或使用JRE版本1.6更新31,已经解决了在此图片中显示的问题:

LINE_END

以下是用于此示例的代码:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

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 int colourCounter;
     Color[] colours = {
                            Color.BLUE.darker(),
                            Color.MAGENTA.darker(),
                            Color.BLACK.darker(),
                            Color.RED.darker(),
                            Color.PINK.darker(),
                            Color.CYAN.darker(),
                            Color.DARK_GRAY.darker(),
                            Color.YELLOW.darker(),
                            Color.GREEN.darker()
                       };

    private Color backgroundColour;
    private Color foregroundColour; 

    private ActionListener timerAction = new ActionListener()
    {
        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;

    private ComponentAdapter componentAdapter = new ComponentAdapter()
    {
        public void componentResized(ComponentEvent ce)
        {
            timer.restart();
        }
    };  

    public BallAnimation()
    {
        x = y = 0;
        positiveX = positiveY = true;
        speedValue = 1;
        colourCounter = 0;
        isTimerRunning = false;
        diameter = 50;
        backgroundColour = Color.WHITE.brighter();
        foregroundColour = colours[colourCounter];
        timer = new Timer(10, timerAction);
    }

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

        drawingArea = new DrawingArea(x, y
                            , backgroundColour, foregroundColour, diameter);
        drawingArea.addComponentListener(componentAdapter);

        frame.add(makeButtonPanel(), BorderLayout.LINE_START);
        frame.add(drawingArea, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);     
    }

    private JPanel makeButtonPanel()
    {
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(0, 1));
        buttonPanel.setBorder(BorderFactory.createLineBorder(
                                    Color.DARK_GRAY, 5, true));

        colourButton = new JButton("BALL COLOUR");
        colourButton.setOpaque(true);
        colourButton.setBackground(colours[colourCounter]);
        colourButton.setForeground(Color.WHITE);
        colourButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("COLOUR JButton Clicked!");
                if (timer.isRunning())
                    timer.stop();
                colourCounter++;
                if (colourCounter == 9)
                    colourCounter = 0;
                foregroundColour = colours[colourCounter];
                drawingArea.setXYColourValues(x, y, backgroundColour
                                                    , foregroundColour);
                colourButton.setBackground(foregroundColour);
                if (!timer.isRunning())
                    timer.start();
            }
        });
        colourButton.setBorder(BorderFactory.createLineBorder(
                                    Color.WHITE, 2, true));
        buttonPanel.add(colourButton);

        return buttonPanel;
    }

    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)
    {
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                new BallAnimation().createAndDisplayGUI();
            }
        };
        SwingUtilities.invokeLater(runnable);
    }
}

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.darker(), 5, true));
    }

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

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

    public void paintComponent(Graphics g)
    {
        g.setColor(backgroundColor);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(foregroundColor);
        g.fillOval(x, y, ballDiameter, ballDiameter);
    }
}

奇怪!BorderLayout.EAST 也会出现这种情况吗(那是 LINE_END 的粗略等价物吗?)? - Andrew Thompson
1
是的,同样的问题,使用BorderLayout.EAST :( - nIcE cOw
到目前为止,我可能已经提交了一个错误报告。我不能说我对我看到的任何1.7实现印象深刻。它们似乎非常有缺陷。 - Andrew Thompson
啊哈,有人也在谈论同样的问题 :-) 水平调整大小,甚至他东边的组件会在调整大小时消失,哈哈 - nIcE cOw
即使OP在接受的答案下方的评论中写道,当添加更多组件时它从未起作用 :-)。 - nIcE cOw

5

那是另一个很好的例子(+1),但我有些困惑,因为绘图部分似乎运行良好。只是 JButton 的文本和颜色在 resize 时显示奇怪的行为! - nIcE cOw
真的,这是我第一次接触图形设计,只是展示,并没有再尝试过。我确定你一直在等待关于碰撞如何工作的真正建议。 - mKorbel
我刚刚意识到,如果我将 JFrame 恢复到其原始大小或更接近原始大小,那么一切都会恢复正常,这可能是布局或其他问题吗 :-) - nIcE cOw

4
我不确定我是否为您的系统找到了解决方案,但是可以调整代码:
colourButton = new JButton( "BALL COLOUR" );
colourButton.setOpaque( true );
colourButton.setBackground( colours[ colourCounter ] );
colourButton.setForeground( Color.WHITE );

在我的系统上(OS X with Java 1.7)可以运行。请注意setOpaque调用,这是必需的,以便setBackground调用有任何效果,正如该方法的javadoc所述:

设置此组件的背景颜色。仅在组件不透明时使用背景颜色

在没有setOpaque调用的情况下,在OS X上,您的代码甚至在调整大小之前都无法工作。


很抱歉,但是这个问题又出现了。当你通过拖动右侧来调整JFrame的大小时,colourButton的颜色仍然保持不变或者显示异常行为。虽然如果我最大化窗口,那么它就可以正常工作,或者我将窗口恢复到原始大小或接近原始大小。但是当我重新调整窗口大小时,又会出现相同的问题 :( 感谢您的努力和帮助 :-) - nIcE cOw
尝试一下,当程序启动时,拖动 JFrame 的右侧以更改其宽度,现在单击 colourButton,看看它的颜色永远不会改变 :-( - nIcE cOw
不,如果我使用setOpaque调用,它总是在我的电脑上工作。没有这个调用,无论是否调整大小,它都不起作用。 - Robin
@Robin:使用setOpaque()设置Aqua背景颜色的想法不错。有时我也会采用这种笨拙的替代方法。Gagandeep Bali:和Robin一样,我也没有发现任何异常。 - trashgod
@Robin:我切换到JRE 6版本后,一切都很顺利。即使在JRE 1.7上删除了每个JButton的整个setBorder(...)语句,也无法解决问题。但是回到1.6版本后,问题就解决了。所以问题已经解决了,但是具体是如何解决的仍然是个谜。 - nIcE cOw
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接