1

I've started working on a project for my Java class - LAN gomoku/five in a row. The game board is represented by a 2-dimensional array filled with buttons (JButton). With the event handler (class clickHandler) I want to draw an oval on the button that I click (the parameter of a clickHandler object). My following code hasn't worked though (I don't know how to get rid of the null-value of variable g)... I'd appreciate any piece of advice. Thank You a lot.

    class clickHandler implements ActionListener {

        JButton button;
        Dimension size;
        Graphics g;

        public clickHandler(JButton button) {
            this.button = button;
            this.size = this.button.getPreferredSize();
        }

        @Override
        public void actionPerformed(ActionEvent ae) {
                this.g.setColor(Color.BLUE);
                this.g.fillOval(this.button.getHorizontalAlignment(), this.button.getVerticalAlignment(), this.size.width, this.size.height);

                this.button.paint(this.g);
                this.button.setEnabled(false);
        }
    }

(In a class that creates the GUI - the game board full of buttons - I assign each button a new Action Listener - an instance of clickHandler) this way:

    gButton.addActionListener(new clickHandler(gButton));
Himanshu
  • 31,810
  • 31
  • 111
  • 133
Kit
  • 11
  • 1
  • 3
  • *"I'd appreciate any piece of advice."* Stop futzing and put an oval shaped image on a square button. I very much doubt a) that the school project requires oval shaped buttons. b) You can get it working in a time suitable for submitting the project. -- Not intending to be a kill-joy, just suggesting you do that last (or not at all). – Andrew Thompson May 26 '12 at 05:49

1 Answers1

4

You have to:

  • Extends the JButton class, and override the paintComponent(Graphics g) method.
  • Do override getPreferredSize() method, which will return on Dimension object and will help the Layout Manager in placing your JButton on the Container/Component, by providing it one appropriate size.

  • Make your circle code there.

  • add an onClickListener, and set a flag on the clicked button if it is clicked, and call it to repaint.


About the Graphics object: it's best to keep it in it's paintComponent method, and to use it only there. It will always get passed in on a repaint, and if you save it for other moments, strange things can happen (happy experimenting :) ).

A small Example :

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

public class ButtonExample
{
    private MyButton customButton;

    private void displayGUI()
    {
        JFrame frame = new JFrame("Custom Button Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        customButton = new MyButton();
        customButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                MyButton.isClicked = true;
                customButton.repaint();
            }
        });

        frame.getContentPane().add(customButton, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new ButtonExample().displayGUI();
            }
        });
    }
}

class MyButton extends JButton
{
    public static boolean isClicked = false;

    public Dimension getPreferredSize()
    {
        return (new Dimension(100, 40));
    }

    public void paintComponent(Graphics g)
    {
        if (!isClicked)
            super.paintComponent(g);
        else
        {
             g.setColor(Color.BLUE);
             g.fillOval(getHorizontalAlignment(), getVerticalAlignment(), getWidth(), getHeight());
        }       
    }
}
nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
Hidde
  • 11,493
  • 8
  • 43
  • 68
  • Hey, Hidde, thanks, I'm not familiar with flags yet but I'll try to get the first two steps done. – Kit May 25 '12 at 22:41
  • A flag is just a variable you make in the extended `JBitton` class. You set that value on true (or 1 or whatever you want), so that the `paintComponent` method knows that it has been clicked and needs a circle. – Hidde May 25 '12 at 22:44
  • @Hidde : Pardon me, for my edit. Just couldn't stop myself from doing the hardwork of providing the SSCCE, for testing purpose :-) If you think it shouldn't have to be there, please feel free to revert back and cancel my edits. – nIcE cOw May 26 '12 at 06:29
  • Added a point, regarding overriding `getPreferredSize()` method, just like we override our `paintComponent(...)` method. – nIcE cOw May 26 '12 at 06:35
  • 1
    That's great, no worries :)! This was a quick answer, I'm sure I have some code like this lying around somewhere, but you've just done it for me, thanks! – Hidde May 26 '12 at 08:30
  • This code did't work for me, I probably did something wrong but didn't spend much time checking thoroughly because in the meantime I found a more important issue in other part of the game so I'll get back to drawing later (for right now I'm just changing the color of the button's background). Thanks a lot anyways, I'm sure it'll be very helpful when I get back to it. – Kit May 28 '12 at 14:39