display an icon in a JButton and hide it - java

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.

Related

Can you put an action listener inside an action listener?

When I press button labeled "one", my popup window freezes up, and I think it's because I'm trying to put a button with an action listener into the action listener of another button. Is that possible?
//code...
one = new JButton("Customize Race");
one.setBounds(30,200,200,75);
one.addActionListener(new ActionListener(){
#Override
public void actionPerformed( ActionEvent e ) {
one.setVisible(false);
Boolean pic = true;
String Player1 = "Player1";
while (pic == true)
{
p1 = new JButton(Player1);
p1.setBounds(50, 50, 200, 100);
p1.addActionListener(new ActionListener(){
#Override
public void actionPerformed( ActionEvent e ) {
// code that will pull up menu to
customize string value of Player1
}
});
next1 = new JButton("Next =>");
next1.setBounds(50, 375, 450, 50);
next1.addActionListener(new ActionListener(){
#Override
public void actionPerformed( ActionEvent e ) {
Boolean pic = false;
}
});
panel.add(p1);
panel.add(next1);
}
p1.setVisible(false);
}
});
panel.add(one);
frame.setVisible(true);
Can you put an action listener inside an action listener?
Yes you can create a component in your ActionListener and add an ActionListener to the new component.
That is not the problem.
my popup window freezes up,
while (pic == true)
The problem is you have a while loop that continues to execute.
Your ActionListener is continually creating components and adding them to the frame and the loop never ends.
Get rid of the while loop!!!
Also, when you add components to a visible frame the code should be:
panel.add(....);
panel.revalidate();
panel.repaint();
The revalidate() invokes the layout manager so the component can be positioned properly and the repaint() just makes sure all the components are repainted.

Add Enter key as JButton accelerator

I'm building simple chat application with simple GUI, but a I have a problem assigning Enter key to Send button. Right now it is quite unpractical pressing Alt+Enter.
public void buildInterface() {
//some other components
btnSend = new JButton("Send");
btnExit = new JButton("Exit");
btnSearch=new JButton("Search");
btnSend.setMnemonic(KeyEvent.VK_ENTER);
JPanel box=new JPanel();
add(box, BorderLayout.SOUTH);
box.add(tfInput);
box.add(btnSend);
box.add(btnExit);
box.add(btnSearch);
}
When the button is focused, under most look and feels the Enter will activate the button.
You can, however, assign a button to be the "default" button for the window, which will be activated when the Enter key pressed, so long as the focused component does not consume it.
See How to Use Root Panes and JRootPane#setDefaultButton for more details
Add following code to your Util class
public static void bindKeyStroke(final JButton btn, String ks) {
final ActionListener[] alist = btn.getActionListeners();
if (alist.length != 0) {
AbstractAction action = new AbstractAction(btn.getText(), btn.getIcon()) {
#Override
public void actionPerformed(ActionEvent e) {
for (ActionListener al : alist) {
ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), Action.ACCELERATOR_KEY);
al.actionPerformed(ae);
}
}
};
KeyStroke keyStroke = KeyStroke.getKeyStroke(ks);
btn.setAction(action);
btn.getActionMap().put(Action.ACCELERATOR_KEY, action);
btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, Action.ACCELERATOR_KEY);
}
}
Goto frame, dialog or panel constructor and add after initComponent();
Util.bindKeyStroke(<your button>, "alt enter");
Fix double action, in action performed
if (evt.getActionCommand().equals(Action.ACCELERATOR_KEY)) {
// Your send action here
}

How can I remove JButton from JFrame?

I want to remove JButton when user click JButton.
I know that I should use remove method, but it did not work.
How can I do this?
Here is my code:
class Game implements ActionListener {
JFrame gameFrame;
JButton tmpButton;
JLabel tmpLabel1, tmpLabel2, tmpLabel3, tmpLabel4;
public void actionPerformed(ActionEvent e) {
gameFrame.remove(tmpLabel1);
gameFrame.getContentPane().validate();
return;
}
Game(String title) {
gameFrame = new JFrame(title);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.setBounds(100, 100, 300, 500);
gameFrame.setResizable(false);
gameFrame.getContentPane().setLayout(null);
tmpLabel4 = new JLabel(new ImageIcon("./images/bomber.jpg"));
tmpLabel4.setSize(200, 200);
tmpLabel4.setLocation(50, 100);
tmpButton = new JButton("Play");
tmpButton.setSize(100, 50);
tmpButton.setLocation(100, 350);
tmpButton.addActionListener(this);
gameFrame.getContentPane().add(tmpLabel4);
gameFrame.getContentPane().add(tmpButton);
gameFrame.setVisible(true);
}
}
If hiding the button instead of removing works for your code then you can use:
public void actionPerformed(ActionEvent event){
tmpButton.setVisible(false);
}
for the button.But the button is just hidden not removed.
The simplest solution might be to...
Attach an ActionListener to the button, see How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listeners for more details
When the ActionListener is clicked, extract the source of the event, JButton buttonThatWasClicked = (JButton)actionEvent.getSource()
Remove it from it's parent...
For example...
Container parent = buttonThatWasClicked.getParent();
parent.remove(buttonThatWasClicked);
parent.revaidate();
parent.repaint();
As some ideas...
First of all in your actionPerformed method you need to check that the button is clicked or not. And if the button is clicked, remove it. Here's how :
if(e.getSource() == tmpButton){
gameFrame.getContentPane().remove(tmpButton);
}
add this to your actionPerformed Method
don't add your button to jframe but add each component you want!
public void actionPerformed(ActionEvent event)
{
//gameFrame.getContentPane().add(tmpButton); -=> "Commented Area"
gameFrame.getContentPane().validate();
}
or hide your button like this
public void actionPerformed(ActionEvent event)
{
tmpButton.setVisible(false);
}

Actions performed on jButton after disabling

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.

How can I keep executing work while a button is pressed?

I want to keep executing work while a button is pressed, using Java. When the button is released, the work should stop. Something like this:
Button_is_pressed()
{
for(int i=0;i<100;i++)
{
count=i;
print "count"
}
}
How might I achieve this?
One way:
Add a ChangeListener to the JButton's ButtonModel
In this listener check the model's isPressed() method and turn on or off a Swing Timer depending on its state.
If you want a background process, then you can execute or cancel a SwingWorker in the same way.
An example of the former:
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class ButtonPressedEg {
public static void main(String[] args) {
int timerDelay = 100;
final Timer timer = new Timer(timerDelay , new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button Pressed!");
}
});
JButton button = new JButton("Press Me!");
final ButtonModel bModel = button.getModel();
bModel.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent cEvt) {
if (bModel.isPressed() && !timer.isRunning()) {
timer.start();
} else if (!bModel.isPressed() && timer.isRunning()) {
timer.stop();
}
}
});
JPanel panel = new JPanel();
panel.add(button);
JOptionPane.showMessageDialog(null, panel);
}
}
I want to keep executing work while a button is pressed
Execute that process in another thread and then your form is not block and you can press the button to cancel or stop the execution.
see :
How to stop threads of a Java program?
Stop/cancel SwingWorker thread?
Control thread through button
You may need to use mousePressed event to start the action
And use mouseReleased event to stop the action (This is neccesary)
For more information refer here
For Android Apps
I know this question is old, but you can use:
while (yourButton.isPressed()) {
// Do Stuff
}

Categories