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);
}
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:
More help needed with this little project of mine again, this time trying to get two labels that are inside a panel in certain positions. Those positions being one on the left and then a separation of spaces (like a tab) and then the second label to make way for entries being added below them when a button is pressed which I am also unsure how to start.
I've uploaded an image of the current program running :
As you can see I have two buttons (may change to one at some point) and then a separate results panel with currently two labels inside that I want to move. I want 'Name' to be on the left side and 'Grade' slightly more to the right (separated by about a tabs worth of space). I'm also unsure what the two little lines are so if someone could explain that to me it would be great.
Where I plan to go with this is then for a button entry to lead to a name entry being entered below these labels and a grade entry being entered below these labels which keeps updating with each button press. If anyone could guide me in the right direction for this it would be great. I have provided the code for the panel below.
Thanks for taking the time to read this!
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GradePanel2 extends JPanel {
private JButton addEntry, calculate;
private JLabel name, grade, nameResult, gradeResult;
private JTextField nameField, gradeField, resultField;
public GradePanel2() {
// Button to add entry to list
addEntry = new JButton("Add entry to list");
addEntry.addActionListener(new buttonListener());
// Button to print all entries in correct format
calculate = new JButton("Print all user grades");
calculate.addActionListener(new buttonListener());
//Create Labels
name = new JLabel("Enter student name: ");
nameField = new JTextField(10);
nameField.addActionListener(new buttonListener());
grade = new JLabel("Enter students mark: ");
gradeField = new JTextField(5);
gradeField.addActionListener(new buttonListener());
//Result Labels
nameResult = new JLabel("NAME");
gradeResult = new JLabel("GRADE");
//Bottom segment for result
resultField = new JTextField();
resultField.setOpaque(false);
resultField.setEditable(false);
setLayout(new BorderLayout());
//Bottom Panel
JPanel GradePanel = new JPanel();
GradePanel.setBorder(BorderFactory.createTitledBorder("Students/Results"));
GradePanel.setOpaque(false);
GradePanel.setPreferredSize(new Dimension(0 , 100));
GradePanel.add(resultField);
resultField.setAlignmentX(LEFT_ALIGNMENT);
GradePanel.add(nameResult);
GradePanel.add(gradeResult);
//Button Panel
JPanel ButtonPane = new JPanel();
ButtonPane.setLayout(new BoxLayout(ButtonPane, BoxLayout.PAGE_AXIS));
addEntry.setAlignmentX(CENTER_ALIGNMENT);
calculate.setAlignmentX(CENTER_ALIGNMENT);
ButtonPane.add(addEntry);
ButtonPane.add(Box.createVerticalStrut(10));
ButtonPane.add(calculate);
//Label Panel
JPanel labelPane = new JPanel();
labelPane.setLayout(new BoxLayout(labelPane, BoxLayout.PAGE_AXIS));
labelPane.add(name);
labelPane.add(Box.createRigidArea(new Dimension (5,0)));
labelPane.add(nameField);
labelPane.add(Box.createRigidArea(new Dimension (0,2)));
labelPane.add(grade);
labelPane.add(Box.createRigidArea(new Dimension (5,0)));
labelPane.add(gradeField);
//Add all panels to the main panel
add(labelPane, BorderLayout.NORTH);
add(ButtonPane, BorderLayout.CENTER);
add(GradePanel, BorderLayout.SOUTH);
setBackground(Color.WHITE);
setPreferredSize(new Dimension(400, 300));
}
public class buttonListener implements ActionListener{
public void actionPerformed(ActionEvent event){
String studentName;
int studentMark;
studentName = nameField.getText();
String intMark = gradeField.getText();
studentMark = Integer.parseInt(intMark);
}
}
}
and then the driver class:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Grade2{
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Grade Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GradePanel2 panel = new GradePanel2();
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(runnable);
}}
Take time to read this the most flexible Layout Manager that commonly used by programmer :)
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
Btw I separate your class Bottom Panel It's a little bit confused while reading it. Much better try the Nested Classes to look your code clean and easy to read.
https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GradePanel2 extends JPanel {
private JButton addEntry, calculate;
private JLabel name, grade, nameResult, gradeResult;
private JTextField nameField, gradeField, resultField;
public GradePanel2() {
// Button to add entry to list
addEntry = new JButton("Add entry to list");
addEntry.addActionListener(new buttonListener());
// Button to print all entries in correct format
calculate = new JButton("Print all user grades");
calculate.addActionListener(new buttonListener());
//Create Labels
name = new JLabel("Enter student name: ");
nameField = new JTextField(10);
nameField.addActionListener(new buttonListener());
grade = new JLabel("Enter students mark: ");
gradeField = new JTextField(5);
gradeField.addActionListener(new buttonListener());
//Bottom segment for result
resultField = new JTextField();
resultField.setOpaque(false);
resultField.setEditable(false);
setLayout(new BorderLayout());
GridBagConstraints nameResultConstraints = new GridBagConstraints();//Constraints
GridBagConstraints gradeResultConstraints = new GridBagConstraints();//Constraints
//Button Panel
JPanel ButtonPane = new JPanel();
ButtonPane.setLayout(new BoxLayout(ButtonPane, BoxLayout.PAGE_AXIS));
addEntry.setAlignmentX(CENTER_ALIGNMENT);
calculate.setAlignmentX(CENTER_ALIGNMENT);
ButtonPane.add(addEntry);
ButtonPane.add(Box.createVerticalStrut(10));
ButtonPane.add(calculate);
//Label Panel
JPanel labelPane = new JPanel();
labelPane.setLayout(new BoxLayout(labelPane, BoxLayout.PAGE_AXIS));
labelPane.add(name);
labelPane.add(Box.createRigidArea(new Dimension (5,0)));
labelPane.add(nameField);
labelPane.add(Box.createRigidArea(new Dimension (0,2)));
labelPane.add(grade);
labelPane.add(Box.createRigidArea(new Dimension (5,0)));
labelPane.add(gradeField);
myBottomPanel mybottompanel = new myBottomPanel();//Object
//Add all panels to the main panel
add(labelPane, BorderLayout.NORTH);
add(ButtonPane, BorderLayout.CENTER);
add(mybottompanel, BorderLayout.SOUTH);
setBackground(Color.WHITE);
setPreferredSize(new Dimension(400, 300));
}
public class myBottomPanel extends JPanel{
public myBottomPanel()
{
this.setLayout(new GridBagLayout());
//Result Labels
nameResult = new JLabel("NAME");
gradeResult = new JLabel("GRADE");
//Constraints
GridBagConstraints nameResultConstraints = new GridBagConstraints();
GridBagConstraints gradeResultConstraints = new GridBagConstraints();
//Bottom Panel
setBorder(BorderFactory.createTitledBorder("Students/Results"));
setOpaque(false);
setPreferredSize(new Dimension(0 , 100));
nameResultConstraints.anchor = GridBagConstraints.LINE_START;
nameResultConstraints.weightx = 0.5;
nameResultConstraints.weighty = 0.5;
add(nameResult,nameResultConstraints);
add(gradeResult);
}
}
public class buttonListener implements ActionListener{
public void actionPerformed(ActionEvent event){
String studentName;
int studentMark;
studentName = nameField.getText();
String intMark = gradeField.getText();
studentMark = Integer.parseInt(intMark);
}
}
}
and here is your Frame.
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Grade2{
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Grade Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GradePanel2 panel = new GradePanel2();
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(runnable);
}}
OUTPUT
Hope this helps. :)
If you want data displayed in a column then you need to use an appropriate layout manager to achieve the effect you want.
Maybe you can use a GridBagLayout. You can have columns and spaces between the columns, but you need to use the appropriate constraints. Read the section from the Swing tutorial on How to Use GridBagLayout for more information and working examples.
However, the easier option would be to use a JTable which is a component designed for display data in rows/columns. Again check out the Swing tutorial on How to Use Tables.
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 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