0

f.e. I have an email client, it receives new message, button with incoming messages starts doing something, until user clicks it to see whats up.

I'm trying to make button attract attention by selecting, waiting and then deselecting it, but this does nothing!

 do{
        button.setSelected(true);
               Thread oThread = new Thread() {
                    @Override
                   public void run() {
                       synchronized (this) {
                           try {
                               wait(1000);
                           } catch (InterruptedException e1) {
                               e1.printStackTrace();
                           }
                       }
                       button.setSelected(false);
                   }
               };
               oThread.start();
        }while(true);
Jonas
  • 121,568
  • 97
  • 310
  • 388
bunnyjesse112
  • 747
  • 6
  • 27
  • 44
  • 1
    Don't indicate importance by grabbing focus. Try instead changing the button icon from a red version to green (or some less horrendous color combination). – Andrew Thompson Dec 23 '11 at 10:31
  • @bunnyjesse112 question ---> are you want to shaking with Text inside JButton or shaking with JButton, or with JButton and with Test too ??? – mKorbel Dec 23 '11 at 10:35
  • 1
    How about replacing the button icon with a pulsing animated GIF? – Adriaan Koster Dec 23 '11 at 10:39
  • @mKorbel Shake? I'm familiar with ["Shake, (rattle & roll)"](http://en.wikipedia.org/wiki/Shake,_Rattle_and_Roll) (yes, I am that ancient1()), but what does 'shake' have to do with this? 1) (OK, a decade before my time, but a feckin' classic track nonetheless.) – Andrew Thompson Dec 23 '11 at 10:41
  • @AdriaanKoster +1, yeah, like that suggestion. – Andrew Thompson Dec 23 '11 at 10:43
  • i just want JButton to attract attention; selecting deselecting is the only thing i could think of. Are there other, more cool, or efficient ways to do this? Maybe there are some third party components? help me out please. – bunnyjesse112 Dec 23 '11 at 10:48
  • @bunnyjesse112 you'd be able to creating whatever with JButton, whatever that you see around, but I missing deepest idea and direction, – mKorbel Dec 23 '11 at 11:04
  • @Andrew Thompson not, never, hmmm but in other hands, well, sure maybe one Jack Daniel's by direct & quick implementations can solve issues with this song – mKorbel Dec 23 '11 at 11:06
  • @mKorbel i just want button that beats, throbs, or glows, or pulsates, anything thats attracts user! – bunnyjesse112 Dec 23 '11 at 11:13
  • @bunnyjesse112 then you have to try Substance, there are built-in Glittering, and ..., and..., you have to try, but please don't suck compiled *.jar, codesource, there is one class (I'm in office) and there you can switch betweens all Custom Look and Feels that exist around with Custom Add-Ons http://stackoverflow.com/questions/3954616/look-and-feel-in-java, end_less combinations about everything, carrefully with effects, could be pretty annoying users, less is in all cases more – mKorbel Dec 23 '11 at 11:21
  • wow i know about substance laf, but tell me more about Glittering. how do i use it? i wont suck i promise! – bunnyjesse112 Dec 23 '11 at 11:25
  • @bunnyjesse112 everything are about trying to set some values and their combinations in prepared GUI (I plaeyd with that once whole weeked), there nothing about coding, everything is there prepared – mKorbel Dec 23 '11 at 11:42
  • But how do i make button animate programmatically? f.e. I have an email client, it receives new message, button with incoming messages starts doing something, until user clicks it to see whats up. – bunnyjesse112 Dec 23 '11 at 11:46

2 Answers2

5

You should use Swing timers for that. Don't interact with GUI objects from foreign threads.

There's some docs in the Java tutorial: How to use Swing timers.

Here's an example way you could do this playing with the button's icon.

// member var
Icon buttonIcon;
Timer timer;
  // in constructor for example
  buttonIcon = new ImageIcon("resources/icon.png");
  button.setIcon(buttonIcon);

  timer = new Timer(1000, this);
  timer.start();
   // in the actionPerformed handler
   if (button.getIcon() == null)
     button.setIcon(icon);
   else
     button.setIcon(null);

Your class will need to implement ActionListener for this to work like that. Add some logic to stop the flashing when you need it.

Mat
  • 202,337
  • 40
  • 393
  • 406
4

hafl_workaround to your questions

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ShakingButtonDemo implements Runnable {

    private JButton button;
    private JRadioButton radioWholeButton;
    private JRadioButton radioTextOnly;

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new ShakingButtonDemo());
    }

    @Override
    public void run() {
        radioWholeButton = new JRadioButton("The whole button");
        radioTextOnly = new JRadioButton("Button text only");
        radioWholeButton.setSelected(true);
        ButtonGroup bg = new ButtonGroup();
        bg.add(radioWholeButton);
        bg.add(radioTextOnly);
        button = new JButton("  Shake with this Button  ");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                shakeButton(radioWholeButton.isSelected());
            }
        });
        JPanel p1 = new JPanel();
        p1.setBorder(BorderFactory.createTitledBorder("Shake Options"));
        p1.setLayout(new GridLayout(0, 1));
        p1.add(radioWholeButton);
        p1.add(radioTextOnly);
        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(0, 1));
        p2.add(button);
        JFrame frame = new JFrame();
        frame.setTitle("Shaking Button Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(p1, BorderLayout.NORTH);
        frame.add(p2, BorderLayout.SOUTH);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void shakeButton(final boolean shakeWholeButton) {
        final Point point = button.getLocation();
        final Insets margin = button.getMargin();
        final int delay = 75;
        Runnable r = new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 30; i++) {
                    try {
                        if (shakeWholeButton) {
                            moveButton(new Point(point.x + 5, point.y));
                            Thread.sleep(delay);
                            moveButton(point);
                            Thread.sleep(delay);
                            moveButton(new Point(point.x - 5, point.y));
                            Thread.sleep(delay);
                            moveButton(point);
                            Thread.sleep(delay);
                        } else {// text only
                            setButtonMargin(new Insets(margin.top, margin.left + 3, margin.bottom, margin.right - 2));
                            Thread.sleep(delay);
                            setButtonMargin(margin);
                            Thread.sleep(delay);
                            setButtonMargin(new Insets(margin.top, margin.left - 2, margin.bottom, margin.right + 3));
                            Thread.sleep(delay);
                            setButtonMargin(margin);
                            Thread.sleep(delay);
                        }
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }

    private void moveButton(final Point p) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                button.setLocation(p);
            }
        });
    }

    private void setButtonMargin(final Insets margin) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                button.setMargin(margin);
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319