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 Answers
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.

- 35
- 5