Java swing, out of scope variable and usage of buttons - java

I am trying to make an actionlistener, for the buttons I have created and display each one a textfield much like a calculator upon each entry of a number.
However under the actionPerformed method, it seems like button1 and all of them seem to be out of scope, I can't declare a button static now can I?
I need to overcome the out of scope issue any takers?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import layout.TableLayout;
public class example extends JFrame implements ActionListener
{
public static void main (String args[])
{
new example();
}
public example ()
{
super("The Power of Preferred Sizes");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = getContentPane();
double size[][] = {{75, 75, 75, 75, 75}, // Columns
{75, 75, 75, 75, 75,75}}; // Rows
pane.setLayout(new TableLayout(size));
TableLayout layout = new TableLayout(size);
pane.setLayout (layout);
// Create all controls
String label[] = {"1", "2", "3", "4", "5","6","7", "8","9","0","PLS","RES"};
JButton button[] = new JButton[label.length];
JTextField upperText = new JTextField();
JTextField bottomText = new JTextField();
// textfieldName.setSize(10, 10);
pane.add(upperText, "0, 0, 4, 0");
pane.add(bottomText, "0, 5, 4, 0");
JButton button1 = new JButton(label[0]);
JButton button2 = new JButton(label[1]);
JButton button3 = new JButton(label[2]);
JButton button4 = new JButton(label[3]);
JButton button5 = new JButton(label[4]);
JButton button6 = new JButton(label[5]);
JButton button7 = new JButton(label[6]);
JButton button8 = new JButton(label[7]);
JButton button9 = new JButton(label[8]);
JButton button10 = new JButton(label[9]);
JButton button11= new JButton(label[10]);
JButton button12 = new JButton(label[11]);
pane.add(button1, "1,1");//1
pane.add(button2, "2,1");//2
pane.add(button3, "3,1");//3
pane.add(button4, "1,2");//
pane.add(button5, "2,2");
pane.add(button6, "3,2");
pane.add(button7, "1,3");
pane.add(button8, "2,3");
pane.add(button9, "3,3");
pane.add(button10, "1,4");
pane.add(button11, "2,4");
pane.add(button12, "3,4");
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
button4.addActionListener(this);
button5.addActionListener(this);
button6.addActionListener(this);
button7.addActionListener(this);
button8.addActionListener(this);
button9.addActionListener(this);
button10.addActionListener(this);
button11.addActionListener(this);
button12.addActionListener(this);
pack();
setResizable(false);
show();
}
public void actionPerformed(ActionEvent e) {
//code that reacts to the action...
Object source = e.getSource();
if(source == button1){
upperText.append("1");
}
}
}

You can declare them as class fields, so they will be accessible within the whole class:
public class example extends JFrame implements ActionListener {
JButton button1;
JButton button2;
JButton button3;
JButton button4;
JButton button5;
JButton button6;
JButton button7;
JButton button8;
JButton button9;
JButton button10:
JButton button11;
JButton button12;
// Constructor
// Methods
}
Also you should consider using an array to hold the 12 buttons.

Related

Can I use a for loop to create objects in java?

Can I initialize multiple objects in a single loop?
Here's what a snippet of my code looks like. As you can see, it becomes hard to look at from a glance and takes up too much space.
I'd like to be able to create the buttons in one for loop and then modify in another for loop.
public class MyFrame extends JFrame {
MyFrame() {
JButton button1 = new JButton();
JButton button2 = new JButton();
JButton button3 = new JButton();
JButton button4 = new JButton();
JButton button5 = new JButton();
JButton button6 = new JButton();
JButton button7 = new JButton();
JButton button8 = new JButton();
JButton button9 = new JButton();
JButton button0 = new JButton();
button1.setBounds(60, 60, 50, 50);
button2.setBounds(120,60,50,50);
button3.setBounds(180,60,50,50);
button4.setBounds(60,120,50,50);
button5.setBounds(120,120,50,50);
button6.setBounds(180,120,50,50);
button7.setBounds(60,180,50,50);
button8.setBounds(120,180,50,50);
button9.setBounds(180,180,50,50);
button0.setBounds(120,240,50,50);
}
}
Yes, you can use a for loop to create the buttons.
Here's a GUI I created.
It's not a good idea to use absolute positioning (setBounds) when creating a GUI. You should use the Swing layout managers.
I used a GridLayout to position the buttons.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TenButtonGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new TenButtonGUI());
}
#Override
public void run() {
JFrame frame = new JFrame("Ten Button GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(0, 3, 5, 5));
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
for (int i = 0; i < 11; i++) {
if (i == 9) {
JLabel label = new JLabel(" ");
panel.add(label);
} else {
JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 50));
panel.add(button);
}
}
return panel;
}
}
You could do something like this:
List<JButton> buttons = new ArrayList<>();
int[][] bounds = {{60, 60, 50, 50}, {120,60,50,50}}; //add more bound quadruplets
// iterating over the values in the bounds array
Arrays.asList(bounds).forEach(v -> {
JButton button = new JButton();
button.setBounds(v[0], v[1], v[2], v[3]);
buttons.add(button);
});
In the end you will find your buttons in the buttons List.

How to separate a JTextField from the rest of the GridLayout

I'm trying to make a calculator as a fun project. But as I try to make it look like a... calculator, it just turns out like one big grid, as follows:
I've tried to follow along with whatever I found on the Internet, but that was a big bust.
Can anyone help me out trying to separate the JTextField so it doesn't do this, and it can be in it's own row?
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame {
public Main() {
// Row = ->
// Column = ^
Container cp = getContentPane();
cp.setLayout(new GridLayout(3, 0));
JTextField txtCalc = new JTextField("0");
txtCalc.setHorizontalAlignment(SwingConstants.RIGHT);
JButton btn0 = new JButton("0");
JButton btn1 = new JButton("1");
JButton btn2 = new JButton("2");
JButton btn3 = new JButton("3");
JButton btn4 = new JButton("4");
JButton btn5 = new JButton("5");
JButton btn6 = new JButton("6");
JButton btn7 = new JButton("7");
JButton btn8 = new JButton("8");
JButton btn9 = new JButton("9");
JButton btn10 = new JButton("10");
cp.add(txtCalc);
cp.add(btn0);
cp.add(btn1);
cp.add(btn2);
cp.add(btn3);
cp.add(btn4);
cp.add(btn5);
cp.add(btn6);
cp.add(btn7);
cp.add(btn8);
cp.add(btn9);
cp.add(btn10);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Calculator");
setSize(600, 600);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::new);
}
}
Edit:
Now I have the answer! This is my fixed code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame {
public Main() {
Container cp = getContentPane();
cp.setLayout(new GridLayout(3, 0));
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel(new GridLayout(3, 0));
setContentPane(border);
JTextField txtCalc = new JTextField("0");
txtCalc.setHorizontalAlignment(SwingConstants.RIGHT);
txtCalc.setEditable(true);
JButton btn1 = new JButton("1");
JButton btn2 = new JButton("2");
JButton btn3 = new JButton("3");
JButton btn4 = new JButton("4");
JButton btn5 = new JButton("5");
JButton btn6 = new JButton("6");
JButton btn7 = new JButton("7");
JButton btn8 = new JButton("8");
JButton btn9 = new JButton("9");
JButton btn0 = new JButton("0");
mainPanel.add(buttonPanel, BorderLayout.CENTER);
mainPanel.add(txtCalc, BorderLayout.NORTH);
buttonPanel.add(btn1);
buttonPanel.add(btn2);
buttonPanel.add(btn3);
buttonPanel.add(btn4);
buttonPanel.add(btn5);
buttonPanel.add(btn6);
buttonPanel.add(btn7);
buttonPanel.add(btn8);
buttonPanel.add(btn9);
buttonPanel.add(btn0);
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::new);
}
}
Have your main panel use a BorderLayout. Put the JTextField in the North position. Put your buttons in a panel that uses GridLayout, then add that panel to your main panel in the Center position.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame {
public Main() {
JPanel mainPanel = new JPanel(new BorderLayout());
setContentPane(mainPanel);
JTextField txtCalc = new JTextField("0");
txtCalc.setHorizontalAlignment(SwingConstants.RIGHT);
JPanel buttonPanel = new JPanel(new GridLayout(3, 0));
JButton btn0 = new JButton("0");
JButton btn1 = new JButton("1");
JButton btn2 = new JButton("2");
JButton btn3 = new JButton("3");
JButton btn4 = new JButton("4");
JButton btn5 = new JButton("5");
JButton btn6 = new JButton("6");
JButton btn7 = new JButton("7");
JButton btn8 = new JButton("8");
JButton btn9 = new JButton("9");
buttonPanel.add(txtCalc);
buttonPanel.add(btn0);
buttonPanel.add(btn1);
buttonPanel.add(btn2);
buttonPanel.add(btn3);
buttonPanel.add(btn4);
buttonPanel.add(btn5);
buttonPanel.add(btn6);
buttonPanel.add(btn7);
buttonPanel.add(btn8);
buttonPanel.add(btn9);
mainPanel.add(txtCalc, BorderLayout.NORTH);
mainPanel.add(buttonPanel, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Calculator");
setSize(600, 600);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::new);
}
}

No Components are showing up on JFrame GUI

I'm fairly new to Swing and GUIs, and so far, only the window will appear, but none of the components will be visible. What can I do about this? Is there something wrong with the visibility or is it with a container?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class PhoneCaller
{
JButton button1;
JButton button2;
JButton button3;
JButton button4;
JButton button5;
JButton button6;
JButton button7;
JButton button8;
JButton button9;
JButton buttonDash;
JButton button0;
JButton dialButton;
String phoneNum = "";
public static void main (String[] args)
{
new PhoneCaller();
}
public PhoneCaller()
{
JFrame myFrame = new JFrame();
myFrame.setTitle("Dialer");
myFrame.setSize(200, 250);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel myPanel = new JPanel(new BorderLayout(10,10));
myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.Y_AXIS));
myFrame.add(myPanel);
JPanel myPanel2 = new JPanel();
myPanel2.setLayout(new FlowLayout());
JLabel lab = new JLabel("Enter the number to dial");
myPanel2.add(lab);
JPanel myPanel3 = new JPanel();
myPanel3.setLayout(new GridLayout(4,3,5,5));
button1 = new JButton ("1");
myPanel3.add(button1);
button2 = new JButton ("2");
myPanel3.add(button2);
button3 = new JButton ("3");
myPanel3.add(button3);
button4 = new JButton ("4");
button5 = new JButton ("5");
button6 = new JButton ("6");
button7 = new JButton ("7");
button8 = new JButton ("8");
button9 = new JButton ("9");
button0 = new JButton ("0");
buttonDash = new JButton ("-");
myPanel3.add(button4);
myPanel3.add(button5);
myPanel3.add(button6);
myPanel3.add(button7);
myPanel3.add(button8);
myPanel3.add(button9);
myPanel3.add(button0);
myPanel3.add(buttonDash);
myFrame.setVisible(true);
}
}
I think you forgot to add myPanel2 and myPanel3 inside myPanel.
myPanel.add(myPanel2);
myPanel.add(myPanel3);
You forgot to add myPanel2 and myPanel3 to your JFrame, add the following snippet to the end of your code
myFrame.add(myPanel2);
myFrame.add(myPanel3);

Setting functions to individual buttons

I have a soundboard program I am designing for school. I'm actually permitted to write whatever program that I want. I have a code written for it, as shown here:
package soundboard;
import javax.swing.*;
import java.awt.event.*;
public class Soundboard implements ActionListener{
JButton loadButton;
JButton clearButton;
JButton Button1;
JButton Button2;
JButton Button3;
JButton Button4;
JPanel mainsPanel;
int load;
public void windowCreate() {
JFrame frame = new JFrame();
mainsPanel = new JPanel();
loadButton = new JButton("Load...");
loadButton.setSize(80, 30);
loadButton.setLocation(4, 4);
loadButton.addActionListener(this);
clearButton = new JButton("Clear");
clearButton.setSize(80, 30);
clearButton.setLocation(92, 4);
clearButton.addActionListener(this);
Button1 = new JButton("1");
Button1.setSize(80, 80);
Button1.setLocation(4, 45);
Button1.addActionListener(this);
Button2 = new JButton("2");
Button2.setSize(80, 80);
Button2.setLocation(92, 45);
Button2.addActionListener(this);
Button3 = new JButton("3");
Button3.setSize(80, 80);
Button3.setLocation(4, 133);
Button3.addActionListener(this);
Button4 = new JButton("4");
Button4.setSize(80, 80);
Button4.setLocation(92, 133);
Button4.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(loadButton);
frame.add(clearButton);
frame.add(Button1);
frame.add(Button2);
frame.add(Button3);
frame.add(Button4);
frame.add(mainsPanel);
frame.setSize(183,245);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent event){
load += 1;
System.out.println(load);
}
public static void main(String[] args){
Soundboard window = new Soundboard();
window.windowCreate();
}
}
In this example, every single button does the exact same thing. How, using this base code, ca I set it so the buttons do their own individual thing? I plan on designing it so hitting the "load" button and then a number-button loads a sound to that said button. Hitting a number-button without hitting load first plays the previously designated sound. Hitting "clear" unloads all buttons.
Instead of
ButtonX.addActionListener(this);
write
ButtonX.addActionListener(e -> {
//do stuff here
});
The -> signifies that this is a lambda expression, which basically creates an anonymous class from a functional interface and passes it as an argument. For more on lambda expressions, you can read my guide here, or the official (but long) tutorial here.
After you make all the lambda expressions, you can remove the
#Override
public void actionPerformed(ActionEvent event){
load += 1;
System.out.println(load);
}
and
implements ActionListener
from your class.
You need to attach different action performed to seperate button an e.g. on how to do it is below for load and clear button
import javax.swing.*;
import java.awt.event.*;
public class Soundboard implements ActionListener{
JButton loadButton;
JButton clearButton;
JButton Button1;
JButton Button2;
JButton Button3;
JButton Button4;
JPanel mainsPanel;
int load;
public void windowCreate() {
JFrame frame = new JFrame();
mainsPanel = new JPanel();
loadButton = new JButton("Load...");
loadButton.setSize(80, 30);
loadButton.setLocation(4, 4);
loadButton.addActionListener(e -> System.out.println("load action"));
clearButton = new JButton("Clear");
clearButton.setSize(80, 30);
clearButton.setLocation(92, 4);
clearButton.addActionListener(e -> System.out.println("Clear action"));
Button1 = new JButton("1");
Button1.setSize(80, 80);
Button1.setLocation(4, 45);
Button1.addActionListener(this);
Button2 = new JButton("2");
Button2.setSize(80, 80);
Button2.setLocation(92, 45);
Button2.addActionListener(this);
Button3 = new JButton("3");
Button3.setSize(80, 80);
Button3.setLocation(4, 133);
Button3.addActionListener(this);
Button4 = new JButton("4");
Button4.setSize(80, 80);
Button4.setLocation(92, 133);
Button4.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(loadButton);
frame.add(clearButton);
frame.add(Button1);
frame.add(Button2);
frame.add(Button3);
frame.add(Button4);
frame.add(mainsPanel);
frame.setSize(183,245);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent event){
load += 1;
System.out.println(load);
}
public static void main(String[] args){
Soundboard window = new Soundboard();
window.windowCreate();
}
}

Working with ActionListeners and cannot set text field to not visible

I'm just trying to make a text field not visible until I click one of the numbered buttons. Ignore my poor spacing and lack of commenting as this is an early, rough draft. The text field is called inputField1 and I want it to be set Visible when I click the button labeled 1. Thanks
import java.lang.String.*;
import java.lang.Exception.*;
import java.util.EventObject;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Airplanes extends JFrame implements ActionListener {
private static final int FRAME_WIDTH = 330;
private static final int FRAME_HEIGHT = 300;
private static final int FRAME_X_ORIGIN = 150;
private static final int FRAME_Y_ORIGIN = 300;
private static final int BUTTON_WIDTH = 50;
private static final int BUTTON_HEIGHT = 30;
private JTextField inputLine1;
private JButton oneButton;
private JButton twoButton;
private JButton threeButton;
private JButton fourButton;
private JButton fiveButton;
private JButton sixButton;
private JButton sevenButton;
private JButton eightButton;
private JButton nineButton;
private JButton tenButton;
private JButton elevenButton;
private JButton twelveButton;
public static void main(String[] args) {
Airplanes airplanes = new Airplanes();
airplanes.setVisible(true);
}
#SuppressWarnings("null")
public Airplanes() {
Container contentPane;
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setResizable(false);
setTitle("Island Airways");
setLocation(FRAME_X_ORIGIN, FRAME_Y_ORIGIN);
contentPane = getContentPane();
contentPane.setLayout(null);
contentPane.setBackground(Color.white);
oneButton = new JButton("1");
oneButton.setBounds(10, 100, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(oneButton);
twoButton = new JButton("2");
twoButton.setBounds(10, 140, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(twoButton);
threeButton = new JButton("3");
threeButton.setBounds(60, 100, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(threeButton);
fourButton = new JButton("4");
fourButton.setBounds(60, 140, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(fourButton);
fiveButton = new JButton("5");
fiveButton.setBounds(110, 100, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(fiveButton);
sixButton = new JButton("6");
sixButton.setBounds(110, 140, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(sixButton);
sevenButton = new JButton("7");
sevenButton.setBounds(160, 100, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(sevenButton);
eightButton = new JButton("8");
eightButton.setBounds(160, 140, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(eightButton);
nineButton = new JButton("9");
nineButton.setBounds(210, 100, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(nineButton);
tenButton = new JButton("10");
tenButton.setBounds(210, 140, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(tenButton);
elevenButton = new JButton("11");
elevenButton.setBounds(260, 100, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(elevenButton);
JButton twelveButton = new JButton("12");
twelveButton.setBounds(260, 140, BUTTON_WIDTH, BUTTON_HEIGHT);
contentPane.add(twelveButton);
JButton firstClass = new JButton("First Class");
firstClass.setBounds(50, 30, 100, 30);
contentPane.add(firstClass);
JButton coach = new JButton("Coach");
coach.setBounds(175, 30, 100, 30);
contentPane.add(coach);
inputLine1 = new JTextField();
inputLine1.setBounds(70, 200, 135, 30);
contentPane.add(inputLine1);
inputLine1.setVisible(false);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() instanceof JButton) {
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("First Class")) {
inputLine1.setVisible(true);
if (buttonText.equals("1")) {
}
}
}
}
}
You have implemented ActionListener but your buttons are not attached to any Listener, hence its not invoking your actionPerformed method.
You need to do add listners to your buttons like this:
oneButton.addActionListener(this);
Then change your actionPerfomed like:
public void actionPerformed(ActionEvent event) {
if (event.getSource() instanceof JButton) {
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("First Class")) {
//do something
} else if (buttonText.equals("1")) {
inputLine1.setVisible(true);
}
}
}
Read this tutorial
When you are implementing ActionListener
you have to implement it's methods
you have to add that listener to a particular component you want.
You forgot to do second one.
oneButton.addActionListener(this);
you add the following code to your actionPerformed method.
if (buttonText.equals("1")) {
inputLine1.setVisible(true);
}

Categories