Solved

Jbutton image trouble.

Posted on 2006-07-09
26
220 Views
Last Modified: 2010-03-31
I have the following:
long STime = System.currentTimeMillis();
while(System.currentTimeMillis()-STime <3000)
{
      for(int i =0;i<5;i++)
      {
            Random RandGen = new Random();
            SetImage(Button[i],(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
      }
}

Rather than changing the images constantly for 3 seconds however, it changes the images ONCE after 3 seconds.
What is the best way to force the images to refresh after a call to SetImage?
0
Comment
Question by:List244
  • 11
  • 8
  • 5
  • +1
26 Comments
 
LVL 26

Expert Comment

by:ksivananth
ID: 17069271
try

Button[i].validate() ;
Button[i].repaint() ;
0
 
LVL 8

Author Comment

by:List244
ID: 17069282
Still no paint.
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 17069354
execute all the update code in SwingUtilities.invokeLater method if you execute this in separate thread
0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
LVL 86

Expert Comment

by:CEHJ
ID: 17069607
Easiest to use a swing Timer. Example in API docs:

http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/Timer.html
0
 
LVL 8

Author Comment

by:List244
ID: 17069720
CEHJ, I have tried this as well, can you give a code example?  Either implemented in my code, or something similar so
I can see how it is done?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 17069730
I'm not sure precisely what timing you want though...
0
 
LVL 8

Author Comment

by:List244
ID: 17069739
I would say pretty fast, and I could always alter that.  I just would like to see some working example of how to do it
properly.  I have tried a timer previously, and it didn't work, so I assume my method is faulty.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 17069742
(assuming every 3 seconds)

int delay = 3000; // 3 seconds
final Random RandGen = new Random();
ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
            SetImage(Button[i],(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
      }
};
new Timer(delay, taskPerformer).start();
0
 
LVL 8

Author Comment

by:List244
ID: 17069745
Have yet to try this, but I remember previously, I had an issue where it said can not access non-final member 'i'.
Is this still going to occur?
0
 
LVL 8

Author Comment

by:List244
ID: 17069749
Basically, what I am trying to do is this:

User clicks a jbutton, for 3 seconds, the images switch randomly.  At the end of the three seconds,
the button images remain constant at whatever the last randomly generated set was.  The problem
is, everytime I try this, it only shows the images LAST chosen.  As if the loop is too busy so it does not
draw until completed.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 17069751
Depends where 'i' is defined. If it's a local variable, define it as final, like the Random
0
 
LVL 92

Expert Comment

by:objects
ID: 17069761
try the following, where Timer and STimer are member vars of your class

ActionListener taskPerformer = new ActionListener() {
     Random RandGen = new Random();
     public void actionPerformed(ActionEvent evt) {
          SetImage(Button[i],(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
          if (System.currentTimeMillis()-STime <3000) {
             Timer.stop();
          }
 }
};
STime = System.currentTimeMillis();
Timer = new Timer(100, taskPerformer).start();
0
 
LVL 92

Expert Comment

by:objects
ID: 17069772
you should avoid using final, if you are just updating one button at a time then instead use a member var

ActionListener taskPerformer = new ActionListener() {
     Random RandGen = new Random();
      public void actionPerformed(ActionEvent evt) {
          SetImage(UpdateButton,(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
          if (System.currentTimeMillis()-STime <3000) {
             Timer.stop();
          }
 }
};
STime = System.currentTimeMillis();
Timer = new Timer(100, taskPerformer).start();
0
 
LVL 92

Expert Comment

by:objects
ID: 17069775
If you are updating more than one button at a time, then instead define the button to update and the time as member vars of the *inner* class. Let me know if you have any questions :)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 17069783
Try the following - you can't set the Timer too fast or the eye won't register the changes


private class ImageRandomizer implements ActionListener {
      private final MAX_ITERATIONS = 2 * 3;
      private int iterations;
      private Random RandGen = new Random();
      
      public void actionPerformed(ActionEvent evt) {
            if (++iterations == MAX_ITERATIONS) {
                  randomizerTimer.cancel();
            }
            SetImage(Button[i],(1+RandGen.nextInt(6))+".jpg");
      }

}

....

randomizerTimer = new Timer(delay, new ImageRandomizer()).start(); // randomizerTimer is a member var
0
 
LVL 8

Author Comment

by:List244
ID: 17069843
Can either of you show a working example?  I can not get any of this working within the method I first supplied.
I can not access the variables because they are not final, and they can not be final because they need to change.
Maybe it would be easier to thread the set-image function?
0
 
LVL 92

Expert Comment

by:objects
ID: 17069849
the code i posted above should do what you want (and does not require any final vars). have u tried it?

ActionListener taskPerformer = new ActionListener() {
     Random RandGen = new Random();
      public void actionPerformed(ActionEvent evt) {
          SetImage(UpdateButton,(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
          if (System.currentTimeMillis()-STime <3000) {
             Timer.stop();
          }
 }
};
UpdateButton = Button[i];
STime = System.currentTimeMillis();
Timer = new Timer(100, taskPerformer).start();
0
 
LVL 8

Author Comment

by:List244
ID: 17069854
Objects, yes I have, but I do not know how to use it.  For example, where would this go?

ActionListener taskPerformer = new ActionListener() {
     Random RandGen = new Random();
      public void actionPerformed(ActionEvent evt) {
          SetImage(UpdateButton,(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
          if (System.currentTimeMillis()-STime <3000) {
             Timer.stop();
          }
 }
};
0
 
LVL 92

Expert Comment

by:objects
ID: 17069859
put it in the action listener that gets called when the button is clicked
ie. where you have your existing code (which it will replace)
0
 
LVL 8

Author Comment

by:List244
ID: 17069873
Objects, I am not doing it quite that way, maybe I should post my code:

public class Yahtzee extends JApplet implements ActionListener
{
      private static final long serialVersionUID = 3932602065490549886L;
      final JButton Dice[] = new JButton[5];
      final JButton Roll = new JButton("Roll dice");
      public void init()
      {
            Container Form = getContentPane();
            JPanel MainPanel = new JPanel();
            MainPanel.setBackground(Color.BLACK);
            Form.add(MainPanel);
            MainPanel.add(DiceFrame(),BorderLayout.NORTH);
            Form.add(Roll,BorderLayout.SOUTH);
            Roll.addActionListener(this);
      }
      private JPanel DiceFrame()
      {
            JPanel DicePanel = new JPanel();
            DicePanel.setBackground(Color.BLACK);
            for(int i=0;i<5;i++)//Loop through 5 dice.
            {
                  Dice[i] = new JButton();
                  SetImage(Dice[i],(i+1) + ".jpg");
                  Dice[i].setBorder(BorderFactory.createBevelBorder(0));
                  Dice[i].setBackground(Color.BLACK);
                  Dice[i].setVerticalTextPosition(SwingConstants.BOTTOM);
                  Dice[i].setHorizontalTextPosition(SwingConstants.CENTER);
                  Dice[i].setForeground(Color.BLUE);
                  DicePanel.add(Dice[i]);
                  Dice[i].addActionListener(this);
            }
            return DicePanel;      
      }
      private int SetImage(JButton Button,String File)
      {
            URL ImageLoc = getClass().getResource("/" + File);
            Icon ThePic = new ImageIcon(ImageLoc);
            Button.setIcon(ThePic);
            return 1;
      }
      public void actionPerformed(ActionEvent e)
      {
            if (e.getSource() == Roll)
            {
                  RollDice();
                  return;
            }
            for(int i=0;i<5;i++)
            {
                  if (e.getSource() == Dice[i])
                  {
                        if(IsHeld(Dice[i]))
                        {
                              Dice[i].setBorder(BorderFactory.createBevelBorder(0));
                              Dice[i].setText("");
                        }
                        else
                        {
                              Dice[i].setBorder(BorderFactory.createBevelBorder(1));
                              Dice[i].setText("Held");
                        }
                  }
            }
      }
      private void RollDice()
      {
            long STime = System.currentTimeMillis();
            while(System.currentTimeMillis()-STime <3000)
            {
                 for(int i =0;i<5;i++)
                 {
                      Random RandGen = new Random();
                      if (!IsHeld(Dice[i]))
                            SetImage(Dice[i],(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
                 }
            }
      }
      private boolean IsHeld(JButton Button)
      {
            Border b = Button.getBorder();
            if (b instanceof BevelBorder)
            {
                BevelBorder bb = (BevelBorder) b;
                if (bb.getBevelType()==0)
                      return false;
                else if (bb.getBevelType()==1)
                      return true;
            }
            return false;
      }
}
0
 
LVL 8

Author Comment

by:List244
ID: 17069884
So, you can see, I can't really replace the current listener, as it is handling more than one object.
Also, at current, I am not inside of a listener for the changing of an image, I have moved it away
to separate things since I am using global listeners.
0
 
LVL 92

Expert Comment

by:objects
ID: 17069897
put the code in RollDice
0
 
LVL 92

Expert Comment

by:objects
ID: 17069903
you''; also want to add your existing loop into the new action listener

ActionListener taskPerformer = new ActionListener() {
     Random RandGen = new Random();
      public void actionPerformed(ActionEvent evt) {
         for(int i =0;i<5;i++)
         {
             if (!IsHeld(Dice[i]))
               SetImage(Button[i],(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
             if (System.currentTimeMillis()-STime <3000) {
                Timer.stop();
              }
        }
    }
};
0
 
LVL 8

Author Comment

by:List244
ID: 17069924
     private void RollDice()
      {
            Timer T = new Timer(100,new ActionListener()
            {
                 Random RandGen = new Random();
                 long STime = System.currentTimeMillis();
                  public void actionPerformed(ActionEvent evt)
                  {
                     for(int i =0;i<5;i++)
                     {
                         if (!IsHeld(Dice[i]))
                           SetImage(Dice[i],(1+RandGen.nextInt(6))+".jpg"); //Set Button[i] to random image 1,2,3,4,5, or 6.jpg
                         if (System.currentTimeMillis()-STime >3000)
                         {
                               SetImage(Dice[0],"6.jpg");
                            stop();
                          }
                    }
                }
            });
            T.start();
      }

Okay, the above is my code, it works, almost.  Everything is as expected until "stop();"  It does not stop.  I added an image change
before stop, to test that it is happening, and it is, however, it continues on with the timer.
0
 
LVL 92

Accepted Solution

by:
objects earned 500 total points
ID: 17069931
>                           stop();

thould be T.stop()

and make T a member variable
0
 
LVL 8

Author Comment

by:List244
ID: 17069946
That works, thanks again, Objects.
0

Featured Post

ScreenConnect 6.0 Free Trial

Check out the updates in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI that improves session organization and overall user experience. See the enhancements for yourself!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
stackato and cloud 4 86
servlet  URL Rewriting 1 37
mysql jsp example issue 32 38
going to wrong jsp page 2 21
INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question