So I have a class that extends a JPanel and within the constructor I add my JButtons and whatever else I need to add. I also have a MainFrame class that is the container (JFrame) and this class will take an argument from a class called FrameSwitcher (Controller) which will assess what buttons were clicked, and pass the information to the MainFrame
I'm having troubles doing this, I can't find a proper way to do this. I do also wish to maintain the JButtons private and non static.
JPanel example:
public class MainMenu() {
private JButton btnSinglePlayer, btnMultiPlayer;
public MainMenu() {
setLayout(null);
btnSinglePlayer = new JButton("singlePlayer");
btnSinglePlayer.setBounds(320, 25, 275, 130);
add(btnSinglePlayer);
btnMultiPlayer = new JButton("MultiPlayer");
btnMultiPlayer.setBounds(320, 170 , 275, 130);
add(btnMultiPlayer);
}
}
FrameSwitcher:
public class FrameSwitcher implements panelListener { // panelListener is an interface defined else where.
public FrameSwitcher(MainFrame frame) {
// This is irrelevant to the question.
}
#Override
public void gamePanel() {
System.out.println("GamePanel Event: Recieved");
}
#Override
public void mainMenu() {
System.out.println("mainMenu Event: Recieved");
}
#Override
public void scoreBoardPanel() {
System.out.println("scoreBoardPanel Event: Recieved");
}
}
Then my MainFrame:
public class MainFrame extends JFrame implements ActionListener {
private PanelListener panelListener;
private JFrame mainContainer = new JFrame("Game");
private JPanel mainMenu = new MainMenu();
public void start() {
mainContainer(mainMenu);
}
public MainFrame(JPanel frame) {
mainContainer.getContentPane().add(frame);
mainContainer.pack();
// Other methods to initialize the frame
return mainContainer;
}
public void switchFrames(PanelListener panelListener) {
this.panelListener = panelListener; // PanelListener is an interface.
}
public void actionPerformed(ActionEvent e) {
JButton source = (JButton)e.getsource();
if(source == MainMenu.btnSinglePlayer) {
if(panelListener != null) {
System.out.println("Recieved the event approriately.");
}
}
}
}
In this example, it does compile, but doesn't do what it is supposed to. Another thing is I currently have the JButtons as public and static, I don't want that.
In your MainMenu class, you need to add some kind of listener that interested parties can register with, so when some event occurs, they can be notified.
The simplest solution would be to provide a addActionListener method which delegated to each of the buttons. This, however, has may expose portions of the application you don't exposed (a listener now has direct access to the JButton and can do all kinds of nasty things to it).
A better solution would be to create something like a MainMenuListener which had methods like startSinglePlayer and startMultiPlayer
You would then provide a add/removeMainMenuListener method within in your MainMenu class.
Each button would then register there own actionListener and fire the appropriate menu listener event
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MainMenu extends JPanel {
private JButton btnSinglePlayer, btnMultiPlayer;
public MainMenu() {
setLayout(null);
btnSinglePlayer = new JButton("singlePlayer");
btnSinglePlayer.setBounds(320, 25, 275, 130);
add(btnSinglePlayer);
btnSinglePlayer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fireStartSinglePlayer();
}
});
btnMultiPlayer = new JButton("MultiPlayer");
btnMultiPlayer.setBounds(320, 170, 275, 130);
add(btnMultiPlayer);
btnMultiPlayer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fireStartMultiPlayer();
}
});
}
public void addMainMenuListener(MainMenuListener listener) {
listenerList.add(MainMenuListener.class, listener);
}
public void removeMainMenuListener(MainMenuListener listener) {
listenerList.remove(MainMenuListener.class, listener);
}
public void fireStartSinglePlayer() {
MainMenuListener[] listeners = listenerList.getListeners(MainMenuListener.class);
if (listeners != null && listeners.length > 0) {
for (MainMenuListener listener : listeners) {
listener.startSinglePlayer();
}
}
}
public void fireStartMultiPlayer() {
MainMenuListener[] listeners = listenerList.getListeners(MainMenuListener.class);
if (listeners != null && listeners.length > 0) {
for (MainMenuListener listener : listeners) {
listener.startMultiPlayer();
}
}
}
public interface MainMenuListener extends EventListener {
public void startSinglePlayer();
public void startMultiPlayer();
}
}
First you have to create an ActionListener like this
class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
//do your stuff
}
}
Then call,
yourButton.addActionListener(new MyActionListener());
Related
A Controller creates a new JFrame with a button. Using the actionListener is getting the order correctly but the action is asked to perform after is not working. Is asked to change a button name literal on the view but it never happens. Otherwise with debugging the function seems tu run but there is no change on the view.
With Java are implemented the following classes:
public class Window extends JFrame {
JButton bGoFile;
public static final String FILE = "FILE";
public Window(ActionListener actionListener) {
this.actionListener = actionListener;
setupButtons();
setupView();
}
private void setupButtons() {
bGoFile = new JButton("Button");
bGoFile.addActionListener(actionListener);
bGoFile.setActionCommand(GO_FILE);
}
private void setupView() {
setTitle("Cover pdf to img");
setBounds(300, 90, 900, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
ImageIcon icon = new ImageIcon("./src/resources/logo.jpg");
setIconImage(icon.getImage());
JPanel jp = new JPanel;
jp.add(bGoFile);
add(jp);
}
public void changeButtonName(String name) {
bGoFile.setText(name);
System.out.println("Name should be changed.");
// Here I already tried to user repaint() but with no result.
}
public class WindowController implements ActionListener {
Window window;
public WindowController() {
this.window = new Window(this);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action performed");
switch (e.getActionCommand()) {
case GO_FILE -> {
synchronized (this) {
window.changeButtonName("New name");
break;
}
}
}
}
The point is that the both prints on terminal are shown but the button name on the running Window is not changing.
You shouldn't be creating an instance of the view in the controller. This should be passed to the controller (AKA using dependency injection).
You should also be making use of interfaces, as the controller should not be bound to an implementation of a view (or model), but should be working through an established series of contracts and observers.
So, let's start with some basics...
public interface View {
public JComponent getView();
}
public interface Controller<V extends View> {
public V getView();
}
I did say basic. But, working with these interfaces directly will become tedious really fast, so let's add some helpers...
public abstract class AbstractController<V extends View> implements Controller<V> {
private V view;
public AbstractController(V view) {
this.view = view;
}
#Override
public V getView() {
return view;
}
}
public abstract class AbstractView extends JPanel implements View {
#Override
public JComponent getView() {
return this;
}
}
Nothing special, but this takes care of the a lot of boiler plating.
Next, we want to define the contract of our view...
public interface MainView extends View {
public interface Observer {
public void didPerformGoFile(MainView view);
}
public void addObserver(Observer observer);
public void removeObserver(Observer observer);
public void setDescription(String description);
}
That's pretty simple. Note though, this does not describe any kind of implementation detail. The contract does not care how didPerformGoFile might be generated, only that the action can be observed by interested parties
Next, we want to define or implementations for the MainView...
public class DefaultMainView extends AbstractView implements MainView {
private List<Observer> observers = new ArrayList<>(8);
private JButton goFileButton;
private JLabel descriptionLabel;
public DefaultMainView() {
goFileButton = new JButton("Make it so");
descriptionLabel = new JLabel("...");
descriptionLabel.setHorizontalAlignment(JLabel.CENTER);
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(goFileButton, gbc);
add(descriptionLabel, gbc);
goFileButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fireDidPerformGoFile();
}
});
}
#Override
public void addObserver(Observer observer) {
observers.add(observer);
}
#Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
protected void fireDidPerformGoFile() {
for (Observer observer : observers) {
observer.didPerformGoFile(this);
}
}
#Override
public void setDescription(String description) {
descriptionLabel.setText(description);
}
}
And MainController....
public class MainViewController extends AbstractController<MainView> {
public MainViewController(MainView view) {
super(view);
view.addObserver(new MainView.Observer() {
#Override
public void didPerformGoFile(MainView view) {
view.setDescription("Go file!");
}
});
}
}
Now, we can put them together and run them...
JFrame frame = new JFrame();
Controller controller = new MainViewController(new DefaultMainView());
frame.add(controller.getView().getView());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Now, you're probably sitting there thinking, "that's a lot of work for little gain" and you'd be ... wrong, actually.
Let's say you wanted to change how the controller responds to the goFileAction depending on some kind of state, like the user's credentials or something. You could put a lot of logic into the MainViewController to handle it, or, more easily, just create a different controller altogether (nb: This is where the model in "Model-View-Controller" would come in, but since there's no concept of model in your example, I've done it "differently")
public class OverlordController extends AbstractController<MainView> {
public OverlordController(MainView view) {
super(view);
view.addObserver(new MainView.Observer() {
#Override
public void didPerformGoFile(MainView view) {
view.setDescription("Your overload has spoken!");
}
});
}
}
Then, by simply changing...
Controller controller = new MainViewController(new DefaultMainView());
to
Controller controller = new OverlordController(new DefaultMainView());
you change the output!
"Model-View-Controller" is not as straight forward in Swing as it might be in other APIs/frameworks, this is because Swing is already based on MVC, so you're actually wrapping a MVC on a MVC. If you understand this, you can make it work more easily.
For example, above, I don't expose the ActionListener to the controller, instead I created my own observer which described the actual actions which might be triggered by implementations of the view. The actual action handling took place in the implementation of the view itself.
This is good in the fact that we've decoupled the workflow, it also means that the view is free to implement the triggers for these actions in any way it sees fit.
You might want to also take a look at:
Implementing the Controller part of MVC in Java Swing
How MVC work with java swing GUI
Java and GUI - Where do ActionListeners belong according to MVC pattern?
What is the correct way of Message Passing between Classes in MVC?
Listener Placement Adhering to the Traditional (non-mediator) MVC Pattern
JTextField input fails to update output in TextView in MVC
Multithreaded MVC to recreate plane dashboard with multiple independent gauges
Where to store model objects in MVC design?
Runnable example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
Controller controller = new OverlordController(new DefaultMainView());
frame.add(controller.getView().getView());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface View {
public JComponent getView();
}
public interface Controller<V extends View> {
public V getView();
}
public abstract class AbstractController<V extends View> implements Controller<V> {
private V view;
public AbstractController(V view) {
this.view = view;
}
#Override
public V getView() {
return view;
}
}
public abstract class AbstractView extends JPanel implements View {
#Override
public JComponent getView() {
return this;
}
}
public interface MainView extends View {
public interface Observer {
public void didPerformGoFile(MainView view);
}
public void addObserver(Observer observer);
public void removeObserver(Observer observer);
public void setDescription(String description);
}
public class MainViewController extends AbstractController<MainView> {
public MainViewController(MainView view) {
super(view);
view.addObserver(new MainView.Observer() {
#Override
public void didPerformGoFile(MainView view) {
view.setDescription("Go file!");
}
});
}
}
public class OverlordController extends AbstractController<MainView> {
public OverlordController(MainView view) {
super(view);
view.addObserver(new MainView.Observer() {
#Override
public void didPerformGoFile(MainView view) {
view.setDescription("Your overload has spoken!");
}
});
}
}
public class DefaultMainView extends AbstractView implements MainView {
private List<Observer> observers = new ArrayList<>(8);
private JButton goFileButton;
private JLabel descriptionLabel;
public DefaultMainView() {
goFileButton = new JButton("Make it so");
descriptionLabel = new JLabel("...");
descriptionLabel.setHorizontalAlignment(JLabel.CENTER);
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(goFileButton, gbc);
add(descriptionLabel, gbc);
goFileButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fireDidPerformGoFile();
}
});
}
#Override
public void addObserver(Observer observer) {
observers.add(observer);
}
#Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
protected void fireDidPerformGoFile() {
for (Observer observer : observers) {
observer.didPerformGoFile(this);
}
}
#Override
public void setDescription(String description) {
descriptionLabel.setText(description);
}
}
}
I am trying to do something when one of the arrow keys are pressed using the KeyListener in my JPanel class. Here is my code:
public class TestPanel extends JPanel implements KeyListener{
public TestPanel(){
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left");
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
My main method adds a new instance of this panel to a frame and displays it. Do I need to add the keylistener to the JFrame? In my case, this would be difficult and inefficient, so I would like to make it work with this JPanel if possible. Anyone know what I am doing wrong?
EDIT: Key Bindings code that does not work either:
public class GamePanel extends JPanel implements ActionListener{
//Constructor
public GamePanel(){
setupKeyBinding();
this.setFocusable(true);
this.requestFocusInWindow();
}
private void setupKeyBinding() {
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inMap = getInputMap(condition);
ActionMap actMap = getActionMap();
inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
actMap.put("Left", new leftAction());
}
private class leftAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
System.out.println("test");
}
}
public void actionPerformed(ActionEvent e) {
//some other game info
}
}
Can someone tell me why this doesnt work either? (my second action listener is for other stuff needed for my game)
If you search this problem, you'll see that it is asked and has been solved many times.
KeyListeners need to be on the focused component to work. One solution is to give your component the focus after first making it focusable.
Better by a long shot however is to use Key Bindings. Google the tutorial on this.
Please have a look at my answer to this question for more on this, including many of the gory details.
For reference, I've create an example using your approach; while it works, it also suggests a focus problem elsewhere in your code. Key Bindings avoid this, as shown here.
Addendum: Here's my working key binding.
private static class TestPanel extends JPanel {
private static final String LEFT = "Left";
private Action left = new AbstractAction(LEFT) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(LEFT);
}
};
private static final String RIGHT = "Right";
private Action right = new AbstractAction(RIGHT) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(RIGHT);
}
};
public TestPanel() {
this.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), LEFT);
this.getActionMap().put(LEFT, left);
this.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), RIGHT);
this.getActionMap().put(RIGHT, right);
}
}
Original SSCCE:
import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* #see https://stackoverflow.com/a/16531380/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class TestPanel extends JPanel implements KeyListener {
public TestPanel() {
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left");
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}
For receives key events on JPanel you must set focus:
setFocusable(true);
requestFocus();
the JPanel now has focus, so it receives key events
I had to do two things: I added comp.setFocusable(true); to the component comp that listens to key events, and I added comp.requestFocus(); to each action which caused comp to lose the focus.
i am in trouble with checking if the mouse has clicked with a JFrame. When i use public void mousePressed(MouseEvent e) to print something and i click with the mouse it doesn't print anything. It doesn't gives a error, it just prints nothing out. Here is my code :
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class tuna extends JFrame
{
private JTextArea textArea;
public static void main(String[] args)
{
//Run the program
tuna run = new tuna();
run.setDefaultCloseOperation(3);
run.setSize(1200, 1000);
run.setVisible(true);
}
public tuna()
{
super("Simple JFrame");
//add a simple JScrollPane
textArea = new JTextArea(10,10);
JScrollPane scrollPane = new JScrollPane(textArea);
textArea.setEditable(true);
add(scrollPane);
}
//This doesn't print anything when i am clicking in the JFrame
public void mousePressed(MouseEvent e)
{
if(e.getButton() == MouseEvent.BUTTON1)
{
System.out.println("left");
}
else if(e.getButton() == MouseEvent.BUTTON3)
{
System.out.println("right");
}
}
}
Thank you in advance.
You can make you own Mouse Listener and add it to textArea or another component.
For example like this:
public class tuna extends JFrame
{
private JTextArea textArea;
public static void main(String[] args)
{
//Run the program
tuna run = new tuna();
run.setDefaultCloseOperation(3);
run.setSize(1200, 1000);
run.setVisible(true);
}
public tuna()
{
super("Simple JFrame");
//add a simple JScrollPane
textArea = new JTextArea(10,10);
JScrollPane scrollPane = new JScrollPane(textArea);
textArea.setEditable(true);
textArea.addMouseListener(new CustomListener());
add(scrollPane);
}
//This doesn't print anything when i am clicking in the JFrame
public class CustomListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent mouseEvent) {
if(mouseEvent.getButton() == MouseEvent.BUTTON1)
{
System.out.println("left");
}
else if(mouseEvent.getButton() == MouseEvent.BUTTON3)
{
System.out.println("right");
}
}
#Override
public void mousePressed(MouseEvent mouseEvent) {
}
#Override
public void mouseReleased(MouseEvent mouseEvent) {
}
#Override
public void mouseEntered(MouseEvent mouseEvent) {
}
#Override
public void mouseExited(MouseEvent mouseEvent) {
}
}
}
Well there are few issues, in your concept and source code
First you need a MouseListener, so in your case either you can
create a separate MouseListener or use the current JFrame class
itself, like this
public class Tuna extends JFrame implements MouseListener
Also I would recommend to follow proper naming convention and use Tuna instead of tuna.
Then the element you want to respond on the MouseEvents should be
register with the MouseListener created in first step, in your constructor.
textArea.addMouseListener(this);
Also make sure on what element you want to register your
MouseListener, currently your entire Frame is covered by TextArea,
so registering listener on JFrame won't help, instead add it on
JTextArea
Try using #Override annotation where ever possible, editor shows
appropriate compiler errors then, in your case you just wrote,
public void mousePressed(MouseEvent e)
instead of
#Override
public void mousePressed(MouseEvent e)
As this methods works only if you implement an MouseListener
Refer this link for more understanding,
https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
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);
}
}
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.
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);
}
}
I am really struggling with making a program that has buttons on it and when a button is clicked, it calls a class to work. I have only been using Java for about 10 weeks now and I get the basics but I have not found any place that gives me an understanding of what I want to do here.
I have tried
public void mouseEntered(MouseEvent e) {
if (e.getButton()== MouseEvent.BUTTON3){
Object triangle;
Frame.class.getClass();
}
}
I have also tried
panel.addMouseListener(new MouseAdapter() {
if (e.getButton()== MouseEvent.BUTTON1) {
Frame.class.getClass(circle); }
Either way I have tried it I usually get an error unable to find object or The method getClass() in the type Objectis not applicable for the arguments (JButton).
Can anyone please help me try to figure out what I am doing wrong?
Thank you.
public class MainFrame extends JFrame {
private JButton button = new JButton("Run AnotherClass");
MainFrame() {
super();
this.setTitle("Demo App");
this.setSize(200,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.add(button);
button.addActionListener(new ButtonHandler());
}
public class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
new AnotherClass();
}
}
public static void main(String[] args) {
new MainFrame().setVisible(true);
}
}
public class AnotherClass {
public AnotherClass() {
JOptionPane.showMessageDialog(null, "AnotherClass is in operation");
}
}