Storing JFrame output into a String in the Main Program - java

It seems to me that so far, everything that happens within JFrame stays within JFrame. (Probably should have gotten into JavaFX instead of Swing)
Let's say you have a JFrame Class (gui_frame) that utilizes JButtons with a nested class named HandlerClass that implements ActionListener, as shown below:
public class gui_frame extends JFrame {
private JButton button1;
public gui_frame() {
super("Title");
setLayout(new FlowLayout());
button1 = new JButton("Hello");
add(button1);
HandlerClass handler = new HandlerClass();
button1.addActionListener(handler);
}
private class HandlerClass implements ActionListener{
public void actionPerformed(ActionEvent e){
//insert code here
}
}
}
And then you have the main code, which calls upon this gui_frame class.
public class main {
public static void main(String[] args){
//insert some unrelated code here
gui_frame gf = new gui_frame();
gf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gf.setSize(400,75);
gf.setVisible(true);
String button_name;
//insert some code that uses button_name
}
}
Essentially, I'm trying to store the name of the button in the JFrame class gui_frame (in this case "Hello"), AFTER BEING CLICKED, into the String button_name in the main class, during run time.
Is this possible? What do I have to insert into the actionPerformed method in the gui_frame, in order to make this happen?

There's a few ways that you could do this:
implement the ActionListener as a lambda in the main class (btw, that should be capitalized, i.e. "Main"), and pass the lambda to the gui_frame class (again, that should be "GuiFrame"), and have the GuiFrame class apply the listener to the button
create an interface for the GuiFrame class to use to notify the Main class that the button has been clicked (and the name of the button). Have the Main class implement that interface, and then pass the instance of Main to the GuiFrame class. Then have the GuiFrame's ActionListener call the method in the Main class' interface to notify it.
Store the name of the last clicked button in the GuiFrame class, and have the Main class ask for it when it needs it (if it doesn't need to know when the button is clicked).

Related

How to close a JFrame on a class that implements ActionListener

I need to close a specific JFrame with another class that implements ActionListener
public class EditStudent extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
EditStudent frame = new EditStudent();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I will use this class to a JButton on that JFrame. (It's like a controller to a JButton)
public class EditFileController implements ActionListener {
#SuppressWarnings("unused")
private JButton btnEdit = new JButton();
public EditFileController(JButton btnEdit) {
super();
EditStudent.btnEdit = btnEdit;
}
}
Every searchable method. I've been searching for at least 5 hrs.
Well start with the basics of how to write an ActionListener. The code you posted doesn't even implement the actionPerformed(...) method so it won't even compile.
Read the Swing tutorial for Swing basics. Maybe start with the section on How to Use Lists. The ListDemo code shows how to use an inner class to define an ActionListener.
Your controller class makes no sense to me. You appear to be making it to complicated. For example why would you pass the button as a parameter but also make a new instance of the button in the class.
An ActionListener does NOT to define the button or have it passed as a parameter.
All you need to do is create the button where you add all other components to the frame. Then you add the ActionListener to your button.
Then the the basic code in your ActionListener would be:
Window window = SwingUtilities.windowForComponent(event.getSource());
window.dispose();
Once you get that working and understand the basic concepts you may want to check out Closing an Application which presents a simple API to create reusable code that can be used for any frame.

Can you make a jButton in a jFrame generate its code into another class?

Can you make a button in a jframe generate its Events>Action>actionPerformed code into another class besides the jframe class. If you cant, can you manually make the code in the different class to make the button do something.
Yes, you can.
Basically, you use myJbutton.setActionListener(new MyButtonActionListener()).
And you have a class MyButtonActionListener implements ActionListener. The method actionPerformed will be called automatically.
EDIT: Added code below
public class MyButtonActionListener implements ActionListener {
#Override
public void actionPerformed(EventListener e){
// Do stuff
}
}
And you setup your button:
JButton myButton = new JButton("mybutton");
myButton.setActionListener(new MyButtonActionListener());

What is the keyword "this" referring to if it is given as an argument

I know when to use the keyword "this" for fields and constructors but I'm not sure when it is passed as an argument
import javax.swing.*;
import java.awt.event.*;
public class SimpleGui implements ActionListener {
JButton button;
public static void main (String[] args) {
SimpleGui gui = new SimpleGui();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
button = new JButton("click me");
button.addActionListener(this);
frame.getContentPane().add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
button.setText("I've been clicked!");
}
}
The line button.addActionListener(this); means:
Add a listener to actions performed on the button object
Make the listener the current instance of SimpleGui within context (SimpleGui happens to implement the ActionListener interface)
So when the button is clicked, SimpleGui#actionPerformed should be invoked.
Whenever a button is presses to get a callback, we need to attach a listener to that button, here in your example that is done using following line,
button.addActionListener(this);
addActionListener() requires to pass a instance which implements ActionListener interface.
And here SimpleGui is a ActionListener as it implements that interface. Hence in SimpleGui you are writing,
button.addActionListener(this);
where this is instance of SimpleGui which implements ActionListener
This is a keyword which means the instance of the class,
in your class
public class SimpleGui implements ActionListener {
this is an instance of the SimpleGui, it could be as well an object (any) that is implementing the actionListener
If you call a method that accepts this, it is because
this argument is an object of the SimpleGui class, or even better, is an object (no matter which one) that implements the ActionListener.

Passing "this" as a Method Argument - Clarification

I am currently working on Java Swing lessons after finishing my first set of lessons in Java. In this lesson, we are working on communication between different components (buttons,toolbars,etc.) that we have been studying. The problem is, "this" is being passed as a method argument for the addActionListener() method. This works, however, I do not completely understand what it is doing. I did some research regarding "this," and found that the most popular usage for the "this" keyword would be in constructors with variables of the same names. I could not find an example that would fit my case. By looking at the code below, I will explain that parts of the code that I understand.
import java.awt.FlowLayout; Implements FlowLayout class
import java.awt.event.ActionEvent; //Imports ActionEvent Class
import java.awt.event.ActionListener; //Imports ActionListener Interface
import javax.swing.JButton; //Imports JButton class
import javax.swing.JPanel; //Imports JPanel class
public class Toolbar extends JPanel implements ActionListener {
// ^ Inherits JPanel & Implements ActionListener Interface
private JButton helloButton; //Creating variable of JButton type
private JButton goodbyeButton; //Creating variable of JButton type
public Toolbar() { //Constructor
helloButton = new JButton("Hello"); //Creates new JButton
goodbyeButton = new JButton("Goodbye"); //Creates new JButton
helloButton.addActionListener(this); //Question 1
goodbyeButton.addActionListener(this); //Question 1
setLayout(new FlowLayout(FlowLayout.LEFT)); //Sets Layout Type to Left
add(helloButton); //Adds button to FlowLayout (Layout Manager) Interface
add(goodbyeButton); //Adds button to FlowLayout (Layout Manager) Interface
}
public void setTextPanel(TextPanel textPanel) {
//No Usage Yet!
}
public void actionPerformed(ActionEvent arg0) { //Unimplemented Method from ActionListener
System.out.println("A button was clicked"); //Prints after button is clicked.
}
}
Question 1: As you can see, after creating two JButtons, we are adding an addActionListener() method in order to see detect if the button has been clicked. If it has been clicked, then it will do any code typed in actionPerformed that is implemented from the ActionListener interface. In previous lessons, we had a different way of making a button respond to a click. It did the same thing, but it looked like this:
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
textPanel.appendText("Hello\n");
}
});
In this example, rather than printing to the console to test to see if the actionListener() worked, we just appended the text to a text area from a customized component. In the code directly above this text, we are working with an anonymous class.
So... The question is, what exactly is "this" doing as it is being passed as a method argument in addActionListener()? I know that it is printing "A button was clicked" to the console, but I don't understand the logic behind what "this" is doing to send that the button has been clicked to actionPerformed().
This is what the applications looks like:
This is the application in motion, and the buttons have already printed to the console after being clicked. I thought it might give you a better idea of what I am working on. I hope somebody can shed some light on this, and explain how "this" is working in this context. Thank you!
this represents the current instance of your class.
Toolbar class implements ActionListener interface, that means it provides an implementation of method actionPerformed.
So, helloButton.addActionListener(this); becomes possible (try to remove implements ActionListener from class declaration, the code won't compile).
Saying this, Toolbar instances can be considered as ActionListener objects and can be passed to button.addActionListener.
When using
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
}
}
you create a new implementation of the ActionListener interface in the fly. This kind of implementation is named anonymous.
The both solutions are valid. Prefer the anonymous solution if the code in actionPerformed cannot be used from another place.
this is just an instance of your Toolbar class. It is used inside instance methods to represent the current instance. Essentially you can imagine your class has another private member variable named this, that points to a Toolbar object.
Since Toolbar implements ActionListener you are assigning the newly instantiated Toolbar object as a listener to the buttons (meaning the Toolbar.actionPerformed() method will be called when the buttons are clicked.)
By implementing ActionListener and then passing this to addActionListener method you are asking to be informed of any actions that are performed through a call to your actionPerformed method.
Or, more simply, you are giving the button your phone number and asking it to call you whenever something happens.
In the earlier lessons you were stating what should happen - print this text or add some text to the textPanel. To do this you were making an ActionListener on-the-fly. Now you implement ActionListener yourself you can request a callback to you anstead of making a listener one on-the-fly.
The addActionListener method for a swing component takes an argument of type ActionListener. A class that implements an ActionListener contains code that specifies what should be done when someone interacts with a swing component.
When you pass this to the addActionListener method, you are passing a reference to the current object that is being instantiated. As it happens, the current object being instantiated is also an ActionListener (as it implements ActionListener) and can therefore be passsed to the addActionListener method.
When you interact with the JButton in the GUI, the actionPerformed method of Toolbar class will be called since that is the ActionListener that you registered the JButton with.
These two examples would do the same thing (assuming all imports are there, and that capitalization would be correct):
public static void main(String args[]){
myFrame frame = new myFrame();
myFrame.addActionListener(new myListener);
}
public myFrame extends JFrame{
public myFrame(){
super("myFrame");
}
}
public myListener implements ActionListener{
public void ActionPerformed(ActionEvent e){
//Do Stuff
}
}
and
public static void main(String args[]){
myFrame frame = new myFrame();
}
public myFrame extends JFrame implements ActionListener{
public myFrame(){
super("myFrame");
this.add(this);
}
public void ActionPerformed(ActionEvent e){
//Do Stuff
}
}
The advantage of having the ActionListener be this is that it would have more direct access to fields and methods, if you want to make the modifier on the methods private.
However, if you want to avoid if/else if monstrosities for handling multiple buttons, I recommend either using a separate ActionListener(and providing a means to change what needs to be changed), or taking a look at anonymous classes and lambda expressions.
Often with object-oriented coding, it's worth role-playing the part of an object of the class you're coding. If you do that, "this" means "me".
And because Java is pass-by-reference, "this" is an arrow pointing to "me".
public class Foo implements ActionListener {
public void actionPerformed(ActionEvent e) {
// do something useful with e
}
}
Here we've written a class Foo. Since we've said it implements ActionListener, it must have an actionPerformed() method. Anything can call that:
ActionListener listener = new Foo(...);
ActionEvent event = ...;
foo.actionPerformed(event);
And we can create a Foo and give it to something that generates events:
ActionListener listener = new Foo(...);
button.addListener(listener);
If we role-play the object, you can think of this last line as "Hey button! Tell listener whenever an action happens.".
Now, what if we want the listener to take control of who tells it what on its own? "Hey button, tell me whenever an action happens".
public class Foo implements ActionListener {
public attachToButton(JButton button) {
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// do something useful with e
}
}
It may help to imagine what the button's addActionListener code might look like:
public class JButton { // not the real JButton code, but it will be similar
private List<ActionListener> actionListeners = new ArrayList<ActionListener>();
public void addActionListener(ActionListener a) {
actionListeners.add(a);
}
// called internally when an event happens
private void onEvent(ActionEvent e) {
for(ActionListener listener : actionListeners) {
listener.actionPerformed(e);
}
}
}
So, if you're the listener that called addActionListener(this), then that List contains a reference that points right back at you, which the button uses to tap you on the shoulder every time an action occurs.

ActionListener principles

I am trying to find basic principles of adding action to JButton or other components. Here is what I am doing and what am I getting.
I have created a class named : Ali which has a main method in it, inside the main method Instantiate another method called: MainFrame and Whatever components I have I put in here.
I have created a simple button here, registered that with ActionListener interface, and I wrote an actionPerformed() method for that. Very simple and easy. But, somehow this program giving an error to me.
Here is the simplified codes and and errors.
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Ali{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame frame = new MainFrameAli2("MainFrameAli2");
frame.setSize(400,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
And here is the MainFrameAli2 class
public class MainFrameAli2 extends JFrame implements ActionListener {
public MainFrameAli2(String title){
super(title);
// set layout manager
setLayout(new BorderLayout());
// create swing component
JTextArea textArea = new JTextArea();
JButton button = new JButton("click");
// add swing components to content pane
Container c = getContentPane();
c.add(textArea, BorderLayout.NORTH);
c.add(button, BorderLayout.SOUTH);
// add behavior
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
System.out.println("Clicked");
}
});
}
}
Now the problem is code is not running, here is the error:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problems:
The public type MainFrameAli2 must be defined in its own file
The type MainFrameAli2 must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent)
And, if I write the code like below, everything is working OK.
// add behavior
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
System.out.println("hooyt");
}
}
Why it is not working in the first case and working in second case?
so, why it is not working in the first case and working in second case.?
Like the compiler message says, in the first example you didn't implement the ActionListener interface in your MainFrameAli2 class.
You created an anonymous inner class which implements the ActionListener interface. This is not the same thing as having your class implement the interface.
In the second example your class does implement the ActionListener.
If the first example you could have done:
//public class MainFrameAli2 extends JFrame implements ActionListener {
public class MainFrameAli2 extends JFrame {

Categories

Resources