15

JRE Version 1.7 Update 3

EXPECTED BEHAVIOUR

As I run the program, it works as expected, everything works smoothly. As when I click on STOP JButton the animation stops and the text on the same JButton changes to START. Now when i click on BALL COLOUR JButton, the colour of the BALL changes, as well as the colour of the BALL COLOUR JBUTTON, also changes, to that of the BALL. This whole behaviour works if I run my application as is without resizing.

UNEXPECTED BEHAVIOUR

But when i RESIZE my JFrame, by pulling the Right Side, that's when unexpected behaviour of my Application is shown, in the sense that if I press STOP JButton and then click on BALL COLOUR button, the text on the JButton clicked earlier whose text changed to START will change to STOP again when it should not be, as well as the colour of the BALL COLOUR JButton will remain unchanged or will turn to BLUE, when it should be changed to the colour of the ball. I am attaching the pics for more info. But if you will try to resize it back to it's original size or closer to that, then things will come back to normal. Why is this happening ? Any idea or clue will be much appreciated.

As My Application Runs with EXPECTED BEHAVIOUR as described above :

Expected Behaviour

And here the UNEXPECTED BEHAVIOUR

Unexpected Behaviour

BOTTOM-LINE :

Why the Application runs as usual as it should be, at the BEGINNING , but not when RESIZED by dragging it's RIGHT SIDE, but again if you bring it to it's original size or closer to it, things come back to normal, it works as expected ?

So considering the scenario, am I doing something wrong, in the program. Or is this exactly the situation, where I should be using the SwingWorker, Or Is this an issue with the Layout, or something hidden related to Content Pane. Please do put some light :-)

here is the code I am using, I had brought it down to the minimum, as I think to demonstrate my problem :

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);
    }
}

**LATEST EDIT : **

LATEST

nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • I just realized, if you will maximize the `JFrame` atleast once, then it seems everything works as expected :( – nIcE cOw Mar 24 '12 at 13:59
  • 1
    I am not seeing the problem here (I.E. without maximizing 1st) using a 1.6 JRE with that code as shown (after removing the 3rd arg to `createLineBorder`!). You are apparently using 1.7 (given the 3rd arg was introduced in 7). Could this be a bug in the JRE being used? – Andrew Thompson Mar 24 '12 at 18:01
  • Ahha, I guess might be it's a bug, I am using 1.7 update 3, previously I cann't use `setLayout(new FlowLayout(FlowLayout.LEFT));` with 1.7 update 1, you might be right :-) , since if I maximize then things are okay, just when i resize it by dragging the Right Side, only then it gives me this wicked behaviour. I might test it somewhere else again, Thankyou again for the help :-) – nIcE cOw Mar 24 '12 at 18:40
  • I recommend 1) Make a version that dumps the JRE version 2) Get test results to confirm a pattern. 3) Check the bug database for duplicates. 4) Lodge a new one, if none found. (Of course, you might jump to step 3 & and come back to 1 & 2.) – Andrew Thompson Mar 24 '12 at 18:46
  • Just if I maximize the whole window once, then no problem arises :-) , only when i resize it by dragging the Right Side, things get messy :( – nIcE cOw Mar 24 '12 at 18:49
  • I did mean 1) Start app. 2) (**no** maximize) 3) Combinations of drag (actually 'expand' rather than 'drag') right/color change/stop/start 4) No observable artifacts. – Andrew Thompson Mar 24 '12 at 19:01
  • @AndrewThompson : I shifted to JRE version 6 and everything works nice, on this, though If I remove the whole `setBorder(...)` statements for each `JButton` on JRE 1.7, even that couldn't solve the thingy. But coming back to 1.6 sorted things out. So things are sorted out, but how and what made it, is still a mystery :-) – nIcE cOw Mar 25 '12 at 05:16
  • Seems like it's the `LINE_END` of BorderLayout that is causing the problem, everywhere else, no matter how you expand the window, everything works fine, just at this location, something is wrong :( – nIcE cOw Mar 25 '12 at 08:56

4 Answers4

12

The problem with your very nice example may be platform dependent, but I can offer a few observations:

  • You're not adding or removing components, so you don't need revalidate().

  • Because the background color is a bound property of the buttons, you don't need the subsequent calls to repaint().

  • You do need repaint() in your custom DrawingArea, but you may want to experiment with adding property change support, as suggested here.

  • Color.white can't be brighter() and Color.black can't be darker(); Color.darkGray.darker() is Color.black().

  • The variation below uses a Queue<Color> to simplify changing colors.

screen capture

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://stackoverflow.com/q/9849950/230513 */
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);
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Those examples were wonderful again, as usual :-) , Actually I wrote those `revalidate()` and `repaint()` thingies to sort things out, though they are not in my actual program. I had found the reason though, as to what is causing the issue, but I really don't know how to rectify that, the problem comes when the instance of `Timer` is in `RUNNING` state. When it is stop, then no issue arises. I had tried setting `timer.stop` inside the `colourButton`s `actionPerformed(...)` method, but to no avail. LOL. God knows what to do now :-) +1 again for the wonderful link and the kind help :-) – nIcE cOw Mar 24 '12 at 16:09
  • Dunno if it's the actual reason since, if no resize is done, then things do work as expected. Might be it's a platform dependent thingy :-) Will test it with others to know how it performs on other machines :-) – nIcE cOw Mar 24 '12 at 16:19
  • Sorry, nothing comes to mind. I've added a recent variation for reference. – trashgod Mar 24 '12 at 19:17
  • I shifted to JRE version 6 and everything works nice, on this, though If I remove the whole `setBorder(...)` statements for each `JButton` on JRE 1.7, even that couldn't solve the thingy. But coming back to 1.6 sorted things out. So things are sorted out, but how and what made it, is still a mystery :-) So it seems like it's a bug in JDK 1.7 update 3 :( – nIcE cOw Mar 25 '12 at 05:17
  • Interesting; using 1.7.0_02 on Windows 7, I could not reproduce the anomaly. If it's still on your machine, you may be able to put it in the `%path%`. – trashgod Mar 25 '12 at 05:47
  • Nah JDK 1.7 Update 3, not 2 :-) – nIcE cOw Mar 25 '12 at 07:09
  • Odd, I can see that update 3 is current, but my Java control panel says I'm current with 1.7.0_02. Sorry, I'm not the Windows guy. :-) – trashgod Mar 25 '12 at 07:18
7

Seems like there is something wrong with BorderLayout.LINE_END thingy, only when I place the buttonPanel on LINE_END, I am getting undesirable results. I had tried to use only one JButton, instead of three as the latest measure, to sort out thingies. Now the problem that use to come as shown in this pic :

LINE_END

has been sorted out by changing the position of the JButton Panel to LINE_START or using JRE version 1.6 update 31, in the pic as below :

LINE_START

Here is the code used for this example :

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);
    }
}
nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • Bizarre! Does it also occur with `BorderLayout.EAST` (is that the crude equivalent of `LINE_END`?)? – Andrew Thompson Mar 25 '12 at 09:10
  • 1
    Yeah same problem , with `BorderLayout.EAST` :( – nIcE cOw Mar 25 '12 at 09:21
  • I probably would have raised a bug report by now. Can't say I'm impressed with any of the 1.7 implementations I've seen thus far. They seem very buggy. – Andrew Thompson Mar 25 '12 at 09:25
  • Ahha, someone else is talking about the Same Problem :-) [HORIZONTAL RESIZE](http://stackoverflow.com/questions/8081559/is-this-a-swing-java-7-rendering-bug), even his component at EAST goes missing on resize, LOL – nIcE cOw Mar 25 '12 at 10:00
  • Even OP had written in his/her comment, below the accepted answer, that it never worked :-), when adding more components. – nIcE cOw Mar 25 '12 at 10:03
5

maybe will help you with two parts of, I think that Graphics/2D is designated to use Swing Timer exclusively,

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • That is another wonderful example (+1 for that), but I am confused, where exactly the problem is since the drawing part it seems like works fine. Just the `JButton`'s text and colour shows weird behaviour , at `resize`!!! – nIcE cOw Mar 24 '12 at 07:59
  • true is that this one was my first touch of Graphics, only exibitions, not tried that again, sure you have waiting for real suggestion how the Colision works – mKorbel Mar 24 '12 at 09:02
  • I just realized, if I bring the `JFrame` back to it's original size or closer to that, then again things come back to normal, Can this be a problem with the Layout or something :-) – nIcE cOw Mar 24 '12 at 11:04
4

I am unsure whether I found a solution for your system, but adjusting the code to

colourButton = new JButton( "BALL COLOUR" );
colourButton.setOpaque( true );
colourButton.setBackground( colours[ colourCounter ] );
colourButton.setForeground( Color.WHITE );

works on my system (OS X with Java 1.7). Note the setOpaque call, which is needed so that the setBackground call has any effect as stated in the javadoc of that method:

Sets the background color of this component. The background color is used only if the component is opaque

On OS X, without that setOpaque call your code does not even work before a resize

Robin
  • 36,233
  • 5
  • 47
  • 99
  • Nah, so Sorry for this, but this thing, again, gives the same result, as you resize the `JFrame` by dragging the right side, the colour of the `colourButton` remains same or shows some abnormal behaviour. Though If I maximize the window, then it works fine, or I bring the window to it's original size or closer to that. But when I resize the window, then again same behaviour :( +1 for the effort though. Thankyou for your kind help on this :-) – nIcE cOw Mar 24 '12 at 13:28
  • Try this, as the program starts, drag the Right Side of the `JFrame` to change it's width, now click on `colourButton` and see it's colour never changes :-( – nIcE cOw Mar 24 '12 at 13:35
  • Though if you won't resize it or just change it slightly so that the ball can move, then everything works fine, as usual, just when I try to resize it a bit further, things go wrong, :( that thingy is bothering me. Something strange is at work here :( , bad news for me I guess. – nIcE cOw Mar 24 '12 at 13:43
  • No, it works always on my PC if I use the `setOpaque` call. Without this call, it never works, with or without resizing – Robin Mar 24 '12 at 14:25
  • @Robin: +1 idea using `setOpaque()` for background color on Aqua. I've sometimes resorted to this clumsier [alternative](http://stackoverflow.com/a/3420431/230513). Gagandeep Bali: Like Robin, I see no anomaly. – trashgod Mar 24 '12 at 14:41
  • See this my latest added image in my question, I had added `setOpaque()` to all, but still the colour of the `JButton` remains `BLUE`. DO check the path on the file and command prompt as well. Moreover, it's not about only colour, even the TEXT of the `startStopButton` changes on the click of the `colourButton` at resize :( – nIcE cOw Mar 24 '12 at 14:51
  • @Robin : I shifted to JRE version 6 and everything works nice, on this, though If I remove the whole `setBorder(...)` statements for each `JButton` on JRE 1.7, even that couldn't solve the thingy. But coming back to 1.6 sorted things out. So things are sorted out, but how and what made it, is still a mystery :-) – nIcE cOw Mar 25 '12 at 05:17