Actions performed on jButton after disabling - java

I have sample code using Swing.
package playerlist;
import java.awt.FlowLayout;
import javax.swing.*;
import java.awt.event.*;
public class Sample extends JFrame{
private JButton button1;
private JButton button2;
public Sample(){
super();
setTitle("Sample JFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button1 = new JButton("Button 1");
button2 = new JButton("Button 2");
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
button1ActionPerformed(e);
}
});
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
button2ActionPerformed(e);
}
});
setLayout(new FlowLayout());
add(button1);
add(button2);
pack();
}
private void button1ActionPerformed(ActionEvent ae){
button1.setEnabled(false);
button2.setEnabled(false);
try{
Thread.sleep(5000);
}catch(Exception e){
}
System.out.println("*** Button 1 Clicked ***");
button1.setEnabled(true);
button2.setEnabled(true);
}
private void button2ActionPerformed(ActionEvent ae){
button1.setEnabled(false);
button2.setEnabled(false);
try{
Thread.sleep(5000);
}catch(Exception e){
}
// I have disabled this button from button 1's action, but still when I click this button within
// 5 seconds, actions of this button is performed
System.out.println("*** Button 2 Clicked ***");
button1.setEnabled(true);
button2.setEnabled(true);
}
public static void main(String [] args){
new Sample().setVisible(true);
}
}
I want like - when I click button1(when button1's action starts), button1 and button2 should be disabled(if I click on disabled button, no actions should be performed). I have disabled both buttons using setEnabled(false). And when action of button1 completes, both buttons should be enabled.
But in my code this is not working, even after disabling button, actions are being performed on disabled button.
In action of button1 I have disabled both buttons and used sleep method to pause execution (for simulating heavy work) for 5 seconds, but within 5 seconds If I click any buttons, their actions are triggered after completion of action of button1.
Please help me. I have provided sample code, when you run it, and after clicking button1, then immediately button2, actions of both buttons are performed.
I want when I press any buttons, heavy work will be done in button's click action, and meanwhile I will disable all buttons, so no other actions can be performed. When first action completes, I will enable all buttons.
Please help me.
Thanks in advance.

logic of code could be correct,
but with one mistake you bloking by Thread.sleep(int) the Event Dispatch Thread
have to change Thread.sleep(int) to Swing Timer
then 1st step is JButton#setEnabled(false) , rest of code should be fired from Swing Action invoked from Swing Timer

I got this working by running task to be performed on click of button on new thread.

Related

Where ActionListener's actionPerformed() is called in a code

Here is a code which handles button click:
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// handle the button click
}
});
I know that actionPerfomed is called when a user clicks a button. But where to find the call in the Java source code library? Where does all the magic happen?

How to enable buttons at start of gui in Netbeans

This is not a duplicate as I already know the code .setEnabled(false);. My problem is that I am making a gui in netbeans and I cannot figure out how to disable/enable buttons. Obviously I am new to JAVA and Netbeans This is what I have to do:
Start the program with all buttons disabled except the Initialize
button.
When Initialize is pressed the ArrayList will be filled with 5 CD
titles. The Initialize button then becomes disabled and the other
buttons become enabled.
The only code I know for buttons is .setEnabled(false); but it only disables button after I click it and what i need is to make one enabled and rest disabled. After I click it, it should be disabled and rest should be enabled.
The current code is not relevant but if you need it I will edit this post! Any help is greatly appreciated and thank you in advance!
You need to use interface ActionListener and add ActionListener after clicking
of button. Implement default method ActionPerformed. Use this code as example.
import java.awt.*;
import java.awt.event.*;
class calc extends Frame implements ActionListener
{
TextField t1 =new TextField(20);
TextField t2 =new TextField(29);
TextField t3 =new TextField(29);
Label l1=new Label("first");
Label l2=new Label("second");
Label l3=new Label("sum");
Button b1=new Button("Add");
Button b2=new Button("close");
calc() //CONSTRUCTOR
{
add(l1);add(t1);
add(t2);add(l2);
add(t3);add(l3);
add(b1);
add(b2);
setSize(444,555);
setVisible(true);
setLayout(new FlowLayout());
b1.addActionListener(this);
b2.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
Object o=e.getSource();
if(o==b2)
{
System.exit(1);
}
String n1=t1.getText();
String n2=t2.getText();
int a=Integer.parseInt(n1);
int b=Integer.parseInt(n2);
t3.setText(""+(a+b));
}
}
class Gi
{
public static void main(String[] args)
{
new calc();
}
}

display an icon in a JButton and hide it

I have a JButton, and I want when I click to this button to display an icon in it then after 3 seconds to hide the icon and display a text in the button.
in the action listener I tried this code :
JButton clickedButton = (JButton) e.getSource();
clickedButton.setIcon(new ImageIcon(images.get(clickedButton.getName())));
try {
Thread.sleep(3000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
clickedButton.setText("x");
clickedButton.setIcon(null);
The problem is that when I click in the button the program blocks for 3 minutes then the text "x" displayed in the button.
How can I solve this problem ?
Don't call Thread.sleep(...) on the Swing event thread since that freezes the thread and with it your GUI. Instead use a Swing Timer. For example:
final JButton clickedButton = (JButton) e.getSource();
clickedButton.setIcon(new ImageIcon(images.get(clickedButton.getName())));
new Timer(3000, new ActionListener(){
public void actionPerformed(ActionEvent evt) {
clickedButton.setText("x");
clickedButton.setIcon(null);
((Timer) evt.getSource()).stop();
}
}).start();
As suggested you don't need to use Thread.Sleep use Swing Timer to perform this task.
// Declare button and assign an Icon.
Icon icon = new ImageIcon("search.jpg");
JButton button = new JButton(icon);
ChangeImageAction listener = new ChangeImageAction(button);
button.addActionListener(listener);
Below ChangeImageAction class will do the necessary action when the button is clicked.
When you click on the button an action is fired and in this action we will call the Timer's Action listener where we set the button's icon as null and give the button a title.
class ChangeImageAction implements ActionListener {
private JButton button;
public ChangeImageAction(JButton button) {
this.button = button;
}
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
button.setIcon(null);
button.setText("Button");
}
};
#Override
public void actionPerformed(ActionEvent arg0) {
Timer timer = new Timer( 3000 , taskPerformer);
timer.setRepeats(false);
timer.start();
}
}
P.S: I am trying Timer for the first time thanks to #Hovercraft Full Of Eels for the suggestion.

Thread sleep in actionPerformed

I am trying to make a tiny program that has 3 buttons, all of them of white color. Pressing the first button (that has the text "Go!") will cause the second button to become orange for 3 seconds and then, after that time, it will become white again AND the third button will become permanently green.
However, in my following code, I have a problem achieving this: When hitting the button "Go!", it causes my program to somewhat freeze for 3 seconds and then the third button becomes green. Can you please help me?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Example extends JFrame
{
public Example(String title)
{
super(title);
GridLayout gl = new GridLayout(3,1);
setLayout(gl);
final JButton b1 = new JButton("Go!");
final JButton b2 = new JButton();
final JButton b3 = new JButton();
b1.setBackground(Color.WHITE);
b2.setBackground(Color.WHITE);
b3.setBackground(Color.WHITE);
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
b2.setBackground(Color.ORANGE);
try
{
Thread.sleep(3000);
} catch (InterruptedException ie) {}
b2.setBackground(Color.WHITE);
b3.setBackground(Color.GREEN);
}
});
add(b1);
add(b2);
add(b3);
setSize(50,200);
setVisible(true);
}
public static void main(String[] args)
{
Example ex = new Example("My Example");
}
}
Swing is single threaded. Calling Thread.sleep in the EDT prevents UI updates. Use a Swing Timer instead.
You're calling Thread.sleep(3000) on the main thread. Hence why your program freezes for three seconds. As #MarounMaroun suggested, you should use a SwingWorker. Here is the documentation.

How can I create a "Drop-Down" menu in a Java Swing toolbar?

I've created a drop-down menu on my Swing JToolBar. But it doesn't create behave the way I want. I'm aiming for it to work like Firefox's "Smart Bookmarks" button.
It disappears when the user selects a menu item: CORRECT!
It disappears when the user presses ESC: CORRECT!
It disappears when the user clicks somewhere in the main frame outside of the menu: CORRECT!
But it doesn't disappear when the user clicks a second time on the button that shows the drop-down menu: INCORRECT... :-(
My question is how can I add this behaviour, that it does disappear when the clicks on the button that shows the menu a second time.
Here's my current code, from Java 6 on the Mac:
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class ScratchSpace {
public static void main(String[] arguments) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Toolbar with Popup Menu demo");
final JToolBar toolBar = new JToolBar();
toolBar.add(createMoreButton());
final JPanel panel = new JPanel(new BorderLayout());
panel.add(toolBar, BorderLayout.NORTH);
panel.setPreferredSize(new Dimension(600, 400));
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private static AbstractButton createMoreButton() {
final JToggleButton moreButton = new JToggleButton("More...");
moreButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
createAndShowMenu((JComponent) e.getSource(), moreButton);
}
}
});
moreButton.setFocusable(false);
moreButton.setHorizontalTextPosition(SwingConstants.LEADING);
return moreButton;
}
private static void createAndShowMenu(final JComponent component, final AbstractButton moreButton) {
JPopupMenu menu = new JPopupMenu();
menu.add(new JMenuItem("Black"));
menu.add(new JMenuItem("Red"));
menu.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
moreButton.setSelected(false);
}
public void popupMenuCanceled(PopupMenuEvent e) {
moreButton.setSelected(false);
}
});
menu.show(component, 0, component.getHeight());
}
}
Well, here is a potential solution that is not without it's drawbacks. Only you can decide if this is acceptable for your application. The issue is that the popup closing occurs before other mouse-handling events are fired so clicking on your More.. button again causes the popup to hide, thus resetting the buttons state to deselected BEFORE the button even gets told it was pressed.
The easy workaround is to add the following call within your main program:
UIManager.put("PopupMenu.consumeEventOnClose", Boolean.TRUE);
The result of this is that whenever a popup menu is closed because of a mouse-pressed event, that mouse event will be consumed at the time the menu is closed and won't be passed on to any other components under the mouse. If you can live with limitation, this is an easy solution.
What's happening is that when you click off the menu, it cancels the popup menu, so you deselect the button, but the next immediate event is clicking the button, and now its deselected so it shows the menu again.
I don't have the exact solution yet, but give me a little bit ...
I don't use Firefox so I don't know what the Smart Bookmarks button looks like, but maybe use a JMenu as the "button". You could try using the Border of a JButton to make it look more like a button.
Well, the listener on the button reacts only when it is pushed down, because you listen for ItemEvent.SELECTED events only. How about adding another if clause to listen for ItemEvent.DESELECTED events here:
moreButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
createAndShowMenu((JComponent) e.getSource(), moreButton);
}
}
});
You could either store a reference to the menu somewhere, or you could make the menu itself add another listener to the button. The latter solution could be more straightforward, since you already seem to send a button reference to the menu.

Categories