I am new in Java and also in StackOverflow so, please excuse me if I do wrong something. I will correct it immediately!
My question is: How could I return a variable which is in a class that implements an ActionListener
into another class's variable?
The class that implements the ActionListener
is not an inner class.
I voluntary omitted imports.
Here an example:
File_A.java
public class Gui extends JFrame {
private JButton myButton;
private String path;
some other properties...
public Gui () {
myButton = new JButton("Some Text");
myButton.AddActionListener(new Pick_Something());
}
}
File_B.java
public class Pick_Something implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser selectElement = new JFileChooser();
String path;
int status = selectElement.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION)
path = selectElement.getSelectedFile().getAbsolutePath();
else
path = null;
}
}
How could I return File_B.java
's path
variable in File_A.java
's path
variable?
I tried to write a method who returns it but the method does not appear in the list of all methods so it is impossible to call. And I tried also to extends Pick_Something
with Gui
and make path
protected but I had a StackOverflowError
.
Anyone see what I do wrong or have an idea about how to do?
I would recommend using a call-back, something that Java-8's java.util.function
supplies for you, and in fact a Consumer<String>
would work perfectly here. Create your Consumer in the original class, and have the ActionListener class call its .accept(...)
method, passing information directly from the listener class to the GUI with low coupling. For example if your Gui has a JTextField called filePathTxtField
that you want filled with the user's file path of choice, one obtained by the ActionListener, then the consumer could look like so:
Consumer<String> consumer = (String text) -> {
filePathTxtField.setText(text);
};
This would be created in the Gui class, and then passed into the ActionListener class via a constructor parameter:
// in the Gui class's constructor
button.addActionListener(new PickSomething(consumer));
// the PickSomething class and its constructor
class PickSomething implements ActionListener {
private Consumer<String> consumer;
public PickSomething(Consumer<String> consumer) {
this.consumer = consumer;
}
Then the actionPerformed method could look like:
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser selectElement = new JFileChooser();
String path;
// get the path String and set it
int status = selectElement.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION) {
path = selectElement.getSelectedFile().getAbsolutePath();
} else {
path = null;
}
// pass the path String into the Gui by calling the call-back method, passing it in
consumer.accept(path);
}
The whole thing could look like:
import java.util.function.Consumer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class Gui extends JPanel {
private JTextField filePathTxtField = new JTextField(45);
private int foo = 0;
public Gui() {
filePathTxtField.setFocusable(false);
add(filePathTxtField);
JButton button = new JButton("Get File Path");
Consumer<String> consumer = (String text) -> {
filePathTxtField.setText(text);
};
button.addActionListener(new PickSomething(consumer));
add(button);
}
private static void createAndShowGui() {
Gui mainPanel = new Gui();
JFrame frame = new JFrame("Gui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.function.Consumer;
import javax.swing.JFileChooser;
public class PickSomething implements ActionListener {
private Consumer<String> consumer;
public PickSomething(Consumer<String> consumer) {
this.consumer = consumer;
}
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser selectElement = new JFileChooser();
String path;
int status = selectElement.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION) {
path = selectElement.getSelectedFile().getAbsolutePath();
} else {
path = null;
}
consumer.accept(path);
}
}