I am making a tic tac toe game in Java and made the gui and wanted to run it to test it but am getting a few errors. I am not sure why and was hoping that someone could explain why those errors are coming up and what i should do to fix them. The errors that I am getting are as follows: Exception in thread "main" java.lang.NullPointerException
at TicTacToeSwing.(TicTacToeSwing.java:84)
at TicTacToeSwing.main(TicTacToeSwing.java:180)
Here is my code: (please note: I have not done the calculations yet because I wanted to get the gui going first) If you know of a better practice that I should consider doing, by all means, let me know.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//Tic Tac Toe
public class TicTacToeSwing extends JFrame
implements ActionListener {
//JButtons
//private JButton button1 = new JButton("");
private JButton jbtnTicTacToe1;
private JButton jbtnTicTacToe2;
private JButton jbtnTicTacToe3;
private JButton jbtnTicTacToe4;
private JButton jbtnTicTacToe5;
private JButton jbtnTicTacToe6;
private JButton jbtnTicTacToe7;
private JButton jbtnTicTacToe8;
private JButton jbtnTicTacToe9;
private JButton jbtnExit;
private JButton jbtnReset;
//JFrame window = new JFrame("Tic-Tac-Toe Swing ");
private JFrame window = new JFrame("Tic-Tac-Toe");
//labels
private JLabel jlblPlayerX = new JLabel ("X");
private JLabel jlblPlayerO = new JLabel ("O");
//text fields
JTextField jtfName = new JTextField(20);
private JTextField jtfPlayerX = new JTextField("X");
private JTextField jtfPlayerO = new JTextField("O");
//Panels
JPanel jpnlMain = new JPanel ();
JPanel jpnlFamily = new JPanel();
JPanel jpnlNorth = new JPanel();
JPanel jpnlSouth = new JPanel();
JPanel jpnlCenter = new JPanel();
JPanel jpnlTop = new JPanel();
JPanel jpnlBottom = new JPanel();
//Class Constructor
public TicTacToeSwing () {
//Prepare JFrame/Window
super ("Tic Tac Toe");
setSize(400,400);
setTitle("Tic Tac Toe Swing");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set the layouts for 3 rows and 3 columns
jpnlMain.setLayout(new BorderLayout(3,3));
jpnlCenter.setLayout(new GridLayout());
jpnlSouth.setLayout(new GridLayout());
jpnlTop.setLayout(new BorderLayout());
jpnlBottom.setLayout(new BorderLayout());
//Center Panel
jpnlCenter.add(jlblPlayerX);
jpnlCenter.add(jlblPlayerO);
//identify each JButton
jbtnReset.setActionCommand("Reset");
jbtnExit.setActionCommand("Exit");
//register JButton for event handling by using the THIS keyword - THIS class will handle the events
jbtnReset.addActionListener(this);
jbtnExit.addActionListener(this);
/*Add Buttons To The Window*/
window.add(jbtnTicTacToe1);
window.add(jbtnTicTacToe2);
window.add(jbtnTicTacToe3);
window.add(jbtnTicTacToe4);
window.add(jbtnTicTacToe5);
window.add(jbtnTicTacToe6);
window.add(jbtnTicTacToe7);
window.add(jbtnTicTacToe8);
window.add(jbtnTicTacToe9);
/*Add The Action Listener To The Buttons
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);
*/
jbtnTicTacToe1.addActionListener(this);
jbtnTicTacToe2.addActionListener(this);
jbtnTicTacToe3.addActionListener(this);
jbtnTicTacToe4.addActionListener(this);
jbtnTicTacToe5.addActionListener(this);
jbtnTicTacToe6.addActionListener(this);
jbtnTicTacToe7.addActionListener(this);
jbtnTicTacToe8.addActionListener(this);
jbtnTicTacToe9.addActionListener(this);
//South Button Panel
jpnlSouth.add(jbtnReset);
jpnlSouth.add(jbtnExit);
/* Instantiate JButtons, put into a method for efficiency
jbtn1 = instantiateJButton("1", Color.PINK);
jbtn2 = instantiateJButton("2", Color.PINK);
jbtn3 = instantiateJButton("3", Color.PINK);
jbtn4 = instantiateJButton("4", Color.PINK);
jbtn5 = instantiateJButton("5", Color.PINK);
jbtn6 = instantiateJButton("6", Color.PINK);
jbtn7 = instantiateJButton("7", Color.PINK);
jbtn8 = instantiateJButton("8", Color.PINK);
jbtn9 = instantiateJButton("9", Color.PINK);
*/
//Finalize screen layout and publish to the display
jpnlMain.add(jpnlCenter, BorderLayout.NORTH);
jpnlMain.add(jpnlSouth, BorderLayout.CENTER);
//Prepare the container
Container ca = getContentPane();
ca.setBackground (Color.LIGHT_GRAY);
ca.add(jpnlMain);
setContentPane (ca);
setVisible(true);
//end constructor
}
//CLASS EVENT HANDLER
public void actionPerformed(java.awt.event.ActionEvent e)
{
//find out which JButton was pressed by using the Action Command
String sActionCommand = e.getActionCommand();
//EXIT JButton
if (sActionCommand == "Exit")
{
System.exit(0);
}
//RESET JButton
else if (sActionCommand == "Reset")
{
jtfPlayerX.setText("");
jtfPlayerO.setText("");
}
} //end ACTIONPERFORMED (java.awt.event.ActionEvent e)
/**
* #param args
*/
public static void main(String[] args) {
//EXECUTION STARTING POINT
TicTacToeSwing TicTacToeSwing = new TicTacToeSwing();
//TicTacToeSwing TicTacToeObject = new TicTacToeSwing();
}//end main(String[] args)
}//end TicTacToeSwing class
The stacktrace has useful information about what is causing the NPE (jbtnReset which appears on line 84). Therefore you need to initialize jbtnReset:
JButton jbtnReset = new JButton("Reset");
In fact the same applys to all the jbtnTicTacToeX buttons as well as jbtnExit.
Side issues:
Use String#equals to compare String content. The == operator compares String content.
if (sActionCommand == "Exit") {
should be
if (sActionCommand.equals("Exit")) {
This checks the action command for any component with this String so you want to check the specific source object instead:
if (e.getSource() == jbtnExit) {
If you look at the stack trace, places like TicTacToeSwing.java:84 show you where the errors are occuring. TicTacToeSwing.java is the file, and :84 means line number 84.
Where you have:
private JButton jbtnExit;
private JButton jbtnReset;
Try:
private JButton jbtnExit = new JButton("Exit");
private JButton jbtnReset = new JButton("Reset");
Related
So, I'm brand spankin' new to programming, so thanks in advance for your help. I'm trying to put this base 2 to base 10/base 10 to base 2 calculator I have made into a GUI. For the life of me I can't figure out how to nicely format it. I'm trying to make it look like the following: The two radio buttons on top, the input textfield bellow those, the convert button bellow that, the output field bellow that, and the clear button bellow that. Any ideas on how I can accomplish this?
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.*;
#SuppressWarnings("serial")
public class GUI extends JFrame implements ActionListener
{
private JTextField input;
private JTextField output;
private JRadioButton base2Button;
private JRadioButton base10Button;
private JButton convert;
private JButton clear;
private Container canvas = getContentPane();
private Color GRAY;
public GUI()
{
this.setTitle("Base 10-2 calc");
this.setLayout(new FlowLayout(FlowLayout.LEFT));
//this.setLayout(new GridLayout(2,2));
base2Button = new JRadioButton( "Convert to base 2");
base10Button = new JRadioButton( "Convert to base 10");
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(base2Button);
radioGroup.add(base10Button);
JPanel radioButtonsPanel = new JPanel();
radioButtonsPanel.setLayout( new FlowLayout(FlowLayout.LEFT) );
radioButtonsPanel.add(base2Button);
radioButtonsPanel.add(base10Button);
canvas.add(radioButtonsPanel);
base2Button.setSelected( true );
base10Button.setSelected( true );
input = new JTextField(18);
//input = new JFormattedTextField(20);
canvas.add(input);
output = new JTextField(18);
//output = new JFormattedTextField(20);
canvas.add(output);
convert = new JButton("Convert!");
convert.addActionListener(this);
canvas.add(convert);
clear = new JButton("Clear");
clear.addActionListener(this);
canvas.add(clear);
output.setBackground(GRAY);
output.setEditable(false);
this.setSize(300, 200);
this.setVisible(true);
this.setLocation(99, 101);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
GUI app = new GUI();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
if(s.equals("Convert!"))
{
String numS = input.getText();
int numI = Integer.parseInt(numS);
if(base2Button.isSelected())
{
output.setText(Integer.toBinaryString(Integer.valueOf(numI)));
}
if(base10Button.isSelected())
{
output.setText("" + Integer.valueOf(numS,2));
}
}
if(s.equals("Clear"))
{
input.setText("");
output.setText("");
}
}
}
For a simple layout, you could use a GridLayout with one column and then use a bunch of child panels with FlowLayout which align the components based on the available space in a single row. If you want more control, I'd suggest learning about the GridBagLayout manager which is a more flexible version of GridLayout.
public class ExampleGUI {
public ExampleGUI() {
init();
}
private void init() {
JFrame frame = new JFrame();
// Set the frame's layout to a GridLayout with one column
frame.setLayout(new GridLayout(0, 1));
frame.setPreferredSize(new Dimension(300, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Child panels, each with FlowLayout(), which aligns the components
// in a single row, until there's no more space
JPanel radioButtonPanel = new JPanel(new FlowLayout());
JRadioButton button1 = new JRadioButton("Option 1");
JRadioButton button2 = new JRadioButton("Option 2");
radioButtonPanel.add(button1);
radioButtonPanel.add(button2);
JPanel inputPanel = new JPanel(new FlowLayout());
JLabel inputLabel = new JLabel("Input: ");
JTextField textField1 = new JTextField(15);
inputPanel.add(inputLabel);
inputPanel.add(textField1);
JPanel convertPanel = new JPanel(new FlowLayout());
JButton convertButton = new JButton("Convert");
convertPanel.add(convertButton);
JPanel outputPanel = new JPanel(new FlowLayout());
JLabel outputLabel = new JLabel("Output: ");
JTextField textField2 = new JTextField(15);
outputPanel.add(outputLabel);
outputPanel.add(textField2);
// Add the child panels to the frame, in order, which all get placed
// in a single column
frame.add(radioButtonPanel);
frame.add(inputPanel);
frame.add(convertPanel);
frame.add(outputPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
ExampleGUI example = new ExampleGUI();
}
}
The end result:
I am having trouble finding a way to invoke an action listener that returns the value of the button clicked in the text area at the bottom.
I made the buttons using a for loop and did not expressly give the buttons a name so I do not know how to reference them when trying to incorporate an ActionListener.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class buttoner implements ActionListener {
//JFrame
JFrame frame = new JFrame("Button Game");
//Make JPanels
JPanel panelLabel = new JPanel();
JPanel buttonGrid = new JPanel(new GridLayout(0,10));
JPanel bottomPanel = new JPanel();
//JLabel
private JLabel label1 = new JLabel("The Button Game");
public buttoner() {
//set layout
frame.setLayout(new BorderLayout());
frame.add(panelLabel, BorderLayout.NORTH);
frame.add(buttonGrid, BorderLayout.CENTER);
frame.add(bottomPanel, BorderLayout.SOUTH);
//Set stuff
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,700);
frame.setVisible(true);
//Change label color
label1.setForeground(Color.RED);
//add Label
panelLabel.add(label1);
//add Buttons
for (int i = 1; i <= 60; i++) {
String val = Integer.toString(i);
buttonGrid.add(new JButton(val));
}
//Add JText Area to bottom JPanel
String num = "value";
JTextArea jta = new JTextArea(num, 1, 1);
bottomPanel.add(jta);
frame.pack();
}
public static void main(String args[]){
buttoner gui = new buttoner();
}
public void actionPerformed(ActionEvent a) {
}
}
I created an action listener to put the value in the text area at the bottom of the GUI.
I fixed a few problems with your code.
In the main method, I called the SwingUtilities invokeLater method to put the Swing GUI on the Event Dispatch thread (EDT). Swing components must be created and updated on the EDT.
The name of a Java class must start with a capital letter.
It's safer to put your Swing components on a JPanel, rather than add them directly to a JFrame.
I separated the code that creates the JFrame from the code that creates the JPanels. It should be easier for any reader of your code, including yourself, to understand what's going on.
In the createMainPanel method, I grouped the code so that everything having to do with the buttonGrid JPanel, to take one instance, is in one place in the code.
I added the action listener to the code that creates the buttonGrid JPanel.
I wrote action listener code that updates the JTextArea with the left clicked button label.
Here's the corrected code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
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.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Buttoner implements ActionListener {
// JFrame
private JFrame frame = new JFrame("Button Game");
// Make JPanels
private JPanel panelLabel = new JPanel();
private JPanel buttonGrid = new JPanel(new GridLayout(0, 10));
private JPanel bottomPanel = new JPanel();
// JLabel
private JLabel label1 = new JLabel("The Button Game");
private JTextArea jta;
public Buttoner() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
// Change label color
label1.setForeground(Color.RED);
// add Label
panelLabel.add(label1);
panel.add(panelLabel, BorderLayout.NORTH);
// add Buttons
for (int i = 1; i <= 60; i++) {
String val = Integer.toString(i);
JButton button = new JButton(val);
button.addActionListener(this);
buttonGrid.add(button);
}
panel.add(buttonGrid, BorderLayout.CENTER);
// Add JText Area to bottom JPanel
String num = "value";
jta = new JTextArea(num, 1, 1);
jta.setEditable(false);
bottomPanel.add(jta);
panel.add(bottomPanel, BorderLayout.SOUTH);
return panel;
}
public static void main(String args[]) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new Buttoner();
}
};
SwingUtilities.invokeLater(runnable);
}
public void actionPerformed(ActionEvent a) {
JButton button = (JButton) a.getSource();
jta.setText(button.getText());
}
}
Try creating an array of buttons and add the newly created button to the array. See comments.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class buttoner implements ActionListener {
//JFrame
JFrame frame = new JFrame("Button Game");
//Make JPanels
JPanel panelLabel = new JPanel();
JPanel buttonGrid = new JPanel(new GridLayout(0,10));
JPanel bottomPanel = new JPanel();
//JLabel
private JLabel label1 = new JLabel("The Button Game");
private JButton buttons[] = new JButton[60]; //create an array of button for future reference
public buttoner() {
//set layout
frame.setLayout(new BorderLayout());
frame.add(panelLabel, BorderLayout.NORTH);
frame.add(buttonGrid, BorderLayout.CENTER);
frame.add(bottomPanel, BorderLayout.SOUTH);
//Set stuff
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,700);
frame.setVisible(true);
//Change label color
label1.setForeground(Color.RED);
//add Label
panelLabel.add(label1);
//add Buttons
for (int i = 1; i <= 60; i++) {
String val = Integer.toString(i);
JButton btn = new JButton(val);
btn.addActionListener(this); //add an actionListener right away
buttons[i] = btn; //add the button in the array for future reference
buttonGrid.add(btn);
}
//Add JText Area to bottom JPanel
String num = "value";
JTextArea jta = new JTextArea(num, 1, 1);
bottomPanel.add(jta);
frame.pack();
}
public static void main(String args[]){
buttoner gui = new buttoner();
}
public void actionPerformed(ActionEvent a) {
}
}
I have a multi-class project involving some basic Java GUI. I am to create a loan calculator using 10 classes (6 of which are JPanel subclasses, a calculation class, a CombinedPanels class, a LoanCalculatorGUI class which creates instances of the CombinedPanels class and calculation class, and a driver). I have to make a reset button in one of the JPanel subclasses (ActionButtons) change a private JLabel in a different JPanel subclass (PaymentInformation). Here is the ActionButtons class:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class ActionButtons extends JPanel{
private JButton calc, reset, exit;
private JPanel actionButtons;
public ActionButtons(){
PaymentInformation pi = new PaymentInformation();
actionButtons = new JPanel(new GridLayout(1, 3, 20, 20));
calc = new JButton("Calculate");
reset = new JButton("Reset");
exit = new JButton("Exit");
actionButtons.add(calc);
actionButtons.add(reset);
actionButtons.add(exit);
actionButtons.setBorder(BorderFactory.createTitledBorder("Action Buttons"));
//Add ActionListeners
calc.addActionListener(new ButtonListener());
reset.addActionListener(new ButtonListener());
exit.addActionListener(new ButtonListener());
}
public JPanel getGUI(){
return actionButtons;
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
PaymentInformation pi = new PaymentInformation();
if(e.getActionCommand().equals("Exit")){
System.exit(0);
}
if(e.getActionCommand().equals("Reset")){
pi.changeValues("0.0");
}
if(e.getActionCommand().equals("Calculate")){
//TODO DO CALCULATIONS
}
}
}
}
And the PaymentInformation class:
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class PaymentInformation extends JPanel{
//Declare variables
private JPanel payInfo;
private JLabel loanAmt, monthPay, totalPay, loanVal, monthVal, totalVal;
public PaymentInformation(){
//Give panel layout
payInfo = new JPanel(new GridLayout(3, 2));
//Give titles, set alignment
loanAmt = new JLabel("Total Loan Amount: $", JLabel.LEFT);
monthPay = new JLabel("Monthly Payment: $", JLabel.LEFT);
totalPay = new JLabel("Total Payment: $", JLabel.LEFT);
loanVal = new JLabel("5.0", JLabel.RIGHT);
monthVal = new JLabel("0.0", JLabel.RIGHT);
totalVal = new JLabel("0.0", JLabel.RIGHT);
//Add stuff to JPanel
payInfo.add(loanAmt);
payInfo.add(loanVal);
payInfo.add(monthPay);
payInfo.add(monthVal);
payInfo.add(totalPay);
payInfo.add(totalVal);
//Set border
payInfo.setBorder(BorderFactory.createTitledBorder("Payment Information"));
}
//Method to get the JPanel
public JPanel getGUI(){
return payInfo;
}
public void changeValues(String val){
loanVal.setText(val);
}
}
I'm trying to use the setValue method in PaymentInformation to change the text of the JLabel, but it stays the same (at "5.0") when the reset button is clicked. I'm not sure if this is needed, but the CombinedPanels class (takes all the JLabel subclasses and puts them into a JFrame) is here:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class CombinedPanels extends JFrame{
public CombinedPanels(){
setTitle("Auto Loan Calculator");
setSize(700,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel center = new JPanel(new GridLayout(2, 2, 20, 20));
//Add other classes to this layout
TitleBar tb = new TitleBar();
add(tb.getGUI(), BorderLayout.NORTH);
ActionButtons ab = new ActionButtons();
add(ab.getGUI(), BorderLayout.SOUTH);
//Add center JPanel to the center of BorderLayout
add(center, BorderLayout.CENTER);
//Continue with adding rest of classes to center JPanel
PaymentInformation pi = new PaymentInformation();
center.add(pi.getGUI());
LoanTerm lt = new LoanTerm();
center.add(lt.getGUI());
FinancingInformation fi = new FinancingInformation();
center.add(fi.getGUI());
PriceWithOptions pwo = new PriceWithOptions();
center.add(pwo.getGUI());
}
}
Lastly, here is an image of the GUI: .
It stays the same when reset is hit, even though the "5.0" JLabel should be changed to "0.0". The exit button, however, is functional.
Sorry for the wall of text, but this problem is driving me crazy. Any help or explanation is much appreciated. Thanks in advance.
You have 3 seperate instances of PaymentInformation. First one in the CombinedPanels class (the one that is displayed), one in the ActionButtons class and one in the ButtonListener class. You only change the values of the last one (which is invisible).
So one solution would be to pass the (visible) pi of the CombinedPanels class to the ActionButtons class and call changeValues() on that instance and on no other.
Relevant code (changed):
public CombinedPanels() {
setTitle("Auto Loan Calculator");
setSize(700, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel center = new JPanel(new GridLayout(2, 2, 20, 20));
// Add other classes to this layout
PaymentInformation pi = new PaymentInformation();
ActionButtons ab = new ActionButtons(pi);
add(ab.getGUI(), BorderLayout.SOUTH);
// Add center JPanel to the center of BorderLayout
add(center, BorderLayout.CENTER);
// Continue with adding rest of classes to center JPanel
center.add(pi.getGUI());
setVisible(true);
}
public class ActionButtons extends JPanel {
private JButton calc, reset, exit;
private JPanel actionButtons;
PaymentInformation pi;
public ActionButtons(PaymentInformation pi) {
this.pi = pi;
actionButtons = new JPanel(new GridLayout(1, 3, 20, 20));
calc = new JButton("Calculate");
reset = new JButton("Reset");
exit = new JButton("Exit");
actionButtons.add(calc);
actionButtons.add(reset);
actionButtons.add(exit);
actionButtons.setBorder(BorderFactory.createTitledBorder("Action Buttons"));
// Add ActionListeners
calc.addActionListener(new ButtonListener());
reset.addActionListener(new ButtonListener());
exit.addActionListener(new ButtonListener());
}
public JPanel getGUI() {
return actionButtons;
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Exit")) {
System.exit(0);
}
if (e.getActionCommand().equals("Reset")) {
pi.changeValues("0.0");
}
if (e.getActionCommand().equals("Calculate")) {
// TODO DO CALCULATIONS
}
}
}
}
Try this
public void changeValues(String val){
loanVal=new JLabel(val, JLabel.RIGHT);
}
I am trying to create a tic tac toe GUI that needs to be set up as follows:
1) The frame is a grid made of 2 panes, left pane with a 9 button grif that acts as the board
2) The right pane pane is divided into two more panes 1 below the other. Based on the symbol the user chooses using the radio buttons, a click on the gameboard must display either "X" or "O".
Since my mouse listener code is in a separate class I am not sure how I can get what the user clicked.
Here is my code. Please give me a nudge in the right direction to overcome this issue.
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package samples;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSplitPane;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
/**
*
* #author saikrishnan.srivat
*/
public class TicTacToe extends JFrame {
/*declare the components of the window*/
JPanel iconPanel;
JPanel tictactoeBoard;
JPanel emptyPanel;
JLabel chooseLabel;
JRadioButton xButton;
JRadioButton oButton;
ButtonGroup bg;
JButton resetButton;
JButton exitButton;
JButton undoButton;
JSplitPane rightPane;
JSplitPane pane;
MouseAdapterMod mam;
public TicTacToe() {
iconPanel = new JPanel();
tictactoeBoard = new JPanel();
emptyPanel = new JPanel();
chooseLabel = new JLabel("Choose your symbol :");
xButton = new JRadioButton("X");
oButton = new JRadioButton("O");
bg = new ButtonGroup();
bg.add(xButton);
bg.add(oButton);
/*add the label and the radio buttons too the empty panel*/
emptyPanel.add(chooseLabel);
emptyPanel.add(xButton);
emptyPanel.add(oButton);
emptyPanel.setLayout(new FlowLayout());
/*add the exit,undo and reset buttons to the icon panel*/
iconPanel.setLayout(new GridLayout(3, 1, 3, 3));
resetButton = new JButton("Reset");
exitButton = new JButton("Exit");
undoButton = new JButton("Undo Move");
iconPanel.add(resetButton);
iconPanel.add(exitButton);
iconPanel.add(undoButton);
/*Set layout of the tictactoe board and add the game buttons to it */
tictactoeBoard.setLayout(new GridLayout(3, 3));
/* Mouse adapter object that listens to the buttons in the tic tac toe board */
mam = new MouseAdapterMod();
for (int i = 0; i < 9; i++) {
JButton button = new JButton("");
button.addMouseListener(mam);
tictactoeBoard.add(button);
}
/*add the icon panel and the empty panel to the right pane*/
rightPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, iconPanel, emptyPanel);
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tictactoeBoard, rightPane);
add(pane);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
//setMaximumSize(new Dimension(500, 500));
setMinimumSize(new Dimension(700, 500));
setLocationRelativeTo(null);
pack();
setTitle("Tic Tac Toe");
setLocationRelativeTo(null);
setVisible(true);
}
}
class MouseAdapterMod extends MouseAdapter {
/*Set 'X' or 'O' based the selected radio button- how to achieve this? */
public void mousePressed(MouseEvent e) {
//JButton button = (JButton)e.getSource();
//button.setText("");
}
}
You can create a variable within your MouseAdapterMod, and assign whatever you need (e.g. the GUI) to it (or a reference of a JButton) through the constructor.
You can then use that to access any information you need during runtime clicking.
Example:
Note: Use getter methods as you wish.
class MouseAdapterMod extends MouseAdapter {
/*Set 'X' or 'O' based the selected radio button- how to achieve this? */
JRadioButton xButton;
public MouseAdapterMod(JRadioButton xButton)
{
this.xButton = xButton;
}
public void mousePressed(MouseEvent e) {
JButton button = (JButton)e.getSource();
if(xButton.isSelected())
button.setText("X");
else
button.setText("O");
}
}
/**
*
* #author saikrishnan.srivat
*/
public class TicTacToe extends JFrame {
/*declare the components of the window*/
JPanel iconPanel;
JPanel tictactoeBoard;
JPanel emptyPanel;
JLabel chooseLabel;
JRadioButton xButton;
JRadioButton oButton;
ButtonGroup bg;
JButton resetButton;
JButton exitButton;
JButton undoButton;
JSplitPane rightPane;
JSplitPane pane;
MouseAdapterMod mam;
public static void main(String args[])
{
new TicTacToe();
}
public TicTacToe() {
iconPanel = new JPanel();
tictactoeBoard = new JPanel();
emptyPanel = new JPanel();
chooseLabel = new JLabel("Choose your symbol :");
xButton = new JRadioButton("X");
oButton = new JRadioButton("O");
bg = new ButtonGroup();
bg.add(xButton);
bg.add(oButton);
/*add the label and the radio buttons too the empty panel*/
emptyPanel.add(chooseLabel);
emptyPanel.add(xButton);
emptyPanel.add(oButton);
emptyPanel.setLayout(new FlowLayout());
/*add the exit,undo and reset buttons to the icon panel*/
iconPanel.setLayout(new GridLayout(3, 1, 3, 3));
resetButton = new JButton("Reset");
exitButton = new JButton("Exit");
undoButton = new JButton("Undo Move");
iconPanel.add(resetButton);
iconPanel.add(exitButton);
iconPanel.add(undoButton);
/*Set layout of the tictactoe board and add the game buttons to it */
tictactoeBoard.setLayout(new GridLayout(3, 3));
/* Mouse adapter object that listens to the buttons in the tic tac toe board */
mam = new MouseAdapterMod(xButton);
for (int i = 0; i < 9; i++) {
JButton button = new JButton("");
button.addMouseListener(mam);
tictactoeBoard.add(button);
}
/*add the icon panel and the empty panel to the right pane*/
rightPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, iconPanel, emptyPanel);
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tictactoeBoard, rightPane);
add(pane);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
//setMaximumSize(new Dimension(500, 500));
setMinimumSize(new Dimension(700, 500));
setLocationRelativeTo(null);
pack();
setTitle("Tic Tac Toe");
setLocationRelativeTo(null);
setVisible(true);
}
}
My suggestion is to use an array of JButtons combined with ActionListener.
Try out the following quick SSCCE I just wrote and see if it will give you some good ideas:
(Once you click any of the 9 buttons, the console shall write the button number)
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
class test extends JFrame implements ActionListener
{
JButton button[] = new JButton[9];
public test()
{
init();
initializeAndAddButtons();
}
private void init()
{
this.setLayout(new GridLayout(3, 1, 3, 3));
this.setSize(600,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setTitle("Test");
}
private void initializeAndAddButtons()
{
for(int i = 0; i < 9;i++)
{
button[i] = new JButton(String.valueOf(i));
button[i].addActionListener(this);
add(button[i]);
}
}
public void actionPerformed(ActionEvent e)
{
JButton tempButton = (JButton) e.getSource();
System.out.println(tempButton.getText());
}
}
public class main
{
public static void main(String args[])
{
new test().setVisible(true);
}
}
okay ... my question is rather straight forward so I doubt ill need to add any code but I will if need be.
Whenever I create a GUI frame and add a couple of panels to it and run my application, the contents are not displayed until I either re-size the window or minimize it on the toolbar then restore it. What could be the cause of that and how can I solve it?
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public final class Calculator extends JFrame
{
//initialise various variables for use within the program
//BUTTONS
private final JButton additionButton = new JButton("+");
private final JButton subtractionButton = new JButton("-");
private final JButton divisionButton = new JButton("/");
private final JButton multiplicationButton = new JButton("*");
//PANELS
private JPanel operatorPanel;
private JPanel operandPanel;
//LABELS
private JLabel operationLabel;
//constructor to initialise the frame and add components into it
public Calculator()
{
super("Clancy's Calculator");
setLayout(new BorderLayout(5, 10));
setSize(370, 200);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
//create a message label to display the operation that has just taken place
operationLabel = new JLabel("YOU HAVE PERFORMED SOME OPERATION",SwingConstants.CENTER);
add(getOperatorPanel(), BorderLayout.NORTH);
add(getOperandPanel(), BorderLayout.CENTER);
add(operationLabel, BorderLayout.SOUTH);
}
//setter method for the operator panel
public void setOperatorPanel()
{
operatorPanel = new JPanel();
operatorPanel.setLayout(new FlowLayout());
operatorPanel.add(additionButton);
operatorPanel.add(subtractionButton);
operatorPanel.add(multiplicationButton);
operatorPanel.add(divisionButton);
}
//getter method for the operator panel
public JPanel getOperatorPanel()
{
setOperatorPanel();
return operatorPanel;
}
//setter method for operands panel
public void setOperandPanel()
{
operandPanel = new JPanel();
operandPanel.setLayout(new GridLayout(3, 2, 5, 5));
//LABELS
JLabel operandOneLabel = new JLabel("Enter the first Operand: ");
JLabel operandTwoLabel = new JLabel("Enter the second Operand: ");
JLabel answerLabel = new JLabel("ANSWER: ");
//TEXT FIELDS
JTextField operandOneText = new JTextField(); //retrieves one operand
JTextField operandTwoText = new JTextField(); //retrieves another operand
JTextField answerText = new JTextField(); //displays answer
answerText.setEditable(false); //ensure the answer field is not editable
operandPanel.add(operandOneLabel);
operandPanel.add(operandOneText);
operandPanel.add(operandTwoLabel);
operandPanel.add(operandTwoText);
operandPanel.add(answerLabel);
operandPanel.add(answerText);
}
//getter method for operand panel
public JPanel getOperandPanel()
{
setOperandPanel();
return operandPanel;
}
/** main method */
public static void main(String[] args)
{
new Calculator();
}
}
I notice you're programatically setting a new layout manager. Whenever you add, remove or change a java gui, you need to call invalidate() or revalidate() to make java re-create the GUI. See if calling invalidate() before setVisible(true) fixes the problem