Im kind of new to programming in java but here im trying to figure out how to add the value of a button clicked in ActionEvent. I even changed the actionlistener to MouseListener etc but still not working. It only displays the current button clicked but i would like to add every button clicked into an arraylist.
Problem: I cant add the value of buttons clicked into an arraylist.
Example: if i click on the button named E then i want E to be added to arraylist, after that if i click on the button S then it should add S o the same arraylist.
but its not adding aything to the arraylist. it only displays the current button clicked
public class WordFinder extends JFrame implements ActionListener {
private JButton buttons[];
ArrayList<String> LettersClicked = new ArrayList<String>();
private JTextArea jta;
private JLabel jLabel;
public WordFinder(){
int numberOfLetters = 64;
buttons = new JButton[numberOfLetters];
JFrame frame = new JFrame("wordfinder");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.red);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel topPanel = new JPanel();
topPanel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
topPanel.setPreferredSize(new Dimension(600, 600));
topPanel.setMaximumSize(new Dimension(600, 600));
topPanel.setBackground(Color.red);
JPanel bottomPanel = new JPanel();
bottomPanel.setBorder(BorderFactory.createLineBorder(Color.yellow));
bottomPanel.setPreferredSize(new Dimension(600, 300));
bottomPanel.setMaximumSize(new Dimension(600, 300));
bottomPanel.setBackground(Color.green);
Font f3 = new Font(Font.DIALOG, Font.BOLD, 35);
for (int i = 0;i<numberOfLetters;i++) {
char letter = alphabet();
buttons[i] = new JButton(String.valueOf(letter));
buttons[i].setFont(f3);
// buttons[i].setMinimumSize(new Dimension(40, 20));
buttons[i].setPreferredSize(new Dimension(65, 65));
buttons[i].setMargin(new Insets(0,0,0,0));
buttons[i].setBackground(Color.white);
buttons[i].setFocusPainted(false);
buttons[i].addActionListener(this);
topPanel.add(buttons[i]);
}
String buttValue = "";
jLabel = new JLabel(""+buttValue);
jLabel.setFont(f3);
bottomPanel.add(jLabel);
LettersClicked.add(jLabel.toString());
for (int z = 0; z<LettersClicked.size(); z++){
JLabel aa = new JLabel(""+LettersClicked.size());
bottomPanel.add(aa);
}
mainPanel.add(topPanel);
mainPanel.add(bottomPanel);
frame.getContentPane().add(mainPanel);
frame.setSize(1000,1000);
frame.setMinimumSize(new Dimension(1000, 1000));
frame.setVisible(true);
}
public char alphabet(){
Random rnd = new Random();
String alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char letter = alphabets.charAt(rnd.nextInt(alphabets.length()));
return letter;
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
JButton button = (JButton) actionEvent.getSource();
jLabel.setText(button.getText());
LettersClicked.add(button.getText());
}
}
I think you are confused about the content of the JLabel displayed on the GUI and your ArrayList. The issue is actually in the former.
Your current implementation replaces the text of the JLabel instead of appending it for each pressed button.
So, in your actionPerformed() method, change this line
jLabel.setText(button.getText());
to
jLabel.setText(jLabel.getText() + button.getText());
Related
I've hit a problem in getting a JPanel to update.
My simple program uses a custom JPanel which displays a label and a textfield. A Jbutton on the main panel is used to replace the JPanel with a new JPanel. The initial panel shows up fine but when the button is pressed the panel is not updated with a new MyPanel. I can tell that a new object is being created as count is being incremented.
public class SwingTest extends JFrame{
private JPanel mp;
private JPanel vp;
private JButton button;
public static void main(String[] args) {
SwingTest st = new SwingTest();
}
public SwingTest() {
vp = new MyPanel();
mp = new JPanel(new BorderLayout());
mp.add(vp, BorderLayout.CENTER);
button = new JButton("Change");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
mp.add(button, BorderLayout.SOUTH);
this.add(mp);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setSize(250, 150);
pack();
setVisible(true);
}
}
and my custom panel....
public class MyPanel extends JPanel{
private JLabel label;
private JTextField tf;
static int count = 0;
public MyPanel(){
count++;
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
setPreferredSize(new Dimension(400, 200));
c.gridx = 0;
c.gridy = 0;
label = new JLabel(String.valueOf(count));
tf = new JTextField(10);
add(label,c);
c.gridx = 1;
add(tf, c);
}
}
You state:
A Jbutton on the main panel is used to replace the JPanel with a new JPanel.
And yet this code:
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
and yet this code does not do this at all. All it does is change the JPanel referenced by the vp variable, but has absolutely no effect on the JPanel that is being displayed by the GUI, which suggests that you're confusing reference variable with reference or object. To change the JPanel that is displayed, you must do exactly this: add the new JPanel into the container JPanel into the BorderLayout.CENTER (default) position, then call revalidate() and repaint() on the container.
e.g.,
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
// vp = new MyPanel();
// vp.revalidate();
mp.remove(vp); // remove the original MyPanel from the GUI
vp = new MyPanel(); // create a new one
mp.add(vp, BorderLayout.CENTER); // add it to the container
// ask the container to layout and display the new component
mp.revalidate();
mp.repaint();
}
});
Or better still -- use a CardLayout to swap views.
Or better still -- simply clear the value held by the JTextField.
For more on the distinction between reference variable and object, please check out Jon Skeet's answer to this question: What is the difference between a variable, object, and reference?
I am learning Java creating small projects for fun. I am fairly new to it and easily stuck, hence the question I am asking.
I'm trying to create a simple Shopping Cart program, which in it's main panel has a 3x3 grid consisting of empty labels later
going to be replaced with images. And to the right of the grid there is four buttons, Add a Meal, Add a Drink, Total Price
and Clear All. So when either of the first two buttons are clicked, I want it to change the current panel to the panels corresponding to the button that was clicked.
The panel that is displayed then has data, like type of the food in a combobox which displays set food and quantity of the food.
Which then when the user chooses the type and quantity, presses the Add button, that would then change the panel
back to the main panel and the first empty label now has an image of the item that has been added to the cart.
This is all I currently know and as far as I can get.
Main class
public class ShoppingCart
{
public ShoppingCart()
{
JFrame app = new JFrame("Cart");
MainPanel main = new MainPanel();
app.add(main);
app.pack();
app.setResizable(false);
app.setLocationRelativeTo(null);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setVisible(true);
}
public static void main(String[] args)
{
new ShoppingCart();
}
}
MainPanel class
public class MainPanel extends JPanel implements ActionListener
{
private final JLabel labels[] = new JLabel[9];
private final JButton button[] = new JButton[4];
public MainPanel()
{
String buttonText[] ={"Add a Meal", "Add a Drink", "Total Price", "Clear All"};
String buttonToolTipText[] =
{"This will add food", "This will add drink", "This will display the price", "Clear the cart"};
this.setLayout(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4, 1, 2, 2));
for (int i = 0; i < 4; i++)
{
button[i] = new JButton(buttonText[i]);
button[i].setOpaque(true);
button[i].setBackground(Color.WHITE);
button[i].setFont(new Font("Ariel", Font.PLAIN, 18));
button[i].setPreferredSize(new Dimension(150,50));
button[i].setVisible(true);
button[i].setToolTipText(buttonToolTipText[i]);
button[i].addActionListener(this);
buttonPanel.add(button[i]);
}
JPanel labelPanel = new JPanel(new GridLayout(3, 3, 2, 2));
Border border = BorderFactory.createLineBorder(Color.GRAY);
for (int i = 0; i < 9; i++)
{
labels[i] = new JLabel();
labels[i].setOpaque(true);
labels[i].setVisible(true);
labels[i].setPreferredSize(new Dimension(100, 100));
labels[i].setBorder(border);
labels[i].setBackground(Color.WHITE);
labelPanel.add(labels[i]);
//set empty label to the image of the type chose,
//if right clicked, show type and quantity chosen
}
add(labelPanel, BorderLayout.WEST);
add(buttonPanel, BorderLayout.EAST);
}
#Override
public void actionPerformed(ActionEvent e)
{
if(button[0] == e.getSource())
{
//Change panel to Meal panel
}
if(button[1] == e.getSource())
{
//Change panel to Drink panel
}
if(button[2] == e.getSource())
{
//JOptionPane to show total price
}
if(button[3] == e.getSource())
{
//Check whether labels are empty, if not clear them else display message
}
}
}
MealPanel class
public class MealPanel extends JPanel implements ActionListener
{
public MealPanel()
{
this.setLayout(new BorderLayout());
JPanel titlePanel = new JPanel();
JPanel labelPanel = new JPanel(new GridLayout(2, 1, 3, 3));
JPanel inputField = new JPanel(new GridLayout(2, 1, 3, 3));
JPanel addCancel = new JPanel();
JLabel title = new JLabel("Add a Meal");
title.setBorder(BorderFactory.createMatteBorder(5,0,10,0, new Color(0,0,0,0)));
titlePanel.add(title);
JLabel type = new JLabel("Type:", JLabel.RIGHT);
labelPanel.add(type);
JLabel quantity = new JLabel("Quantity:", JLabel.RIGHT);
labelPanel.add(quantity);
final String arr[] = {"Burger", "Pizza"};
JComboBox mealType = new JComboBox(arr);
inputField.add(mealType);
JTextField quant = new JTextField();
inputField.add(quant);
JButton add = new JButton("Add");
add.addActionListener(this);
addCancel.add(add);
JButton cancel = new JButton("Cancel");
cancel.addActionListener(this);
addCancel.add(cancel);
add(titlePanel, BorderLayout.NORTH);
add(labelPanel, BorderLayout.WEST);
add(inputField, BorderLayout.EAST);
add(addCancel, BorderLayout.SOUTH);
}
#Override
public void actionPerformed(ActionEvent e)
{
//If cancel is pressed, return back to main, nothing changed on this panel
//else if add is pressed, set the type and quantity and return back to main
}
}
I guess what is shown, is I don't know how to specifically change the current panel to the panel chosen via which button is clicked. Then when the panel is shown, how to set the data then change the panel back to the MainPanel to then have that type of food displayed in the label as an image within the grid corresponding to the type that was chosen, so either a burger or pizza in the first empty label.
How would one go about doing the application?
class ABC extends JFrame {
public JPanel createGUI()
{
JPanel outerPanel = new JPanel();
outerPanel.setLayout(null);
JLabel top = new JLabel();
top.setBounds(40,40,400,30);
top.setText("Hello World");
outerPanel.add(top);
int l = getLength();
JPanel innerPanel = new JPanel();
if(l==0)
{
innerPanel.setLayout(null);
JLabel empty = new JLabel("No Data Found");
empty.setBounds(80,150,300,30);
innerPanel.add(empty);
}
else
{
innerPanel.setLayout(new GridLayout(l,4,5,5));
for(int i=0;i<l;i++)
{
innerPanel.add(new JLabel("Text1");
innerPanel.add(new JLabel("Text2");
JButton b1 = new JButton("Button1");
innerPanel.add(b1);
JButton b2 = new JButton("Button2");
innerPanel.add(b2);
}
}
outerPanel.add(innerPanel);
return outerPanel;
}
}
In the above code the innerPanel does not show up and neither any error occurs.Any idea how to show up the innerPanel which is inside an outerPanel.I tried using
getContentPane().add(innerPanel)
but it didn't work.
Try changing
outerPanel.setLayout(null);
to
outerPanel.setLayout(new FlowLayout());
or remove the setLayout call entirely.
For some reason my action listener isn't working correctly. When I add the first number to it it works fine, but when I continue to add numbers it stops working correctly. Any ideas on why this happens would be appreciated!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BabyCalculatorFinal extends JFrame{
private JLabel additionLabel;
private JTextField additionField;
private JButton additionButton;
private JPanel multiplication;
private JLabel multiplicationLabel;
private JTextField multiplicationField;
private JButton multiplicationButton;
private JPanel total;
private JLabel totalLabel;
private JTextField totalField;
private JButton stopButton;
public BabyCalculatorFinal(){
setDefaultCloseOperation(EXIT_ON_CLOSE);// 1st thing to do
setName("Baby Calculator Final"); // 2nd thing to do
setLayout(new GridLayout(3,0)); //sets grid layout for the entire thing with 3 rows
// Create Action Event
BabyCalculatorListener listener = new BabyCalculatorListener();
//Addition
//Addition Set Layout
JPanel addition = new JPanel(new BorderLayout());
//Addition Features
additionLabel = new JLabel("Amount to add"); //Create label
additionField = new JTextField(10);
additionButton = new JButton("Add");
//Organize Addition Panel
addition.add(additionLabel, BorderLayout.WEST);//IMPORTANT FORMAT
addition.add(additionField, BorderLayout.CENTER);
addition.add(additionButton, BorderLayout.EAST);
//Add addition Panel to Frame
add(addition);
additionButton.addActionListener(listener);
//Multiplictation
//Multiplication Set Layout
multiplication = new JPanel();
multiplication.setLayout(new BorderLayout());//Trying a different way of setting the layout
//Multiplication Features
multiplicationLabel = new JLabel("Amount to Multiply"); //Create label
multiplicationField = new JTextField(10);
multiplicationButton = new JButton("Multiply");
//Organize Multiplication Panel
multiplication.add(multiplicationLabel, BorderLayout.WEST);
multiplication.add(multiplicationField, BorderLayout.CENTER);
multiplication.add(multiplicationButton, BorderLayout.EAST);
//Add Multiplication Panel to Frame
add(multiplication);
multiplicationButton.addActionListener(listener);
//Total
total = new JPanel(new FlowLayout());
totalLabel = new JLabel("Total");
totalField = new JTextField();
totalField.setText("0.0");
totalField.setEditable(false);
stopButton = new JButton("Stop");
total.add(totalLabel);
total.add(totalField);
total.add(stopButton);
//Add Total Panel to Frame
add(total);
pack();
setVisible(true);
}
public static void main(String[] args){
JFrame myFrame = new BabyCalculatorFinal();
}
public class BabyCalculatorListener implements ActionListener{
public void actionPerformed(ActionEvent e){
String totalText = totalField.getText();
double totalAmount = Double.parseDouble(totalText);
if (e.getSource() == additionButton){
String additionText = additionField.getText();
double addAmount = Double.parseDouble(additionText);
totalAmount += addAmount;
}
else{
String multiplicationText = multiplicationField.getText();
double multiplicationAmount = Double.parseDouble(multiplicationText);
totalAmount *= multiplicationAmount;
}
totalField.setText(totalAmount + "");
}
}
}
Your code works fine for me. It could be a repaint issue that you're experiencing. Try resizing the frame when you stop seeing the "total" change. If that works, you could try a repaint() after setting the totalField text.
I am writing a very simple GUI, that contains 3 buttons, 2 labels, 2 text fields and one text area. Strangely, the result is unstable: when running the class the GUI appears with random number of the controls. I tried various layout managers, changing the order among the control - nothing.
Can someone help?
package finaltestrunner;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FinalTestGUI extends JFrame implements ActionListener
{
public Boolean startState = false;
JButton sofButton;
JButton startStopButton;
JButton exitButton;
JTextField loopCounts;
JTextField trSnField;
JTextArea resultField = null;
public FinalTestGUI()
{
// The constructor creates the panel and places the controls
super(); // Jframe constructor
JFrame trFrame = new JFrame();
trFrame.setSize(1000, 100);
trFrame.setVisible(true);
trFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
trFrame.setTitle("Test runner");
setFont(new Font("SansSerif", Font.PLAIN, 14));
// trFrame.setLayout(new FlowLayout());
JPanel trControlPanel = new JPanel();
trControlPanel.setSize(1000, 100);
trControlPanel.setLayout(new GridLayout(1,7));
exitButton = new JButton("Exit");
trControlPanel.add(exitButton);
startStopButton = new JButton("Run ");
trControlPanel.add(startStopButton);
JLabel loopsLabel = new JLabel ("Loops count: ");
trControlPanel.add(loopsLabel);
loopCounts = new JTextField (5);
trControlPanel.add(loopCounts);
sofButton = new JButton("SoF");
trControlPanel.add(sofButton);
JLabel testLabel = new JLabel ("serial Number: ");
trControlPanel.add(testLabel);
trSnField = new JTextField (5);
trControlPanel.add(trSnField);
JTextArea trResultField = new JTextArea (80, 10);
trFrame.add(trControlPanel);
// cpl.add(trResultField);
startStopButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed (ActionEvent trStartStopButton)
{
startState = !startState;
if (startState)
{
startStopButton.setText("Run ");
startStopButton.setForeground(Color.red);
}
else
{
startStopButton.setText("Stop");
startStopButton.setForeground(Color.green);
}
}
});
sofButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed (ActionEvent trSofButton)
{
loopCounts.setText("SOF\n");
}
});
exitButton.addActionListener (new ActionListener()
{
#Override
public void actionPerformed (ActionEvent trExitButton)
{
System.exit(0);
}
});
} // End of the constructor
#Override
public void actionPerformed (ActionEvent ae) { }
public void atpManager ()
{
String selectedAtp = "";
}
}
There are a couple of issues with this code:
You are already inheriting from JFrame, so you do not need to create yet another JFrame
You are showing your frame with setVisible(true) and afterwards adding components to it. This invalidates your layout, you need to revalidate afterwards (or move setVisible() to a position where you already added your components)
You are adding your components to the JFrame directly, but you need to use its contentpane. Starting with Java 1.5, the JFrame.add() methods automatically forward to the content pane. In earlier versions, it was necessary to retrieve the content pane with JFrame.getContentPane() to add the child components to the content pane.
Try this:
public FinalTestGUI() {
// The constructor creates the panel and places the controls
super(); // Jframe constructor
setSize(1000, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Test runner");
setFont(new Font("SansSerif", Font.PLAIN, 14));
setLayout(new FlowLayout());
JPanel trControlPanel = new JPanel();
trControlPanel.setSize(1000, 100);
trControlPanel.setLayout(new GridLayout(1,7));
exitButton = new JButton("Exit");
trControlPanel.add(exitButton);
startStopButton = new JButton("Run ");
trControlPanel.add(startStopButton);
JLabel loopsLabel = new JLabel ("Loops count: ");
trControlPanel.add(loopsLabel);
loopCounts = new JTextField (5);
trControlPanel.add(loopCounts);
sofButton = new JButton("SoF");
trControlPanel.add(sofButton);
JLabel testLabel = new JLabel ("serial Number: ");
trControlPanel.add(testLabel);
trSnField = new JTextField (5);
trControlPanel.add(trSnField);
JTextArea trResultField = new JTextArea (80, 10);
// getContentPane().add(trControlPanel); // pre 1.5
add(trControlPanel); // 1.5 and greater
setVisible(true);
}