Reputation: 305
I'm trying to separate my Swing GUI from my actual code. In short, I want the user to kick off a process (based on the user's selections); in this case, the JFrame will no longer be needed.
What I couldn't figure out is how to share the user's selection from the GUI.class with the Main.class.
Do you have any advice for me?
Here's my code:
public class Main {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI(templates);
gui.setVisible(true);
}
});
// Kick off a process based on the user's selection
}
}
public class GUI extends JFrame {
private static final long serialVersionUID = 1L;
public GUI(Object[] objects) {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 100);
setLocationRelativeTo(null);
JPanel cp = new JPanel();
cp.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(cp);
JLabel lbl = new JLabel("Selection:");
cp.add(lbl);
final JComboBox<String> comboBox = new JComboBox<String>(new String[] { "One", "Two", "Three" });
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
}
});
cp.add(comboBox);
}
}
Upvotes: 1
Views: 1068
Reputation: 46871
A Good way of doing this is use Callback
mechanism.
Steps to follow:
create a callback interface
interface Callback {
void execute(Object result);
}
GUI
class will implement Callback
interface but without providing any implementation
Make GUI
class abstract
abstract class GUI extends JFrame implements Callback
Now create an object of GUI
class providing actual implementation of Callback
interface
Here you can use Anonymous class
GUI gui = new GUI() {
@Override
public void execute(Object result) {
System.out.println("You have selected " + result);
}
};
You can pass any thing in execute()
method of Callback
.
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
// Callback
execute(comboBox.getSelectedItem());
}
});
Here Main
class is responsible for capturing the response of Callback
that is directed by GUI
class.
Here is the code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI() {
@Override
public void execute(Object result) {
System.out.println("You have selected " + result);
}
};
gui.setVisible(true);
}
});
// Kick off a process based on the user's selection
}
}
interface Callback {
void execute(Object result);
}
abstract class GUI extends JFrame implements Callback {
private static final long serialVersionUID = 1L;
public GUI() {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 100);
setLocationRelativeTo(null);
JPanel cp = new JPanel();
cp.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(cp);
JLabel lbl = new JLabel("Selection:");
cp.add(lbl);
final JComboBox comboBox = new JComboBox(new String[] { "One", "Two", "Three" });
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
execute(comboBox.getSelectedItem());
}
});
cp.add(comboBox);
}
}
Upvotes: 0
Reputation: 616
You could create an object to store the selection result and pass it in to the constructor of the GUI class. Set the selection result in that object before closing the UI and then your Main class could access the value:
public class SelectionResult {
private String selectionResult;
public void setSelectionResult(final String selectionResult) {
this.selectionResult = selectionResult;
}
public String getSelectionResult() {
return this.selectionResult;
}
}
Then, you could modify the GUI constructor like this:
private final SelectionResult selectionResult;
public GUI(Object[] objects, SelectionResult selectionResult) {
this.selectionResult = selectionResult;
...
Create a SelectionResult object in your Main class, and pass it to the constructor of the GUI class. In you GUI class ActionListener, you can then call the setSelectionResult() method with the selected value and that value will be available from the Main class.
You would need to add code to make your main method wait while you are waiting for the value to be set in the UI and then proceed with your logic based on the selection.
Upvotes: 1