I am testing an application that directly implements ActionListener
The below application can be compiled and run:
public class App implements ActionListener {
JButton button;
int count = 0;
public static void main (String[] args)
{
App gui = new App();
gui.go();
}
public void go()
{
button = new JButton("Click me!");
JFrame frame = new JFrame();
frame.getContentPane().add(button);
frame.setSize(500,500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event)
{
count++;
button.setText("I've been clicked "+count+" times");
}
});
}
}
But Eclipse wants the
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
method in App class as well. is this because the "go" method may sometimes not be called making actionPerformed not called and then against how implementing works?
Thanks in advance for any assistance.
This is simply because of the java rule for implementing an interface. ActionListener interface has actionPerformed method in it. So any class implementing this interface need to provide the implementation for actionPerformed.
Read more about using ActionListener here: http://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
Related
This is a very simplified version of my code to get a better understanding of what I'm doing wrong here. The GUI freezes if the button is pressed. I need to be able to run a while loop if the button is pressed without freezing.
class obj1 extends Thread{
public void run(){
while(true) {
System.out.println("this thread should run when the button is pressed and I should be able to press another button");
}
}
}
class GUI extends Thread{
JFrame frame = new JFrame();
JButton button = new JButton("test1");
JButton button2 = new JButton("test2");
JPanel panel = new JPanel();
String command;
public void run() {
frame.setVisible(true);
panel.add(button);
panel.add(button2);
frame.add(panel);
frame.pack();
buttonOnAction();
}
public void buttonOnAction(){
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
obj1 one = new obj1();
one.start();
one.run();
}
});
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
obj1 one2 = new obj1();
one2.start();
one2.run();
}
});
}
}
public class Main{
public static void main(String args[]){
GUI gui = new GUI();
gui.start();
gui.run();
}
}
Why does the GUI freeze?
Don't call run() directly on your Thread object. This immediately executes the run() method and doesn't spawn a new thread. Instead, just call start() as you have and let the system create the thread and call run() when it decides to.
It is also worth pointing out that the proper way to schedule graphical work in Swing is to make sure it ends up on the event dispatch thread. To do this properly, use SwingUtilities#invokeLater(Runnable), which will not wait for the work to complete, or SwingUtilities#invokeAndWait(Runnable), which will.
I've been learning quite a lot in Java recently but something has been really bugging me. I learned / was taught how to use ActionListeners when the program involves a constuctor, for example,
public class test extends JFrame implements ActionListener {
JButton button;
public test
{
setLayout(null);
setSize(1920,1080);
setTitle("test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button = new JButton("");
button.setBounds(x,x,x,x);
button.AddActionListener(this); //What can replace the this parameter here.
button.setVisible(true);
add(button);
}
public static void main(String[] args) {
test testprogram = new test();
test.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent clickevent) {
if (clickevent.GetSource() == button) {
//DoSomething
}
}
It can be anything which implements ActionListener.
You might want to consider not making your JFrame implement ActionListener: this means that
It is part of the class' interface that it implements actionPerformed; but you probably don't want other classes to call that directly.
You can only implement it "once", so you end up having to have conditional logic to determine what the source of the event was, and then handle it appropriately.
The alternative is to create a button-specific action listener:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent clickevent) {
// Don't need to check if it is from button, nothing else
// could have created the event.
}
});
and remove implements ActionListener from the test class.
It is instance of class which is going to handle ActionEvent.
From the Documents
Register an instance of the event handler class as a listener on one
or more components. For example:
someComponent.addActionListener(instanceOfMyClass);
I have problem to use action listener to call function void in same class.
example..
code:
public class Product extends JPanel {
JButton add;
JPanel pAdd;
JLabel test;
JFrame frame;
public Product() {
add = new JButton("Add Product");
add.addActionListener(new ButtonListener());
add(add);
}
public void panelAdd(){
pAdd = new JPanel();
pAdd.add(new JLabel("try"));
add(pAdd);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
panelAdd();
}
}
}
How to make call the panelAdd void method?
When you add components to visible JFrame/JPanel/other components, you neet to call revalidate() andrepaint() methods after adding. Change your panelAdd() like next:
public void panelAdd(){
pAdd = new JPanel();
pAdd.add(new JLabel("try"));
add(pAdd);
revalidate();
repaint();
}
If you put
System.out.println("hi");
to
public void panelAdd(){
System.out.println("hi");
pAdd = new JPanel();
pAdd.add(new JLabel("try"));
add(pAdd);
}
you will see hi printed to your console , your code are working, but you have problem in Layout .
I would like to use setAlwaysOnTop(boolean) in java.
I want to setAlwaysOnTop() when I click on a JButton and this JButton has its own actionListener
My Problem is I don't know how to set the JFrame on top at this situation, because it's not inside the constructor nor there is a method getFrame()
I tried creating a method inside the constructor but it does not work :S.
UPDATE:
private class optionAction implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource() == onTop) //onTop is a menuItem when I click it it should make the frame Always on top.
frame.setAlwaysOnTop(true); //This does not work of course just to demonstrat you what I want to do
}
}
The following code lines show you how it can be done with a direct implementation of ActionListener() assigned to a button declared inside the constructor. (You can also do this anywhere else in your class.)
class MyFrame extends JFrame {
public MyFrame() {
// ...
JButton button = new JButton("PRESS");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setAlwaysOnTop(true);
// Alternatively use MyFrame.this.setAlwaysOnTop(true);
}
});
add(button);
// ...
}
}
An idea might be to pass a reference to your JFrame to the constructor of your implementation of the ActionListener.
Maybe something like this:
class MyActionListener implements ActionListener {
private JFrame jFrame;
public MyActionListener(JFrame jFrame) {
this.jFrame = jframe;
}
public void onClick(Event event) {
jFrame.setAlwaysOnTop(true);
}
}
create a boolean called ontop
boolean ontop = false;
jbutton.addActionListener(new ActionListener()) {
public void actionPerformed(ActionEvent e){
if (ontop) {
frame.setAlwaysOnTop(false);
ontop = false;
}
else {frame.setAlwaysOnTop(true); ontop = true}
});
The correct working code for this question is below:
private class optionAction implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource() == onTop) //onTop is a menuItem
setAlwaysOnTop(true); //This does not work of course just to demonstrate you what I want to do
}
}
The reason this is does not work because I was setting the setAlwaysOnTop on a JFrame object, which it doesn't exists in that class.
To set the setALwaysOnTop on a JFrame you have to remove the frame. and just add `setAlwaysOnTop()
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Menu extends JFrame implements ActionListener{
// Create the components and global variables
JButton newGameButton = new JButton("New Game");
JButton instructionGameButton = new JButton("Instructions");
JButton exitButton = new JButton("Exit");
JLabel mylabel = new JLabel("Welcome to Blackjack");
public Menu()
{
// Create the window
super("ThreeButtons");
setSize(300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//Creating the container for the components and set the layout
Container content = getContentPane();
FlowLayout layout = new FlowLayout();
content.setLayout(layout);
//Adding the event listener
newGameButton.addActionListener(this);
instructionGameButton.addActionListener(this);
exitButton.addActionListener(this);
//Adding of components
content.add(mylabel);
content.add(newGameButton);
content.add(instructionGameButton);
content.add(exitButton);
setContentPane(content);
}
//Add the event handler
public void actionPerformed(ActionEvent event)
{
if (event.getActionCommand()=="New Game")
new lol4();
if (event.getActionCommand()=="Instructions")
//new Instructions();
if (event.getActionCommand()=="Quit ?")
System.exit(0);
}
public static void main (String[] args)
{
//Create an instance of my class
new Menu();
}
}
Exit does not seem to work
First of all, never use "==" to compare Strings. Use the equals(...) method.
Exit does not seem to work
Why do you check for "Quit ?"?
The action command defaults to the text of the button, unless you set the command explicitly.
I never liked the "switch-board" action listeners where the listener tries to do everything and risks doing nothing due to hard to fix bugs. Better I think to use anonymous inner classes either to hold simple code themselves, or if more complex to route code to other methods, or if still more complex, to call a Controller's method.
For example:
newGameButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newGameActionPerformed(); // delegate this to a class method
}
});
instructionGameButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// call a controller object's methods
if (myController != null) {
myController.instructionGameAction();
}
}
});
exitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Menu.this.dispose(); // simple code can be called in-line
}
});
and elsewhere in the class:
private void newGameActionPerformed() {
// TODO add some code here!
}
public void setController(MyController myController) {
this.myController = myController;
}