Java: Counting clicks on button - java

I am trying to do something similiar as cookie clicker, nevertheless it does not work. I have not managed to create a "counter" that shows the amount of clicks. This is what I got hitherto, any ideas?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Stocks implements ActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Stocks().createGui();
}
});
}
public void createGui() {
JFrame frame = new JFrame("Clicker");
frame.setSize(175, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
frame.add(panel);
frame.getContentPane().add(panel, BorderLayout.WEST);
GridBagConstraints c = new GridBagConstraints();
JButton button1 = new JButton("Click this");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(40, 40, 40, 40);
panel.add(button1, c);
button1.addActionListener(this);
}

You can have a variable int cnt = 0; inside your Stocks class and everytime someone clicks on the button you increase cnt by one in the actionPerformed method.

As you said, your actionPerformed method is empty, meaning you coded your application to do nothing when the button is clicked.
This answer is assuming you only have one component using that class as ActionListener:
In earlier versions of Java, it would be:
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
Java 8, however, provides us with Lambda expressions, and allows this to be a lot easier (with less code).
button1.addActionListener(event -> counter++);
You don't need to create an implementation of ActionListener, Java 'll take care of this for you. If you write your code like this, it is even easier if you have more components using that class as ActionListener, since you won't be able to mix them up.
If you need them to call shared parts of code, you can still call methods from within the Lambda expression
button1.addActionListener(event -> {callSharedMethod(); counter++;});
In this example, first the shared method will be called. After that, the counter will be augmented, which will/might only be done from clicking this button.

You should first add a counter as a attribute of your class `Stock``
public class Stocks {
private int counter;
Initialize counter variable with 0:
public static void main(String[] args) {
this.counter = 0;
And then add the action listener to increase the variable:
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
});

I'm surprised nobody proposed resolving this by inheritance. The button you want is a JButton but slightly more specialized (it must count the number of clicks performed on itself).
public final class CountButton extends JButton {
private int counter = 0;
public CountButton(String text) {
super(text);
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
});
}
public final int getCounter() {
return counter;
}
}

Related

add action listener to static context

public static void main(String[] args) {
ControlledBall ball2 = new ControlledBall(12,2);
JFrame window = new JFrame("Controlled Ball");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JButton stop = new JButton("Stop");
stop.setSize(4,400);
stop.setVisible(true);
stop.setText("Stop");
stop.addActionListener(new Action());
i get an error on the last line that says 'controlledball.this cannot be referenced from a static context'
when i try the following technique instead of calling the stop() method i just change the values i need to change:
stop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
x= 0;
y = 0;
}
});
i get the error non-static field 'x' cannot be referenced from a static context...
the question is, from the main method how can i change the values of x and y which are declared in another method?
There are may ways you can solve this problem. A good suggestion is to probably create a custom ActionListener that holds a reference to the Object you want to change. For example, you could have:
class StopListener implements ActionListener {
private ControlledBall ball;
public StopListener(ControlledBall ball) {
this.ball = ball;
}
#Override
public void actionPerformed(ActionEvent e) {
ball.stop(); // sets x and y to zero
}
}
Then you can just instantiate and use that class as an ActionListener:
stop.addActionListener(new MyListener(ball2));
This should help you organize your code and keep it clean and maintainable.

I have a small eror in my code here (swing-java-JFrame)

First I am a beginner in java. I'm making a window with small button and a label (with 0 in default position), when I click on the button the label will change to 1 and when I tap another click the button will be 2. But, I have an error in calling the method.
my code:
package prototype;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Prototype {
public static int count;
public static JLabel l;
public void Proto()
{
JFrame f = new JFrame();
JButton b = new JButton("click");
JLabel lo = new JLabel("0");
JPanel p = new JPanel();
f.setBounds(120,120,500,500);
b.addActionListener(new MyAction());
p.add(lo);
p.add(b);
f.getContentPane().add(p,BorderLayout.CENTER);
f.show();}
public class MyAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
count++;
l.setText(Integer.toString(count));}
public static void main(String[] args) {
//I want to call the proto method but it give me an eror
new proto();
}}}
public class Prototype extends JFrame{
private static int count;
private JLabel l;
public Prototype() {
super();
JButton b = new JButton("click");
l = new JLabel("0");
JPanel p = new JPanel();
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
count++;
l.setText(Integer.toString(count));
}
});
p.add(l);
p.add(b);
this.getContentPane().add(p, BorderLayout.CENTER);
this.pack();
this.setVisible(true);
}
public static void main(String...args){
Prototype p=new Prototype();
}
}
I changed the method to a constructor, to have the possibility of creating a object of type Prototype and directly create a frame with it. Also I extended the class with JFrame to not need to create an extra JFrame. Next step was to remove the ActionListener class and creating a new ActionListener while adding it to the button. In my eyes this is useful if you have several buttons with different functionalities, so you can see the function of the button directly just by looking at the code of the button. and the last step was to create a new Object of type Prototype in the main method
If I we're you use a SwingWorker instead of manually setting the text of JLabel. Because this is not a proper way updating your GUI. This should be done using SwingWorker. Please read about publish and processmethod.

I'm trying to make a button to count characters in a text field

I'm trying to use the JButton count to count the number of characters entered into the JTextField t. I'm new to Java and GUIs but here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 extends Frame implements ActionListener{
TextField t;
Button count;
int a;
Choice choice;
public GUI1(){
this.t = new TextField("", 30);
this.count = new Button("count");
this.count.addActionListener(this);
JTextField x = new JTextField();
x.setEditable(false);
this.setTitle("Character count");
this.setLayout(new FlowLayout());
this.add(x);
this.add(t);
this.add(count);
this.pack();
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()== this.count)
t.setText(choice.getSelectedItem()+ " " +a);
}
I'm also trying to enter the value in another uneditable JTextField x. Any help is appreciated.
Add this to your code
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
a = t.getText().length();
}
});
OR
You can use lambda expression like this
count.addActionListener(e -> a = t.getText().length());
For More
http://docs.oracle.com/javase/7/docs/api/java/awt/event/ActionListener.html
You need to add a listener
TextField t = new TextField();
Button b = new Button("Count");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
}
});
You can read more about here
http://www.tutorialspoint.com/awt/awt_button.htm
First of all, I recommend you not to use AWT elements, since it brings tons of problems and it has little to no support, instead you can try using Swing components which are a replacement/fix for AWT. You can read more about here. You might also want to read AWT vs Swing (Pros and Cons).
Now going into your problem:
You should avoid extending from JFrame, I might recommend you to create a new JFrame object instead. Here's the reason to why. That being said, you can also remove all your this.t and other calls with this.
I'm glad you're using a Layout Manager!
And now to count the number of characters on your JTextField and set text to your other JTextField you should use this code:
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
Also I fixed your code, I changed AWT elements to Swing ones and added number of cols to your second JTextField so it would appear.
So, here's a running example that I made from your code (And removed Choice choice line since you didn't posted that code):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 {
JTextField t;
JButton count;
int a;
JFrame frame;
public GUI1(){
frame = new JFrame();
t = new JTextField("", 15);
count = new JButton("count");
JTextField x = new JTextField("", 15);
x.setEditable(false);
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
frame.setTitle("Character count");
frame.setLayout(new FlowLayout());
frame.add(x);
frame.add(t);
frame.add(count);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main (String args[]) {
new GUI1();
}
}
When you click on a button you should
String str = t.getText(); // get string from jtextfield
To save the text from the texfield. Then you can use something like:
a = str..length(); // get length of string
x.setText(str + " " + a); //set it to the field
To set it to the JTextField.

How would I go about preforming actoins after "Next" button is clicked with a Jbutton setup like this?

I found this nice two button interface using javax.swing which I use for my program which will ask a series of questions. I got the question box all set-up but I need to make it go to a second interface after this one.
So I want the next button to preform a piece of code when pressed. Here is my code:
package test;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class SwingJPanelDemo extends JFrame {
String letter = "apple";
private JLabel LetterTest = new JLabel(Main.text);
private JButton NextButton = new JButton("Next");
private JButton NoButton = new JButton("No");
public SwingJPanelDemo() {
super("Is This Your Letter?");
// create a new panel with GridBagLayout manager
JPanel newPanel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.WEST;
constraints.insets = new Insets(10, 10, 10, 10);
// add components to the panel
constraints.gridx = 0;
constraints.gridy = 0;
newPanel.add(LetterTest, constraints);
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.CENTER;
newPanel.add(NextButton, constraints);
constraints.gridx = 0;
constraints.gridy = 3;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.CENTER;
newPanel.add(NoButton, constraints);
// set border for the panel
newPanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Is This Your Letter?"));
// add the panel to this frame
add(newPanel);
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
// set look and feel to the system look and feel
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SwingJPanelDemo().setVisible(true);
}
});
}
}
How would I go about preforming actions after a button is pressed when using this kind of setup for an interface?
BTW: if there are any things you think are mistaken o that could be done better help is always appreciated but not requested
You need to add an ActionListener to your nextButton. There are at least two common patterns
With an anonymous class
nextButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Your code to do something here
}
});
With a custom ActionListener class:
class MyNextButtonActions implements ActionListener
{
// lots of rich method etc that code the meaning of life
public void actionPerformed(ActionEvent e)
{
//code to trigger on click, using all your lovely methods
}
}
which you then add to your button where you create the GUI i.e.
nextButton.addActionListener(new MyNextButtonActions());
A decent tutorial on all this is available for the Swing framework here. You can get very creative - for instance you could make your SwingJPanelDemo class implement ActionListener and add it as an ActionListener for all its components.
Make sure to import java.awt.event.*;, then you add an actionlistener to you're jbutton by doing
NextButton.addActionListener(new MyFirstActionListener());
Next we have to make the MyFirstActionListener() class. So anywhere inside your class is good.. perhaps in between the main method and your constructor, make it like so: and make sure it implements the ActionListener interface. The ActionListener interface only demands 1 method; the actionPerformed method, which takes an ActionEvent object as a parameter.
private class MyFirstActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String whatIsWrittenOnTheButton = e.getActionCommand();
if(whatIsWrittenOnTheButton.equals("Next")) {
System.out.println("You pressed the \'Next\' JButton.");
}
if(e.getSource() == NextButton) {
System.out.println("Here is a 2nd message upon pressing next");
}
}
}
e.getActionCommand() will return a string that represents what was written on the pressed button, and e.getSource() will return an object. This is particularly handy if you use the same actionlistener for multiple different buttons; it's a means to distinguish between them.

Dynamically adding action listener to buttons

i think this is wrong. i want my code to add actionlistener as soon as button is created.Is there a way to do that dynamically. look at the inner for loop i have a problem adding there
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.awt.event.*;
/* <applet code = "Gridl.java" width=300 height=200>
</applet> */
public class Gridl extends Applet
{
TextField t1=new TextField(" ");
public void init()
{
int n = 1;
setLayout(new GridLayout(4,4));
add(t1);
setFont(new Font("Tahoma",Font.BOLD,24));
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
add(new Button(""+n));
this.addActionListener(this); // this didnt work :(
n++;
}
}
}
public void actionPerformed(ActionEvent ae)
{
String str = ae.getActionCommand();
t1.setText(str);
}
}
I think you have some conceptual misunderstandings reflected in your code here. It's important to consider which component you are adding the ActionListener onto. At the moment, your code adds the ActionListener to the Gridl object extending Applet, rather than the button itself. It won't throw an exception, because that's valid, but it won't give you the behaviour you want
To get you working, I suggest you replace
add(new Button(""+n));
with
Button b = new Button(""+n);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("You clicked button "+e.getSource().toString());
}
});
this.add(b);
Note that this sets up a new ActionListener for every Button object, with its behaviour determined by what you put in the actionPerformed() method. You can have the same behaviour for all buttons, or different for each.
I would suggest that you might want to read the oracle Java Swing GUI tutorials, in particular the one on actions. There are code samples there too.
EDIT:
I have realised you might want to have your Gridl be the listener for all buttons. In which case - you can achieve this by:
public class Gridl extends Applet implements ActionListener
{
TextField t1=new TextField(" ");
public void init()
{
int n = 1;
setLayout(new GridLayout(4,4));
add(t1);
setFont(new Font("Tahoma",Font.BOLD,24));
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
Button b = new Button(""+n));
b.addActionListener(this);
this.add(b);
n++;
}
}
}
public void actionPerformed(ActionEvent ae)
{
String str = ae.getActionCommand();
t1.setText(str);
}
}
try like this when creating button new button().add without ending that statement.
new Button("").addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
System.out.println("You clicked the button");
}
});

Categories

Resources