user2693979
user2693979

Reputation: 2542

Composition vs inheritence in JButton

I'd like to create a simple table game by Swing. I have a JFrame and a JPanel variable.

I want to add JButtons to this JPanel, but I'd like to create an own class.

I made a class that extends JButton (inheritence):

public class GameField extends JButton {...}

So I could add GameFields to the JPanel.

But I'd like to create GameFields by composition:

public class GameField{

    private JButton button;

}

But in this clase how I can add GameField to JPanel? Can I solve this problem by compisition?

Upvotes: 3

Views: 196

Answers (2)

dic19
dic19

Reputation: 17971

But in this clase how I can add GameField to JPanel? Can I solve this problem by compisition?

You do this by adding a simple getter like this:

public class GameField{

    private JButton button;

    public GameField(String text) {
        button = new JButton(text);
        // do your stuff here
    }

    public JButton getButton() {
        return button;
    }
}

Then in your GUI:

public void createAndShowGUI() {
    JPanel panel = new JPanel(new GridLayout(5,5));
    panel.add(new GameField("Button # 1").getButton());
    panel.add(new GameField("Button # 2").getButton());
    ...
    JFrame frame = new JFrame("Game");
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.getContentPane().add(panel);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

Edit

You've stated in a comment:

Thanks, but in this case if I'd like to access this field (i.e. panel.getComponent(i)), I can get only a JButton, and not a GameField.

You can keep a list with your GameField objects or you can use putClientProperty() method to keep a reference to the GameField object as shown in the example below:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Demo {

    private void createAndShowGUI() {        
        ActionListener actionListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JButton button = (JButton)e.getSource();
                GameField gameField = (GameField)button.getClientProperty("GameField");
                if(gameField != null) {
                    System.out.println(gameField.getText());
                }
            }
        };

        GameField gameField1 = new GameField("Button # 1");
        gameField1.getButton().addActionListener(actionListener);

        GameField gameField2 = new GameField("Button # 2");
        gameField2.getButton().addActionListener(actionListener);

        JPanel content = new JPanel(new GridLayout());
        content.add(gameField1.getButton());
        content.add(gameField2.getButton());

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    class GameField {

        private String text;
        private JButton button;

        public GameField(String text) {
            this.text = text;
            button = new JButton(text);
            button.putClientProperty("GameField", GameField.this);
        }

        public JButton getButton() {
            return button;
        }

        public String getText() {
            return text;
        }        
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {                
                new Demo().createAndShowGUI();
            }
        });
    }    
}

Upvotes: 6

pedromss
pedromss

Reputation: 2453

If you wish your GameField objects to have JComponents and still be able to add them to other JComponents, have them extend JPanel instead of JButton.

You can then have your GameField objects as JPanels with other JComponents and add them to your JFrame.

Upvotes: 0

Related Questions