Enable one JButton and disable another - java

There are two buttons in my ui which re-directs to two JFrames. I am trying to make that if user press button one, button two becomes disabled, and if the user presses button two, button one becomes disabled, so that the user cannot open both the JFrames at the same time.
import java.awt.*;
import java.awt.event.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class Main extends JFrame {
public Main() {
JPanel panel = new JPanel();
getContentPane().add (panel,BorderLayout.NORTH);
JButton button1 = new JButton("One");
panel.add(button1);
JButton button2 = new JButton("Two");
panel.add(button2);
button1.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
button2.setEnabled(false);
One f = new One();
f.setSize(350,100);
f.setVisible(true);
}
});
button2.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
button1.setEnabled(false);
Two fr = new Two();
fr.setSize(350,100);
fr.setVisible(true);
}
});
public void enableButtons()
{
button1.setEnabled(true);
button2.setEnabled(true);
}
}
public static void main(String[] args) {
Main frame = new Main();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
enableButtons();
System.exit(0);
}
});
frame.setSize(300,200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}

In your ActionListener for Button One, add
ButtonTwo.setEnabled(false);
and in the ActionListenerfor Button Two add
ButtonOne.setEnabled(false);
Don't forget to add the corresponding enables (button.setEnable(true)) otherwise you will be left with two disabled buttons. Maybe in an event for closing the JFrames.
EDIT:
You can write a method like this
public void enableButtons()
{
button1.setEnabled(true);
button2.setEnabled(true);
}
Call this method in an event of JFrame closing.
This tutorial explains the JFrame closing event.

Check out the ButtonGroup for a more elegant solution.
http://docs.oracle.com/javase/tutorial/uiswing/components/buttongroup.html

Related

My Buttons won't execute the command given to them

I am trying to get the buttons to at least execute something when they are pressed and BlueJ doesn't show any errors, but when I execute the Program and I try to press the buttons, nothing happens. I am really unsure why that is the case. I would appreciate any help!
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class MainMenu
{
JFrame frame= new JFrame();
JButton button = new JButton("Singleplayer");
JButton button2 = new JButton("Multiplayer");
MainMenu(){
prepareGUI();
}
public void prepareGUI(){
frame.setTitle("Game");
frame.getContentPane().setLayout(null);
frame.add(button);
frame.add(button2);
button.setBounds(100,200,100,40);
button2.setBounds(200,200,100,40);
frame.setVisible(true);
frame.setBounds(200,200,400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void setUpButtonListeners(){
ActionListener buttonlistener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.getContentPane().setBackground(Color.green);
System.out.println("Singleplayer Selected");
}
};
ActionListener buttonlistener2 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
frame.getContentPane().setBackground(Color.red);
System.out.println("Multiplayer Selected");
}
};
button.addActionListener(buttonlistener);
button2.addActionListener(buttonlistener2);
}
public class MainClass {
public void main(String args[] )
{
new MainMenu();
}
}
}
setUpButtonListeners() are not executed in the program. So action listeners are not available. you can include setUpButtonListeners() in prepareGUI method.

How do I "activate" a button on the GUI?

By now, I already know my code is flawed. I just want to know why it's flawed. I want to activate the "webButton" so that when it gets clicked, it prints a message on the console that reads "This opens Mozilla Firefox."
package smartphone;
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.util.Scanner;
public class Smartphone implements ActionListener {
public static void main(String[] args) {
{
{
JFrame container = new JFrame();
container.setLayout(new BorderLayout());
Scanner daniel = new Scanner(System.in);
JButton webButton = new JButton(new ImageIcon("Firefox.png"));
JButton phoButton = new JButton(new ImageIcon("Facebook.png"));
JButton texButton = new JButton(new ImageIcon("Phone.png"));
JButton setButton = new JButton(new ImageIcon("Settings.png"));
JButton smsButton = new JButton(new ImageIcon("sms.png"));
container.setTitle("Smartphone Interface!");
container.setSize(240,340);
container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container.add(setButton, BorderLayout.CENTER);
container.add(webButton, BorderLayout.SOUTH);
container.add(texButton, BorderLayout.NORTH);
container.add(phoButton, BorderLayout.EAST);
container.add(smsButton, BorderLayout.WEST);
container.setVisible(true);
webButton.addActionListener(instanceofSmartphone);
}
}
}
}
Do this.
webButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
}
});
If you want to use the ActionListener interface then, implement it in your Frame class and then replace that instanceOfSmartphone with
webButton.addActionListener(this);
And put this outside the method
public void actionPerformed(ActionEvent e) {
if(e.getSource() == webButton) {
}
}
You need to implement the actionPerformed method. An example follows.
public void actionPerformed(ActionEvent e) {
System.out.println("This method opens Mozilla Firefox.");
}
Additionally, you need to change how you add the action listener to the following.
webButton.addActionListener(this);
There are also a number of other issues. Here is a modified version of your code to get it working but far from perfect or what you will want in the end. I strongly recommend you walk through all of the tutorials in order at the below website. It doesn't get any easier than what they have. Also, if your not already using it, you should try Netbeans or some other IDE. It give you feedback that may help while you are starting out.
https://docs.oracle.com/javase/tutorial/
package smartphone;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.Scanner;
public class Smartphone extends Frame implements ActionListener {
static JButton webButton = new JButton(new ImageIcon("Firefox.png"));
static JButton phoButton = new JButton(new ImageIcon("Facebook.png"));
static JButton texButton = new JButton(new ImageIcon("Phone.png"));
static JButton setButton = new JButton(new ImageIcon("Settings.png"));
static JButton smsButton = new JButton(new ImageIcon("sms.png"));
Smartphone(){
webButton.addActionListener(this);
}
public static void main(String[] args) {
Smartphone container = new Smartphone();
container.setLayout(new BorderLayout());
Scanner daniel = new Scanner(System.in);
container.setTitle("Smartphone Interface!");
container.setSize(240, 340);
container.add(setButton, BorderLayout.CENTER);
container.add(webButton, BorderLayout.SOUTH);
container.add(texButton, BorderLayout.NORTH);
container.add(phoButton, BorderLayout.EAST);
container.add(smsButton, BorderLayout.WEST);
container.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("This opens a Firefox Webbrowser.");
}
}
You need to add an ActionListener to the buttons INSIDE of the constructor: buttonName.addActionListener(this);.
Then you need to create the following method:
public void actionPerformed(ActionEvent event) {
Object control = event.getSource();
if (control == buttonName) {
//Run code...
}
}

JButton with both ActionListener / MouseListener

Is it possible to create a Jbutton with both an ActionListener and MouseListener
Meaning so i create a button and then when i press it ( throught actionListener) it changes the frame so that AFTER then button was pressed i can press anywhere on the frame and MouseListener would in use.
JButton button = new JButton();//Creates Button
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Insert MouseListener
//Then do something with mouseListener
}
});
Heres the curent code: however they're now in sync when i try to click the button and i cannot call mouseListener a 2nd time
JButton button2 = new JButton("Click");
button2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("You clicked the button");
newCube.stopCube();
}
});
button2.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mousePressed(java.awt.event.MouseEvent evt)
{
double x = evt.getX();
double y = evt.getY();
newCube.setCube(x,y);
}
});
If you want to move something by clicking on it, you can use a mouse listener on that node directly, instead of using it on the button.
To add both the action listener and a mouse listener on a button, you can use the addActionListener and addMouseListener methods on the button.
Look at the api for information about these methods... http://docs.oracle.com/javase/7/docs/api/javax/swing/JButton.html
If I understood you correctly, this sample might help you (add this to your own ActionListener)
#Override
public void actionPerformed(ActionEvent e) {
((JButton)e.getSource()).addMouseListener(yourMouseListener);
}
I tried this, it works.
Here is example with JToggleButton which add/remove MouseListener to JFrame.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
public class Example extends JFrame {
private MouseAdapter mouseListener;
public Example(){
init();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void init() {
mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("clicked");
}
};
setLayout(new FlowLayout());
JToggleButton b = new JToggleButton("add listener");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(((JToggleButton)e.getSource()).isSelected()){
Example.this.addMouseListener(mouseListener);
((JToggleButton)e.getSource()).setText("remove listener");
} else {
Example.this.removeMouseListener(mouseListener);
((JToggleButton)e.getSource()).setText("add listener");
}
}
});
add(b);
}
public static void main(String... s){
new Example();
}
}
EDIT: examle with JButton:
public class Example extends JFrame {
private MouseAdapter mouseListener;
public Example(){
init();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void init() {
mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("clicked");
}
};
setLayout(new FlowLayout());
JButton b = new JButton("add listener");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(((JButton)e.getSource()).getText().equals("add listener")){
Example.this.addMouseListener(mouseListener);
((JButton)e.getSource()).setText("remove listener");
} else {
Example.this.removeMouseListener(mouseListener);
((JButton)e.getSource()).setText("add listener");
}
}
});
add(b);
}
public static void main(String... s){
new Example();
}
}
What you want to do is still not clear to me. Though this can help you. It will add a mouse listner to the component when the start button is clicked and remove the mouse listner when stop button is clicked. Thus you can stop the two listeners from working in sync..
JButton startButton = new JButton();
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Add MouseListener to move the component
}
});
JButton stopButton = new JButton();
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Remove the MouseListener
}
});

Lose Focus on JTextField when clicking on the panel

I want to lose the focus on a JTextField when the user is clicking on the main panel.
setFocusable(true) doens't work for me.
If I am clicking on the main panel, the JTextField has still the focus and you can enter stuff.
Note: My JFrame is set to focusable (true).
I think since you want to get the focus on clicking the main panel, you should implement a simple MouseListener to do the job for you. Again since the panel (main panel) is added to the JFrame or rather it's set as the content pane, that is the place where setFocusable(true); should be called. The code below should sort out the problem :
mainPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseReleased(e);
Focus.this.grabFocus();
}
});
Please note that Focus is the name of my class and am extending the JPanel before adding it to the JFrame.
Note: My JFrame is set to focusable (true).
for example
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class JPanelAndFocus {
private JFrame frm = new JFrame("JPanel_And_Focus");
private JPanel panel = new JPanel();
private JTextField one = new JTextField(10);
private JTextField two = new JTextField(10);
private JTextField three = new JTextField(10);
public JPanelAndFocus() {
//panel.setLayout(new FlowLayout());
panel.add(one);
panel.add(two);
panel.add(three);
panel.setFocusable(true);
panel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
//delayed should be important for events from DocumentListener / InputMask
#Override
public void run() {
//panel.requestFocus();
panel.requestFocusInWindow();
}
});
}
});
panel.setPreferredSize(new Dimension(400, 100));
frm.add(panel);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setLocation(400, 300);
frm.pack();
frm.setVisible(true);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//one.requestFocus();
one.requestFocusInWindow();
}
});
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JPanelAndFocus jpaf = new JPanelAndFocus();
}
});
}
}
Whereas the different methods cited above didn't work for me, meaning that the focus remained on the JButton, I find e.getSource() works to set the component focus right
YourContainerPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
JComponent clicked = (JComponent)e.getSource();
clicked.requestFocusInWindow();
}
});
Try this
this.getParent().requestFocus()

How to set the Java default button to react on ENTER key _released_?

In my application I use a Default button. I want it to react when ENTER Key is released. Not when ENTER Key is pressed.
I removed the KeyStroke from InputMap of the button. But it didn't work for me. How should i do that?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class ButtonTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
buildFrame();
}
});
}
private static void buildFrame() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JButton button = new JButton(new AbstractAction("Button") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ButtonTest::actionPerformed: CALLED");
}
});
JButton button2 = new JButton("Button 2");
InputMap im = button.getInputMap();
im.put(KeyStroke.getKeyStroke("ENTER"), "none");
im.put(KeyStroke.getKeyStroke("released ENTER"), "released");
f.setLayout(new GridBagLayout());
f.add(button);
f.add(button2);
f.getRootPane().setDefaultButton(button);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
This is the sample code.
JRootPane rootPane = SwingUtilities.getRootPane(/* Your JButton */);
rootPane.setDefaultButton(/* Your JButton */);
the keys for the default button (that is, the button that is triggered on enter, no matter which component is focusOwner) are bound in the rootPane's componentInputMap, that is its inputMap of type WHEN_IN_FOCUSED_WINDOW. So technically, that's the place to tweak:
JComponent content = new JPanel();
content.add(new JTextField("some focusable"));
content.add(new JTextField("something else"));
JXFrame frame = wrapInFrame(content, "default button on released");
Action action = new AbstractAction("do something") {
#Override
public void actionPerformed(ActionEvent e) {
LOG.info("clicked");
}
};
JButton button = new JButton(action);
content.add(button);
frame.getRootPane().setDefaultButton(button);
// remove the binding for pressed
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("ENTER"), "none");
// retarget the binding for released
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("released ENTER"), "press");
Beware: this is still different from the pressed/released behaviour of a non-default button because the rootPane action simply call's button.doClick without going through the moves of arming/pressing the buttonModel to indirectly trigger the action.
InputMap im = button.getInputMap();
im.put(KeyStroke.getKeyStroke("ENTER"), "pressed");
im.put(KeyStroke.getKeyStroke("released ENTER"), "released");
The effect of this is that the button executes its actionPerformed only once, when the ENTER is released (if I understand correctly, this is what you want).
EDIT: the running following code demonstrates that the actionPerformed is executed only at ENTER release (although visually the button appears pressed already on ENTER press)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class ButtonTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
buildFrame();
}
});
}
private static void buildFrame() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JButton button = new JButton(new AbstractAction("Button") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ButtonTest::actionPerformed: CALLED");
}
});
InputMap im = button.getInputMap();
im.put(KeyStroke.getKeyStroke("ENTER"), "pressed");
im.put(KeyStroke.getKeyStroke("released ENTER"), "released");
f.add(button);
f.getRootPane().setDefaultButton(button);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
You can use the version of getKeyStroke() that lets you set onKeyRelease to true, like in this answer
Edit: You can stop repeats, like in this answer.

Categories