0

Hey I'm doing a calculator app with java swing (A clone of windows calculator ;) ) As it is a calculator, it has a lot of JButtons with same properties. So my question is can I change the common properties of a group JButtons at once, based on 'DRY'. If possible it will help me a lot...

  • 3
    *"based on 'DRY'"* Use a factory method. – Andrew Thompson Mar 18 '21 at 09:48
  • You could create your own subclass of `JButton`, which then sets the properties you want by default. E.g. you create a `class CalcButton extends JButton` and use these as your buttons. However I would only do this if you want to modify more than just some properties of the default button. – maloomeister Mar 18 '21 at 09:48

1 Answers1

1

A simple subclass of JButton should help, like this example - a modified version of what I saw from another question below:

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

@SuppressWarnings("serial")
public class MyButton extends JButton {

    private Color circleColor = Color.BLACK;

    public MyButton(String label) {
        super(label);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Dimension originalSize = super.getPreferredSize();
        int gap = (int) (originalSize.height * 0.2);
        int x = originalSize.width + gap;
        int y = gap;
        int diameter = originalSize.height - (gap * 2);

        g.setColor(circleColor);
        g.fillOval(x, y, diameter, diameter);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        size.width += size.height;
        return size;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(new MyButton("Custom Button"));
        frame.setVisible(true);
    }

}

If you want more info, research: Creating a custom JButton in Java, which is the cited reference for the example above. Of course, you can code the properties to your liking with the assistance of the JButton Javadoc: https://docs.oracle.com/javase/7/docs/api/javax/swing/JButton.html.

But for modifying the custom button after instantiation: Make sure to add a static ArrayList that contains the instantiated buttons, as well as means to add a constructed button to the arraylist:

public static ArrayList<MyButton> myButtons = new ArrayList<MyButton>();

public MyButton(){
//...
myButtons.add(this);
}

And for modification of the properties/attributes of all buttons (say for example, whether they are visible), do:

public void setVisibleAll(boolean b){
for(MyButton x: myButtons){
x.setVisible(b);
}
}

Not only does this apply to buttons, it should apply to other swing components, like a JLayeredPane designed to act like a button:

package source_code.view.components.buttons;

import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.SwingConstants;

import source_code.controllers.ButtonListener350x40;
import source_code.plus_functions.Texture;

@SuppressWarnings("serial")
public class Button350x40 extends JLayeredPane {

    private JLabel buttonBg = new JLabel();
    private JLabel buttonText = new JLabel();
    private ButtonListener350x40 listener = new ButtonListener350x40();
    private static ArrayList<Button350x40> buttons = new ArrayList<Button350x40>();
    private String id;
    
    public Button350x40(String title, String id) {
        //Button Proper
        super();
        super.setSize(350, 40);
        super.setLayout(null);
        super.addMouseListener(listener);
            //Button BG
            buttonBg.setIcon(new ImageIcon(Texture.textures.get("button_350x40")));
            super.setLayer(buttonBg, 0);
            buttonBg.setBounds(0, 0, 350, 40);
            super.add(buttonBg);
            //Button Text
            buttonText.setText(title);
            buttonText.setForeground(Color.BLACK);
            super.setLayer(buttonText, 1);
            buttonText.setHorizontalAlignment(SwingConstants.CENTER);
            buttonText.setFont(new Font("Arial", Font.PLAIN, 20));
            buttonText.setBounds(0, 0, 350, 40);
            super.add(buttonText);
        this.id = id;
        buttons.add(this);
    }

    public String getId() {
        return id;
    }

    public static ArrayList<Button350x40> getButtons() {
        return buttons;
    }

    public JLabel getButtonBg() {
        return buttonBg;
    }

    public JLabel getButtonText() {
        return buttonText;
    }

    public ButtonListener350x40 getListener() {
        return listener;
    }

}

So TLDR, create a separate class for the custom button, have a static array of created buttons, and to modify all of the buttons, create a method that loops through the array of buttons and sets their respective attributes.

3gordd
  • 35
  • 5