automated buttons implementation in java - java

I want to have a for loop, that can implement and add a specified number of JButtons the one after the other. I was trying to implement it and this is my code so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ArrayForm extends JFrame implements ActionListener
{
JPanel numPanel = new JPanel();
JPanel opPanel = new JPanel();
JTextField textField = new JTextField(25);
JButton [] buttons = new JButton[10];
JButton [] OPbuttons = new JButton[6];
String num="";
String [] operation = {"+","-","*","/","=","C"};
public static void main(String[] args)
{ArrayForm fobject = new ArrayForm();}
public ArrayForm()
{
setLayout(new FlowLayout());
setSize(400,300);
setTitle("Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
numPanel.setPreferredSize(new Dimension(180,150));
numPanel.setLayout(new FlowLayout());
opPanel.setPreferredSize(new Dimension(200,70));
opPanel.setLayout(new FlowLayout());
for (int i = 0; i<10; i++)
{
//The code in here
}
for (int i = 0; i<6; i++)
{
//The code in here
}
add(textField);
this.textField.setEditable(false);
add(numPanel);
add(opPanel);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e)
{
}
}
Can you please help me with for loop part? where the first one is buttons array, and the second one is for OPbuttons array.

Your for loop part might be as follows:
for (int i = 0; i<10; i++)
{
buttons[i] = new JButton(""+i);
numPanel.add(buttons[i]);
buttons[i].addActionListener(this);
}
for (int i = 0; i<6; i++)
{
OPbuttons[i] = new JButton(operation[i]);
opPanel.add(OPbuttons[i]);
OPbuttons[i].addActionListener(this);
}
What i have understood, is that you are trying to add the buttons of a calculator automatically, within two different panels...
NB: don't forget to add the code for your Action Listener.

Related

Weird speed bug in my Java Calculator program

I was creating a Java Calculator with GUI. I created the JPanel of buttons using arrays, but I notice from the start that when the window appears, the buttons load after 3-4 seconds. I checked everything I could but can't find the problem. Here's the code:
Main
package main;
import ui.Calculator;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
calculator.setVisible(true);
calculator.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
Calculator
package ui;
import javax.swing.*;
import java.awt.*;
public class Calculator extends JFrame {
public Calculator() {
super("Calculator");
setSize(400, 400);
setLocation(400, 400);
setLayout(new BorderLayout());
Buttons buttons = new Buttons();
add(buttons);
}
}
Buttons This is what I think, the root of the problem
package ui;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
/**
* Creates a JPanel with the buttons that is going to be on the Window
*/
class Buttons extends JPanel{
private static JButton[] numbers = new JButton[10];
private static JButton bdot, bsum, bsubstract, bdivide, bmultiply, bequal;
Buttons() {
initializeButtons();
JButton[] buttonNumbers = {numbers[7], numbers[8], numbers[9], bdivide, numbers[4], numbers[5], numbers[6], bmultiply,
numbers[1], numbers[2], numbers[3], bsubstract, numbers[0], bdot, bsum, bequal};
setLayout(new GridLayout(4, 4));
int counter = 0;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
add(buttonNumbers[counter]);
counter ++;
}
}
}
/**
* Function that initialize all the buttons with their respective text
*/
private static void initializeButtons() {
for (int i = 0; i < numbers.length; i++) {
numbers[i] = new JButton("" + i);
}
bdot = new JButton(".");
bsum = new JButton("+");
bsubstract = new JButton("-");
bdivide = new JButton("/");
bmultiply = new JButton("*");
bequal = new JButton("=");
}
}
Note: I know that there are other ways to do this, but I just can't find the problem with this approach, I hope you can help me, thank you.

How do I resize JComponents in GridLayout?

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 !

Whack A Mole Game

I am new to java and I am making a Whack a Mole game using a JFrame with JButtons. Currently, I have a 5x5 grid of buttons and that is as far as I got. I am having 3 of the buttons be X (to represent the mole) and 22 be O (to represent an empty hole). I would like for the buttons values to shuffle so that every 2 seconds the values are randomized. How might I go about doing this? Sorry for being such a novice, I literally started java a couple weeks back and JFrames still confuse me lol. Here is the code I currently have, thanks;
import javax.swing.*;
import java.awt.*;
public class Whack_A_Mole extends JFrame {
JButton[][] square = new JButton[5][5];
JButton button1, button2;
static JLabel label = new JLabel();
Whack_A_Mole() {
super("Whack a Mole");
JPanel p = new JPanel(new GridLayout(5,5));
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
square[i][j] = new JButton();
p.add(square[i][j]);
}
}
add(p, BorderLayout.CENTER);
p = new JPanel(new GridLayout(1,2));
setSize(600, 600);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Whack_A_Mole();
}
}
If you put the objects in an ArrayList, you can use the shuffle() method to shuffle their order. As to timing, either use Thread.sleep(millisecondsAmt) or a Timer. I prefer the util.Timer, especially when the action repeats indefinitely or for many repetitions.
Create a thread that will add update function into queue every 2 seconds.
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.util.Random;
public class Wack_A_Mole extends JFrame {
JButton[][] square = new JButton[5][5];
JButton button1, button2;
static JLabel label = new JLabel();
private Thread updateWoker;
Whack_A_Mole() {
super("Whack a Mole");
JPanel p = new JPanel(new GridLayout(5,5));
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
square[i][j] = new JButton();
p.add(square[i][j]);
}
}
add(p, BorderLayout.CENTER);
p = new JPanel(new GridLayout(1,2));
setSize(600, 600);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
}
void start(){
updateWoker=new Thread(new Runnable(){
public void run(){
Runnable r=new Runnable(){
public void run() {
buttonUpdate(); // call buttonUpdate every two seconds
}
};
while (true){
javax.swing.SwingUtilities.invokeLater(r);
try{Thread.sleep(2000);} catch (InterruptedException ex) {
return;
}
}
}
}
);
updateWoker.start();
}
public void buttonUpdate(){ // random update can be done in this function
Random r=new Random();
for(int i=0;i<square.length;i++){
for(int j=0;j<square[i].length;j++){
if(r.nextInt() %2==0)
square[i][j].setText("O");
else
square[i][j].setText("X");
}
}
}
public void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING) { // making sure to stop the thread after gui closes
if(updateWoker.isAlive()){
updateWoker.interrupt();
}
dispose();
}
}
public static void main(String[] args) throws InterruptedException {
final Whack_A_Mole theTest=new Whack_A_Mole();
theTest.start();
}
}

If statements and vertical buttons

I am making a fighting game and the player will choose its class. How do I say If (Player chooses Warrior) then (blah) with my code?
import java.awt.GridLayout;
import javax.swing.*;
public class ButtonTest {
static JDialog dialog;
public static void main(String[] args) {
JDialog dialog = null;
JOptionPane optionPane = new JOptionPane();
optionPane.setMessage("Choose Your Class!");
optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,1));
String[] buttonTxt = {"Warrior","Battlemage","Tank","Archer","Kitty"};
JButton[] buttons = new JButton[buttonTxt.length];
for (int i = 0; i < buttonTxt.length; i++)
{
buttons[i] = new JButton(buttonTxt[i]);
panel.add(buttons[i]);
}
optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
optionPane.add(panel);
dialog = optionPane.createDialog(null, "Icon/Text Button");
dialog.setVisible(true);
}
}
You can use actionperformed event for all the buttons.
for (int i = 0; i < buttonTxt.length; i++){
buttons[i] = new JButton(buttonTxt[i]);
buttons[i].addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
onClickButton(buttonTxt[i]);
}
});
panel.add(buttons[i]);
}
Make buttonTxt a final variable.
Then you can write your if statement inside onClickButton()
private void onClickButton(String buttonText){
if(buttonText.equals("Warrior")){
//do your stuff
}
}

Why does this code have the error: NullPointerException?

This code is part of a Tic Tac Toe program that I'm making with Java Swing. Why does it return NullPointerException when the for statement to add the buttons is added?
import java.awt.*;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TicTacToeGui extends JFrame
{
public final static int r = 3;
public final static int c = 3;
TicTacToeGui()
{
JButton[][] button = new JButton[3][3];
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(r, c));
JLabel label = new JLabel("This is a tic tac toe game.");
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
panel.add(button[i][j]);
}
}
this.add(label);
this.add(panel);
this.setSize(400, 400);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String [] args)
{
new TicTacToeGui();
}
}
You never initialize any JButton. When you declare
JButton[][] button = new JButton[3][3];
It just creates an empty 3x3 array of null, and you have to manually go through each spot in your array of arrays and initialize with
button[row][col] = new JButton("");
because button[0][0] is null. You initialize the array but none of the elements in it.
The line JButton[][] button = new JButton[3][3]; doesn't actually initialize the buttons. You need to create new buttons and stick them in here.

Categories

Resources