Weird speed bug in my Java Calculator program - java

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.

Related

Having selected JButton from a 2d array perform an action

I have a 2 dimensional array of JButtons, and I would like to be able to have the button that my mouse is over to perform an action, such as change color. How can I do this? Thanks.
Here is how I am creating the buttons:
for(int r = 0;r<10;r++){
for(int c = 0;c<10;c++){
buttonArray[r][c] = new JButton();
}
}
Here is an example using a loop and a MouseAdapter (since you don't need all the methods from MouseListener ) :
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JButtonHighlighter extends JPanel {
public static void main(final String[] args) {
JFrame frame = new JFrame();
JPanel contentPanel = new JPanel();
contentPanel.setLayout(new GridLayout(10, 10));
JButton[][] buttonArray = new JButton[10][10];
for (int r = 0; r < 10; r++) {
for (int c = 0; c < 10; c++) {
final JButton newButton = new JButton();
final Color originalColor = newButton.getBackground();
final Color highlightColor = Color.GREEN;
newButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(final MouseEvent e) {
newButton.setBackground(highlightColor);
}
#Override
public void mouseExited(final MouseEvent e) {
newButton.setBackground(originalColor);
}
});
buttonArray[r][c] = newButton;
contentPanel.add(newButton);
}
}
frame.setContentPane(contentPanel);
frame.setSize(100, 100);
frame.setVisible(true);
}
}

automated buttons implementation in 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.

Filling Frame with Buttons Using GridBagLayout

I am trying to build a matching game with icons attached to each button. Although, this isn't close to being finished, I have a problem with filling the panel with buttons.
With this code I get a grey colored frame. If i comment out the 3 methods i use under "//execution" the panel will be all black (which is how i am testing to see if the buttons are filling the space or not.)
For some reaso,n my buttons aren't being populated onto the panel.
I need some help!!! Where am I going wrong?
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MemoryMainFrame extends JFrame implements ActionListener {
JButton button[] = new JButton[16];
private static final int SIXTEEN_BUTTONS = 16;
JPanel mainPanel = new JPanel();
double dim = Math.sqrt(SIXTEEN_BUTTONS);
int numOfColumns = (int) (dim);
int numOfRows = (int) (dim);
public static void main(String[] args) {
new MemoryMainFrame();
}
public MemoryMainFrame() {
this.setTitle("MemoryGame!!!");
this.setSize(400, 400);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
mainPanel.setBackground(Color.BLACK);
mainPanel.setLayout(new GridBagLayout());
// execution
FillButtonArray(SIXTEEN_BUTTONS);
AddButtonListener(SIXTEEN_BUTTONS);
ButtonToPanel(SIXTEEN_BUTTONS);
this.add(mainPanel);
}
public void FillButtonArray(int numOfButtons) {
int i = 0;
while (i < numOfButtons) {
button[i] = new JButton("asdf");
}
}
public void AddButtonListener(int numOfButtons) {
int i = 0;
while (i < numOfButtons) {
button[i].addActionListener(this);
}
}
public void ButtonToPanel(int numOfButtons) {
int n = 0;
GridBagConstraints gbc = new GridBagConstraints();
for (int i = 0; i < numOfColumns; i++) {
for (int j = 0; j < numOfRows; j++) {
gbc.gridx = i;
gbc.gridy = j;
n++;
button[n].setBorder(BorderFactory.createLineBorder(
Color.DARK_GRAY, 2));
mainPanel.add(button[n]);
}
}
}
public void actionPerformed(ActionEvent arg0) {
JFrame j = new JFrame();
j.setSize(300, 300);
j.setVisible(true);
}
}
I use the "asdf" as a test to see if the buttons work as well.
also, the actionperformed was a test as well. That part of the code is irrelevant.
You're creating your GridBagConstraints but you're not using them.
Change this:
mainPanel.add(button[n]);
to this:
// passes both the component and the GBC into the container
mainPanel.add(button[n], gbc);
Edit
You've also got a never-ending loop here:
while (i < numOfButtons) {
button[i] = new JButton("asdf");
}
and likewise for the AddButtonListener(...) method.
You'll want to fix this by using either a for loop or else changing i within the loop.
Also per Andrew Thompson's comment, you're setting the JFrame visible too early, before all components have been added.
Also your use of Math.sqrt then casting the result to int is very risky and risks getting unexpected results. Just declare the side length to 8 and square the int if you need to.
For an example of GridBagLayout, please check out:
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial") // avoid extending JFrame if possible
public class MemoryMainPanel extends JPanel {
private static final int ROWS = 8;
private static final Color BACKGROUND = Color.black;
private static final int I_GAP = 5;
private static final Insets BTN_INSETS = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
private JButton[][] buttons = new JButton[ROWS][ROWS];
public MemoryMainPanel() {
setBackground(BACKGROUND);
setLayout(new GridBagLayout());
for (int row = 0; row < buttons.length; row++) {
for (int col = 0; col < buttons[row].length; col++) {
JButton btn = new JButton(new ButtonAction(row, col));
add(btn, createGbc(row, col));
buttons[row][col] = btn;
}
}
}
private GridBagConstraints createGbc(int y, int x) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = BTN_INSETS;
return gbc;
}
private class ButtonAction extends AbstractAction {
private int row;
private int col;
public ButtonAction(int row, int col) {
super("asdf");
this.row = row;
this.col = col;
}
#Override
public void actionPerformed(ActionEvent e) {
String text = String.format("Column, Row: [%d, %d]", col + 1, row + 1);
Component parentComponent = MemoryMainPanel.this;
String message = text;
String title = "Button Pressed";
int messageType = JOptionPane.PLAIN_MESSAGE;
Icon icon = null;
JOptionPane.showMessageDialog(parentComponent, message, title, messageType, icon);
}
}
private static void createAndShowGui() {
MemoryMainPanel mainPanel = new MemoryMainPanel();
JFrame frame = new JFrame("MemoryMainPanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

How do I create an on screen keyboard in java?

I'm working on a school project where we have to create a virtual smartphone, to run on a computer.
My problem is that I need to create a keyboard on the screen (like on an smartphone), which you can then use by clicking with your mouse. I could just create every single JButton, but that will take a really long time. So I was hopping that someone knew some sort of algorithm that creates all the buttons and places them correctly on the screen.
Thank you in advance :)
You could construct the buttons through the use of for loops. One loop for every keyboard row is a plausible approach.
String row1 = "1234567890";
String row2 = "qwertyuiop";
// and so forth
String[] rows = { row1, row2, .. };
for (int i = 0; i < rows.length; i++) {
char[] keys = rows[i].toCharArray();
for (int j = 0; i < keys.length; j++) {
JButton button = new JButton(Character.toString(keys[j]));
// add button
}
}
// add special buttons like space bar
This could be done more elegantly through a more OOP approach, but this basic loop system will work.
This simple example might help you:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class MainFrame extends JFrame
{
private JTextField txt;
private PopUpKeyboard keyboard;
public MainFrame()
{
super("pop-up keyboard");
setDefaultCloseOperation(EXIT_ON_CLOSE);
txt = new JTextField(20);
keyboard = new PopUpKeyboard(txt);
txt.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
Point p = txt.getLocationOnScreen();
p.y += 30;
keyboard.setLocation(p);
keyboard.setVisible(true);
}
});
setLayout(new FlowLayout());
add(txt);
pack();
setLocationByPlatform(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MainFrame().setVisible(true);
}
});
}
private class PopUpKeyboard extends JDialog implements ActionListener
{
private JTextField txt;
public PopUpKeyboard(JTextField txt)
{
this.txt = txt;
setLayout(new GridLayout(3, 3));
for(int i = 1; i <= 9; i++) createButton(Integer.toString(i));
pack();
}
private void createButton(String label)
{
JButton btn = new JButton(label);
btn.addActionListener(this);
btn.setFocusPainted(false);
btn.setPreferredSize(new Dimension(100, 100));
Font font = btn.getFont();
float size = font.getSize() + 15.0f;
btn.setFont(font.deriveFont(size));
add(btn);
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
txt.setText(txt.getText() + actionCommand);
}
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String alphabet = "abcdefghijklmnopqrstuvwxyz";
JFrame myFrame = new JFrame();
JPanel myPanel = new JPanel();
for (int i = 0; i < alphabet.length(); i++) {
myPanel.add(new JButton(alphabet.substring(i, i + 1)));
}
myFrame.add(myPanel);
myFrame.pack();
myFrame.setVisible(true);
}
This is a fast example of how to do it :).

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