Is there more efficient way to add button R, 0 and E? Is it possible to somehow add them to the array?
public Keypad() {
setTitle("Keypad");
setSize(220, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridLayout(4, 3, 2, 2));
JButton[] buttonArray = new JButton[10];
for (int i = 1; i < buttonArray.length; i++) {
buttonArray[i] = new JButton(String.valueOf(i));
add(buttonArray[i]);
buttonArray[i].addActionListener(this);
}
add(buttonR);
add(button0);
add(buttonE);
setVisible(true);
setResizable(false);
}
You can't get much more efficient than you are already now. You could maybe slightly reorganize the code to move the addition of the ActionListener and the addition of the button to the hierarchy in a single method. Also, the JButton[] is useless so drop it, you will save a few bytes in memory (but really nothing major):
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Keypad extends JFrame implements ActionListener {
private JButton buttonR = new JButton("R");
private JButton button0 = new JButton("0");
private JButton buttonE = new JButton("E");
public Keypad() {
setTitle("Keypad");
setSize(220, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridLayout(4, 3, 2, 2));
for (int i = 1; i < 10; i++) {
addButton(new JButton(String.valueOf(i)));
}
addButton(buttonR);
addButton(button0);
addButton(buttonE);
setResizable(false);
setVisible(true);
}
private void addButton(JButton button) {
button.addActionListener(this);
add(button);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
"Is it possible to somehow add them to the array?"
Yes you can do this if that is what you want
JButton[] buttonArray = new JButton[10];
for (int i = 1; i < buttonArray.length+3; i++) {
if(i<buttonArray.length){
buttonArray[i] = new JButton(String.valueOf(i));
add(buttonArray[i]);
buttonArray[i].addActionListener(this);
}
if(i==buttonArray.length+1){add(buttonR);}
if(i==buttonArray.length+2){add(button0);}
if(i==buttonArray.length+3){add(buttonE);}
}
This does what you want but AFAIK there is no quicker way to do this.
Related
I am trying to add 24 JButtons to the GridLayout of my JPanel buttonPanel, but when I run it, I see that no buttons are added. (At least, they are not visible!). I tried giving the buttonPanel a background color, and it
was visible.
Does anyone know what I'm doing wrong?
This is my code (there is an other class):
package com.Egg;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class NormalCalc implements ActionListener {
static JPanel normalCalcPanel = new JPanel();
JPanel buttonPanel = new JPanel(new GridLayout(6,4,10,10));
Font font = new Font("Monospaced Bold", Font.BOLD, 18);
JButton powB = new JButton("^");
JButton sqrtB = new JButton("sqrt(");
JButton hOpenB = new JButton("(");
JButton hCloseB = new JButton(")");
JButton delB = new JButton("DEL");
JButton acB = new JButton("AC");
JButton mulB = new JButton("*");
JButton divB = new JButton("/");
JButton addB = new JButton("+");
JButton minB = new JButton("-");
JButton decB = new JButton(".");
JButton equB = new JButton("=");
JButton negB = new JButton("(-)");
JButton[] numberButtons = new JButton[10];
JButton[] functionButtons = new JButton[13];
public NormalCalc() {
functionButtons[0] = powB;
functionButtons[1] = delB;
functionButtons[2] = acB;
functionButtons[3] = sqrtB;
functionButtons[4] = mulB;
functionButtons[5] = divB;
functionButtons[6] = hOpenB;
functionButtons[7] = addB;
functionButtons[8] = minB;
functionButtons[9] = hCloseB;
functionButtons[10] = decB;
functionButtons[11] = negB;
functionButtons[12] = equB;
for (int i=0; i<10; i++) {
numberButtons[i] = new JButton(String.valueOf(i));
numberButtons[i].setFocusable(false);
numberButtons[i].setFont(font);
numberButtons[i].addActionListener(this);
}
for (int i=0; i <13; i++) {
functionButtons[i].setFocusable(false);
functionButtons[i].setFont(font);
functionButtons[i].addActionListener(this);
}
normalCalcPanel.setBounds(0, 0, 500, 700);
buttonPanel.setBounds(50, 200, 400, 400);
// Adding the buttons;
buttonPanel.add(functionButtons[0]);
buttonPanel.add(numberButtons[7]);
buttonPanel.add(numberButtons[8]);
buttonPanel.add(numberButtons[9]);
buttonPanel.add(functionButtons[1]);
buttonPanel.add(functionButtons[2]);
buttonPanel.add(functionButtons[3]);
buttonPanel.add(numberButtons[4]);
buttonPanel.add(numberButtons[5]);
buttonPanel.add(numberButtons[6]);
buttonPanel.add(functionButtons[4]);
buttonPanel.add(functionButtons[5]);
buttonPanel.add(functionButtons[6]);
buttonPanel.add(numberButtons[1]);
buttonPanel.add(numberButtons[2]);
buttonPanel.add(numberButtons[3]);
buttonPanel.add(functionButtons[7]);
buttonPanel.add(functionButtons[8]);
buttonPanel.add(functionButtons[9]);
buttonPanel.add(numberButtons[0]);
buttonPanel.add(functionButtons[10]);
buttonPanel.add(functionButtons[11]);
buttonPanel.add(functionButtons[12]);
buttonPanel.repaint();
normalCalcPanel.add(buttonPanel);
normalCalcPanel.add(MainMath.exitButton);
MainMath.frame.add(normalCalcPanel);
MainMath.frame.repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Other (main) class:
package com.Egg;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MainMath implements ActionListener {
static JFrame frame = new JFrame("Math Tools");
static JButton exitButton = new JButton("Exit");
JPanel mainPanel = new JPanel();
JLabel mainLabel = new JLabel("Select your tool.", SwingConstants.CENTER);
JButton nB = new JButton("Normal Calc.");
JButton tB = new JButton("Right Triangle Calc.");
JButton eB = new JButton("Equations Calc.");
public MainMath() {
frame.setBounds(300, 300, 500, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setResizable(false);
mainPanel.setLayout(null);
mainPanel.setBounds(0, 0, 500, 700);
mainLabel.setBounds(100, 25, 300, 50);
mainLabel.setFont(new Font("Monospaced Bold", Font.BOLD, 18));
nB.setBounds(100, 100, 300, 40);
tB.setBounds(100, 150, 300, 40);
eB.setBounds(100, 200, 300, 40);
nB.setFocusable(false);
tB.setFocusable(false);
eB.setFocusable(false);
nB.addActionListener(this);
tB.addActionListener(this);
eB.addActionListener(this);
mainPanel.add(mainLabel);
mainPanel.add(nB);
mainPanel.add(tB);
mainPanel.add(eB);
frame.add(mainPanel);
frame.setVisible(true);
exitButton.setBounds(16, 10, 80, 35);
exitButton.setFocusable(false);
exitButton.addActionListener(this);
}
public static void main(String[] args) {
new MainMath();
System.out.println("");
}
public void setMainScreen() {
frame.remove(exitButton);
frame.remove(NormalCalc.normalCalcPanel);
frame.add(mainPanel);
frame.repaint();
}
public static JFrame getFrame() {
return frame;
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == exitButton)
setMainScreen();
if (e.getSource() == nB) {
frame.remove(mainPanel);
new NormalCalc();
}
if (e.getSource() == tB)
new TriangleCalc();
if (e.getSource() == eB)
new EquationCalc();
}
}
I see multiple issues in your code:
Your arrangement of your buttons is weird looking at first glance.
normalCalcPanel is static, why? It should never be
setBounds(...) when using layout managers, those statements are ignored, so no need for them
repaint() unless you've added / removed any element AFTER you've displayed your GUI, these calls are unnecessary, and should come with revalidate() as well.
MainMath.exitButton another static component, STOP
MainMath.frame.add(normalCalcPanel) implies that your JFrame called frame is static as well, which again, shouldn't be
And (I'm gonna guess here) more than probably you're creating a second instance inside MainMath, but because we don't have the code from that class we don't know what's going on
I ran your code and it looks ok, so that's why I believe your MainMath is creating another instance of JFrame
Here's an example of a calculator arrangement, that should help you to structure your code similarly, not the GUI but the components and classes
Edit
Okay, I understand now that I should not use static things, but how can I add a panel to a frame which I created in another class? I used 'static', because it seemed to work
Let's make an analogy for this case, imagine that your JFrame is a book, and that your JPanels are the sheets of that book, when you write on those sheets, you don't add / paste the book to the sheets, you add the sheets to the book.
So, in this case it's the same, your main class should create the JPanels and add those to your JFrame, your JPanel classes shouldn't have knowledge of your JFrame
In the case of the book, your sheets don't need to know to which book the belong, you know that and the book knows which sheets belong to it, not viceversa.
I made an example to show you what I mean by this, I didn't recreate your GUI but made it as simple as I could for you to get the idea:
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class AnotherCalculator {
private JFrame frame;
private CalculatorPanel calculatorPanel;
public static void main(String[] args) {
SwingUtilities.invokeLater(new AnotherCalculator()::createAndShowGUI);
}
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
calculatorPanel = new CalculatorPanel();
frame.add(calculatorPanel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class CalculatorPanel extends JPanel {
private String[] operations = {"+", "-", "*", "/", "DEL", "AC", "(", ")", "-", "^", "SQRT", ".", "+/-", "="};
private static final int NUMBER_OF_DIGITS = 10;
private JButton[] buttons;
public CalculatorPanel() {
this.setLayout(new GridLayout(0, 4, 5, 5));
buttons = new JButton[operations.length + NUMBER_OF_DIGITS];
for (int i = 0; i < buttons.length; i++) {
if (i < NUMBER_OF_DIGITS) {
buttons[i] = new JButton(String.valueOf(i));
} else {
buttons[i] = new JButton(operations[i - NUMBER_OF_DIGITS]);
}
this.add(buttons[i]);
}
}
}
i have a problem with adding a specific number of buttons from my for-loop to my JPanel, i know how to add all oof them, but i want to add only 1-10 (i havent decided yet, lets go with 10).'
this is my class where i just declare what objects i want to have.
private static int cID;
private static Deck[] card;
static ArrayList<JButton> buttonList = new ArrayList<JButton>();
private JFrame f;
private JPanel p1;
private JButton button;
public boolean isEmpty() {
return cID == 0;
}
public static void main(String[] args) {
CustomDecks c = new CustomDecks();
c.deckCreator();
}```
this is my for-loop where i create 420 buttons and give them names "card" + i where i is 0 - 419, yet when i try to add card0 to my panel, it fails, why?
private void deckCreator() {
card = new Deck[25];
new ArrayList<Cards> (cSet.cards);
for(int i = 0; i < 420; i++) {
button = new JButton();
buttonList.add(button);
button.setName("card" + i);
f.add(button);
p1.add(card0);
}
f.add(p1);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setUndecorated(true);
}
}
}
I'm not sure you can create a JPanel large enough to hold 420 JButtons.
Here's an example of a JButton GUI.
[
Generally, you create an application model and view separately. The model is made up of one or more plain Java classes. The view reads from the application model but doesn't update the model.
Your controller classes (ActionListener classes) update the application model and update / repaint the view.
This pattern is called the model / view / controller (MVC) pattern.
You can see in the example code below that the model is created in the view class constructor. Generally, you create the application model first, then you create the application view.
And here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
public class JButtonScrollGUI {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new JButtonScrollGUI();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private String[] greekAlphabet;
public JButtonScrollGUI() {
this.greekAlphabet = new String[] { "alpha", "beta", "gamma", "epsilon", "zeta" };
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setTitle("Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createScrollPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createScrollPanel() {
JPanel panel = new JPanel(new BorderLayout());
JPanel innerPanel = createButtonPanel();
Dimension d = innerPanel.getPreferredSize();
d.width += 50;
d.height /= 2;
panel.setPreferredSize(d);
JScrollPane scrollPane = new JScrollPane(innerPanel);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new GridLayout(0, 3, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
for (int i = 0; i < 20; i++) {
JButton button1 = new JButton("Previous " + i);
panel.add(button1);
JComboBox<String> selectorBox = new JComboBox<>(greekAlphabet);
panel.add(selectorBox);
JButton button2 = new JButton("Next " + i);
button2.setPreferredSize(button1.getPreferredSize());
panel.add(button2);
}
return panel;
}
}
I want to make list of JButtons (with fixed dimensions, one beneath another) inside JScrollPane, using Swing. My idea was to make JPanel with GridBagLayout and add buttons in their suiting rows, and then create JScrollPane with that JPanel. That looks fine when number of buttons is large, but when the number of buttons is 2 or 3, I can't manage to align buttons one right below the other.
Also later I will add option to add new button (thus the + sign).
Works fine with 10 buttons
I get this empty space between button 0 and button 1 when it's just 2 buttons (this is the problem)
The code (creates upper east panel)
private JPanel createLayerPanel() {
JPanel layerPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// Label ------------------------------------------------
JLabel layersLabel = new JLabel("Buttons");
layersLabel.setHorizontalAlignment(SwingConstants.CENTER);
layersLabel.setFont(DEFAULT_FONT);
//layersLabel.setBorder(new LineBorder(Color.red, 3));
layersLabel.setBackground(new Color(0x22222));
layersLabel.setForeground(new Color(0xFFFFFF));
layersLabel.setOpaque(true);
c.gridx = c.gridy = 0;
c.ipadx = 180;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
layerPanel.add(layersLabel, c);
// Button ------------------------------------------------
JButton newLayerBtn = new JButton("+");
newLayerBtn.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 18));
newLayerBtn.setBackground(new Color(0x222222));
newLayerBtn.setForeground(Color.white);
newLayerBtn.setFocusable(false);
c.gridx = 1;
c.gridy = 0;
c.ipadx = 0;
c.weightx = 0;
layerPanel.add(newLayerBtn, c);
// ScrollPane ------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
JPanel layerListPanel = new JPanel(new GridBagLayout());
layerListPanel.setBackground(Color.BLACK);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1;
gbc.ipady = 40;
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.NORTH;
for (gbc.gridy = 0; gbc.gridy < 10; gbc.gridy++) {
JButton btn = new JButton("Button " + gbc.gridy);
layerListPanel.add(btn, gbc);
}
JScrollPane js = new JScrollPane(layerListPanel);
js.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// ...
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 2;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
layerPanel.add(js, c);
return layerPanel;
}
Do you absolutely need a GridBagLayout?
I just made a demo using a simple Box.
And please have a look at How to write an SSCCE.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class YY extends JFrame {
static String[] args;
public YY() {
setSize(160, 200);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
int icnt= args.length==0 ? 5 : Integer.parseInt(args[0]);
Box box= Box.createVerticalBox();
for (int i=1; i<=icnt; i++) {
JButton btn= new JButton("Button "+i);
btn.setMaximumSize(new Dimension(150, 30));
box.add(btn);
}
JScrollPane scroll= new JScrollPane(box);
scroll.setPreferredSize(new Dimension(150, 100));
add(scroll);
setVisible(true);
}
public static void main(String... args) {
YY.args= args;
EventQueue.invokeLater(YY::new);
}
}
The below code initially displays a JFrame that contains a single JButton that displays the text Add. Each time you click the button a new JButton appears above it. The text on each newly created button is a three digit number with leading zeros that is incremented each time the Add button is clicked. And whenever a new button is added, the JFrame increases in height in order to display the newly added button.
import java.awt.BorderLayout;
import java.awt.EventQueue;
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.WindowConstants;
public class GridBttn implements ActionListener, Runnable {
private int counter;
private JFrame frame;
private JPanel gridPanel;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent event) {
addButtonToGridPanel();
}
private void addButtonToGridPanel() {
JButton button = new JButton(String.format("%03d", counter++));
gridPanel.add(button);
frame.pack();
}
private JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton("Add"));
return buttonsPanel;
}
private JPanel createGridPanel() {
gridPanel = new JPanel(new GridLayout(0, 1));
return gridPanel;
}
private void showGui() {
frame = new JFrame("Grid");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createGridPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new GridBttn());
}
}
Note the parameters to GridLayout constructor. Zero rows and one column. This means that whenever a Component is added to the JPanel it will be placed directly beneath the last Component added. In other words all the components added will appear in a single column. Also note that I call method pack() (of class JFrame) after adding a new button. This causes the JFrame to recalculate its size in order to display all the buttons.
EDIT
Due to OP's comment slightly modified above code so as to be more suitable to his requirements.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;
public class GridBttn implements ActionListener, Runnable {
private int counter;
private JFrame frame;
private JPanel gridPanel;
private JPanel gridPanel2;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent event) {
addButtonToGridPanel();
}
private void addButtonToGridPanel() {
JButton button = new JButton(String.format("%03d", counter++));
gridPanel2.add(button);
frame.pack();
}
private JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton("Add"));
return buttonsPanel;
}
private JPanel createMainPanel() {
gridPanel = new JPanel();
gridPanel.setPreferredSize(new Dimension(400, 300));
return gridPanel;
}
private JScrollPane createScrollPane() {
gridPanel2 = new JPanel();
BoxLayout layout = new BoxLayout(gridPanel2, BoxLayout.PAGE_AXIS);
gridPanel2.setLayout(layout);
JScrollPane scrollPane = new JScrollPane(gridPanel2,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(70, 0));
return scrollPane;
}
private void showGui() {
frame = new JFrame("Grid");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createScrollPane(), BorderLayout.LINE_END);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new GridBttn());
}
}
I'm new to Java programming. Can you help me with the layout of my first application (which is a simple calculator) please?
Here's the code I wrote:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class InputPad extends JFrame {
private JLabel statusLabel;
private JTextArea expTextArea;
InputPad() {
prepareGUI();
}
private void prepareGUI(){
JFrame mainFrame = new JFrame("My Calculator");
mainFrame.setSize(450,450);
mainFrame.setLayout(new GridLayout(3,2));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
JLabel headerLabel = new JLabel("Put your expression here:", JLabel.CENTER);
statusLabel = new JLabel("",JLabel.CENTER);
expTextArea = new JTextArea("1+(2^3*4)");
//Digits Panel
JPanel digitPanel = new JPanel();
GroupLayout layoutDigits = new GroupLayout(digitPanel);
digitPanel.setLayout(layoutDigits);
layoutDigits.setAutoCreateGaps(true);
layoutDigits.setAutoCreateContainerGaps(true);
//Operators Panel
JPanel operatorPanel = new JPanel();
GroupLayout layoutOperators = new GroupLayout(operatorPanel);
operatorPanel.setLayout(layoutOperators);
layoutOperators.setAutoCreateGaps(true);
layoutOperators.setAutoCreateContainerGaps(true);
JButton[] numButtons= new JButton[10];
int i;
for (i=0;i<10;i++){
numButtons[i] = new JButton(Integer.toString(i));
numButtons[i].addActionListener(e -> {
// TODO
});
}
JButton bEquals = new JButton("=");
bEquals.addActionListener(e -> {
// TODO
});
JButton bPlus = new JButton("+");
bPlus.addActionListener(e -> {
// TODO
});
JButton bMinus = new JButton("-");
bMinus.addActionListener(e -> {
// TODO
});
JButton bMultiply = new JButton("*");
bMultiply.addActionListener(e -> {
// TODO
});
JButton bDivide = new JButton("/");
bDivide.addActionListener(e -> {
// TODO
});
JButton bLeftParenthesis = new JButton("(");
bLeftParenthesis.addActionListener(e -> {
// TODO
});
JButton bRightParenthesis = new JButton(")");
bRightParenthesis.addActionListener(e -> {
// TODO
});
JButton bPower = new JButton("^");
bPower.addActionListener(e -> {
// TODO
});
JButton bDel = new JButton("←");
bDel.addActionListener(e -> {
// TODO
});
layoutDigits.setHorizontalGroup(
layoutDigits.createSequentialGroup()
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(numButtons[7])
.addComponent(numButtons[4])
.addComponent(numButtons[1])
.addComponent(numButtons[0]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(numButtons[8])
.addComponent(numButtons[5])
.addComponent(numButtons[2])
.addComponent(bEquals))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(numButtons[9])
.addComponent(numButtons[6])
.addComponent(numButtons[3]))
);
layoutDigits.setVerticalGroup(
layoutDigits.createSequentialGroup()
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[7])
.addComponent(numButtons[8])
.addComponent(numButtons[9]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[4])
.addComponent(numButtons[5])
.addComponent(numButtons[6]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[1])
.addComponent(numButtons[2])
.addComponent(numButtons[3]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[0])
.addComponent(bEquals))
);
layoutOperators.setHorizontalGroup(
layoutOperators.createSequentialGroup()
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(bPlus)
.addComponent(bMinus)
.addComponent(bLeftParenthesis)
.addComponent(bPower))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(bMultiply)
.addComponent(bDivide)
.addComponent(bRightParenthesis)
.addComponent(bDel))
);
layoutOperators.setVerticalGroup(
layoutOperators.createSequentialGroup()
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bPlus)
.addComponent(bMultiply))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bMinus)
.addComponent(bDivide))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bLeftParenthesis)
.addComponent(bRightParenthesis))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bPower)
.addComponent(bDel))
);
mainFrame.add(headerLabel);
mainFrame.add(expTextArea);
mainFrame.add(digitPanel);
mainFrame.add(operatorPanel);
mainFrame.add(statusLabel);
mainFrame.setVisible(true);
}
}
I tried the GridLayout for my JFrame, but I couldn't resize and of my JComponent except the main JFrame. Even I can't place two JPanels (side by side) in one cell of the GridLayout or expand a JLabel to two cells of the GridLayout.
This is what I got:
And here's what I want:
Let's start from the use of Layout Managers, from the link on the part of GridLayout
GridLayout simply makes a bunch of components equal in size and displays them in the requested number of rows and columns
So, this isn't what you want, but if you read the GridBagLayout part it says:
GridBagLayout is a sophisticated, flexible layout manager. It aligns components by placing them within a grid of cells, allowing components to span more than one cell. The rows in the grid can have different heights, and grid columns can have different widths.
We can combine both of them, along with a BoxLayout and you will get a similar output to what you're trying to achieve:
PLEASE NOTE:
Before posting the code, take note of the following tips:
You're extending JFrame and at the same time you're creating a JFrame object, this is discouraged, remove one of them, in this case as you're using the object and this is the recommended thing to do, simply remove the extends JFrame from your class. If you really need to extend something, don't extend JFrame but a JPanel instead.
Place your program inside the EDT, as I did in the main() method
Don't use System.exit(0); instead call setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) as shown in the above code
And now the code
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class CalculatorExample {
private JFrame frame;
private JTextArea area;
private JButton[][] digitsButtons, symbolsButtons;
private String[][] digitsText = {{"7", "8", "9"}, {"4", "5", "6"}, {"1", "2", "3"}, {"0", "="}}; //Looks strange but this will make the button adding easier
private String[][] symbolsText = {{"+", "*"}, {"-", "/"}, {"(", ")"}, {"^", "←"}};
private JPanel buttonsPane, areaAndResultsPane, digitsPane, symbolsPane;
private JLabel label;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new CalculatorExample().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("Calculator Example");
area = new JTextArea();
area.setRows(5);
area.setColumns(20);
label = new JLabel("Results go here");
digitsButtons = new JButton [4][3];
symbolsButtons= new JButton [4][2];
areaAndResultsPane = new JPanel();
areaAndResultsPane.setLayout(new BoxLayout(areaAndResultsPane, BoxLayout.PAGE_AXIS));
buttonsPane = new JPanel();
buttonsPane.setLayout(new GridLayout(1, 2, 10, 10));
digitsPane = new JPanel();
digitsPane.setLayout(new GridBagLayout());
symbolsPane = new JPanel();
symbolsPane.setLayout(new GridLayout(4, 2));
GridBagConstraints c = new GridBagConstraints();
for (int i = 0; i < digitsText.length; i++) {
for (int j = 0; j < digitsText[i].length; j++) {
digitsButtons[i][j] = new JButton(digitsText[i][j]);
}
}
for (int i = 0; i < symbolsText.length; i++) {
for (int j = 0; j < symbolsText[i].length; j++) {
symbolsButtons[i][j] = new JButton(symbolsText[i][j]);
}
}
areaAndResultsPane.add(area);
areaAndResultsPane.add(label);
boolean shouldBreak = false;
for (int i = 0; i < digitsButtons.length; i++) {
for (int j = 0; j < digitsButtons[i].length; j++) {
c.gridx = j;
c.gridy = i;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
if (i == 3) {
if (j == 1) {
c.gridwidth = 2; //This makes the "=" button larger
shouldBreak = true;
}
}
digitsPane.add(digitsButtons[i][j], c);
if (shouldBreak) {
break;
}
}
}
for (int i = 0; i < symbolsButtons.length; i++) {
for (int j = 0; j < symbolsButtons[i].length; j++) {
symbolsPane.add(symbolsButtons[i][j]);
}
}
frame.add(areaAndResultsPane, BorderLayout.NORTH);
buttonsPane.add(digitsPane);
buttonsPane.add(symbolsPane);
frame.add(buttonsPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
This was done nesting JPanels, each with a different layout, I hope it helps you to continue from here.
According to the Oracle documentation :
Each component takes all the available space within its cell, and each cell is exactly the same size.
So sadly, you can't resize any components inside a GridLayout.
You could instead use a GridBagLayout. It is a little bit more complicated to understand but offers more features. I let you make some tests with the documentation to get in touch with it !
My code was working before, but now one JButton takes up the entire JFrame, any help would be appreciated!
I am using a FlowLayout called fl and a class called Ken
I have ten buttons called (oneButton, twoButton, threeButton, etc..)
MY CODE:
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Ken {
public static void frame(){
JFrame frame = new JFrame("Pow");
frame.setSize(500, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
FlowLayout fl = new FlowLayout(0, 50, 40);
JButton oneButton = new JButton(" 1 ");
oneButton.setPreferredSize(new Dimension(100, 90));
frame.add(oneButton);
JButton twoButton = new JButton(" 2 ");
twoButton.setPreferredSize(new Dimension(100, 90));
frame.add(twoButton);
JButton threeButton = new JButton(" 3 ");
threeButton.setPreferredSize(new Dimension(100, 90));
frame.add(threeButton);
JButton fourButton = new JButton(" 4 ");
fourButton.setPreferredSize(new Dimension(100, 90));
frame.add(fourButton);
JButton fiveButton = new JButton(" 5 ");
fiveButton.setPreferredSize(new Dimension(100, 90));
frame.add(fiveButton);
JButton sixButton = new JButton(" 6 ");
sixButton.setPreferredSize(new Dimension(100, 90));
frame.add(sixButton);
JButton sevenButton = new JButton(" 7 ");
sevenButton.setPreferredSize(new Dimension(100, 90));
frame.add(sevenButton);
JButton eightButton = new JButton(" 8 ");
eightButton.setPreferredSize(new Dimension(100, 90));
frame.add(eightButton);
JButton nineButton = new JButton(" 9 ");
nineButton.setPreferredSize(new Dimension(100, 90));
frame.add(nineButton);
JButton zeroButton = new JButton("
0 ");
zeroButton.setPreferredSize(new Dimension(400, 90));
frame.add(zeroButton);
frame.setComponentOrientation(
ComponentOrientation.LEFT_TO_RIGHT);
}
public static void main(String[] args){
frame();
}
}
Anything I can try?
I am using a FlowLayout called fl ...
You are not in fact using FlowLayout as you never call setLayout(...) on a container. Instead your Frame's contentPane is using the default layout for contentPanes, BorderLayout, which will cause the last component added in a default way to fill up the container's BorderLayout.CENTER location.
So one solution is to use your layout:
FlowLayout fl = new FlowLayout(0, 50, 40);
frame.getContentPane().setLayout(fl);
But having said that, you will probably be better off not setting the preferred sizes of your components but instead using a combination of nested containers each using its own layout in order to achieve a pleasing and complex GUI that will be much easier to maintain and extend.
Alternatively, you could play with more complex layouts such as the GridBagLayout. For example:
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class Ken2 {
private static final String[][] NUMBERS = {
{"1", "2", "3"},
{"4", "5", "6"},
{"7", "8", "9"},
{"0"}
};
private static final float BUTTON_FONT_PTS = 45f;
private static final int INSETS = 20;
private static final Insets BUTTON_INSETS = new Insets(INSETS, INSETS,
INSETS, INSETS);
private static final int IPAD = 20;
private JPanel mainPanel = new JPanel();
public Ken2() {
mainPanel.setLayout(new GridBagLayout());
for (int row = 0; row < NUMBERS.length; row++) {
addRowToPanel(row, NUMBERS[row]);
}
}
private void addRowToPanel(int row, String[] numbersRow) {
int columns = numbersRow.length;
for (int col = 0; col < numbersRow.length; col++) {
addNumberButton(row, col, columns, numbersRow[col]);
}
}
private void addNumberButton(int row, int col, int columns,
String numberText) {
JButton button = new JButton(numberText);
button.setFont(button.getFont().deriveFont(Font.BOLD, BUTTON_FONT_PTS));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = col;
gbc.gridy = row;
gbc.gridheight = 1;
gbc.gridwidth = 3 / columns;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = BUTTON_INSETS;
gbc.ipadx = IPAD;
gbc.ipady = IPAD;
mainPanel.add(button, gbc);
}
private static void createAndShowGui() {
Ken2 ken = new Ken2();
JFrame frame = new JFrame("Ken2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(ken.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private Component getMainPanel() {
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Call setLayout(fl) on your void frame() method.