iridescent
iridescent

Reputation: 305

Newly created JButton doesn't override the previously created JButtons

Essentially, what I have coded is a puzzle game.

It contains an image , and the image is further divided into 9 pieces which is placed onto JPanel containing a 3x3 JButton GridLayout. Initially, the 9 buttons are empty. When the user clicks "Start Game", the 9 buttons will then show the images on the buttons.

I used setPreferredSize() to set the size of the JPanel containing the 9 empty JButtons. After that, I used Inset ( 0,0,0,0 ) to make the button's contents fill the entire button.

But now, when I want to add the imaged buttons to replace the empty buttons when the user clicks "Start Game" , it doesn't work.

I think this is because the setPreferredSize() I set earlier on is preventing the Insets values from working.

I inserted some system.out.println values to check if the method is running, it runs, but the image still refuses to appear on the buttons when user clicks "Start Game" .

    public class GameFrame extends JFrame implements ActionListener {
        private JButton button1;
        private JButton[] button = new JButton[9];
        private Insets buttonMargin;
        private boolean testImageMethod;
        private JPanel puzpiece;

        public GameFrame(){
            //.. coding ..

            // create new buttons - button1
            button1  = new JButton("Start Game");
            // add action event to "Start" button
            button1.addActionListener(this);

            // creates a new panel for the splitted puzzle pieces
            puzpiece = new JPanel();
            puzpiece.setLayout(new GridLayout(3,3));

            // check if testImageMethod boolean ( in setupImage() ) is true, 
            //if it isn't, adds 9 buttons w/o images.
             for(int a=0; a<9; a++){
                 if(testImageMethod){
                 }
                 else{
                     // adds 9 buttons without images 
                   button[a] = new JButton();  
                   puzpiece.add(button[a]);
                   puzpiece.setPreferredSize(new Dimension(500,200));
                 }


             }
             // adds puzpiece panel into the frame 
              this.add(puzpiece,BorderLayout.WEST);     
            //.. coding ..

        }

        public void actionPerformed(ActionEvent e){
            if (e.getSource() == button1){
                // puzpiece.button.setVisible(false);
                //puzpiece.remove(button);

                // call setImage() method
                setImage();

                for(int a=0; a<9; a++){
                // adds the new 9 buttons with images into panel
                puzpiece.add(button[a]);
                // test if method is running
                System.out.println("qq");
                }
            }
            else{
                System.out.println("bbb");
            }
        } 

        // method setImage() divides the image into subimages
        public void setImage(){
          //.. coding ..
          // test if method is running
          System.out.println("a");

            setupImage( count++, sc );
        }

        // method setupImage() adds the subimages to the buttons
        private void setupImage( int a, Image wi )
        { 
          // test if method is running
          System.out.println("d");

            buttonMargin = new Insets( 0, 0, 0, 0 );
            button[a] = new JButton( new ImageIcon( wi ) );
            button[a].setMargin( buttonMargin );

            // test if method is running
            System.out.println("e");

        } // end method setupImage()
    }

Upvotes: 2

Views: 122

Answers (2)

nIcE cOw
nIcE cOw

Reputation: 24626

Simply setIcon for the said JButton, don't add JButton anew to the JPanel, already visible

A small example for the same :

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

/**
 * Created with IntelliJ IDEA.
 * User: Gagandeep Bali
 * Date: 1/19/13
 * Time: 10:05 AM
 * To change this template use File | Settings | File Templates.
 */
public class ButtonImageTest
{
    private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
    private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
    private JButton button;
    private int counter = 1;

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

        JPanel contentPane = new JPanel();
        button = new JButton();
        button.setBorderPainted(false);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (counter % 2 != 0)
                {
                    button.setIcon(errorIcon);
                    counter = 2;
                }
                else
                {
                    button.setIcon(infoIcon);
                    counter = 1;
                }
            }
        });
        contentPane.add(button);

        frame.setContentPane(contentPane);
        frame.setSize(100, 100);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    public static void main(String... args)
    {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ButtonImageTest().displayGUI();
            }
        });
    }
}

Upvotes: 4

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285440

I'm not sure I know exactly what you're doing but, ...

  • It appears that you are populating a JPanel with a 3x3 grid of plain JButtons,
  • and that on button press you are adding in JButtons that display an image.
  • But I don't see you removing the original buttons before adding new buttons.
  • Nor do I see you call revalidate() and then repaint() on the puzpiece JPanel after changing components.
  • And even more importantly, why swap JButtons when it's much easier to swap ImageIcons in JButtons that are already held by the puzpiece JPanel? This is something that I recommended in comment 10 minutes ago but am now making an answer.

Upvotes: 4

Related Questions