Solved

Need java menus to change my JFrame background images

Posted on 2004-08-24
24
721 Views
Last Modified: 2012-08-13
Hey all hows it going

OK here is my code below, you will see that I have a try catch to load in 4 images for a background on my java game.  Also i have a corresponding menu that will allow the background to be changed upon selecting the menu.

How can I do it?

import java.awt.*;
import java.awt.event.*;
import java.awt.* ;
import java.awt.event.* ;
import java.awt.image.* ;
import javax.imageio.* ;
import java.io.* ;
import javax.swing.* ;

public class JaySnake extends JFrame
{
  class Game extends JPanel implements Runnable
  {
    private BufferedImage backBuffer ;
    private Graphics myBackBuffer ;

    public Game()
    {

      /******Try read in backgroundImage file and catch any exception*/
      try
      {
        backgroundImage = ImageIO.read( new File( "default.jpg" ) );
        backgroundImage = ImageIO.read( new File( "blueGlass.jpg" ) );
        backgroundImage = ImageIO.read( new File( "grassBack.jpg" ) );
        backgroundImage = ImageIO.read( new File( "sand.jpg" ) );
      }
      catch( IOException e )
      {
        System.out.println( "Cannot load image file!" ) ;
      }
      backBuffer = new BufferedImage( DISPLAY_W, DISPLAY_H, BufferedImage.TYPE_INT_RGB ) ;
      myBackBuffer = backBuffer.getGraphics() ;

//set up the menubar
      menubar = new JMenuBar();
      setJMenuBar(menubar);

    }

    long startTime, waitTime, elapsedTime ;
    public void paintComponent( Graphics g )
    {
      g.drawImage( backBuffer, DISPLAY_X, DISPLAY_Y, null ) ;
    }

    public void run()
    {
      //     1000/25 Frames Per Second = 40millisecond delay
      int delayTime = 1000 / 25 ;

      Thread thisThread = Thread.currentThread() ;
      while( running )
      {
        startTime = System.currentTimeMillis() ;
        // render to back buffer now
        render( myBackBuffer ) ;

        repaint() ;
        //  handle frame rate
        elapsedTime = System.currentTimeMillis() - startTime ;
        waitTime = Math.max( delayTime - elapsedTime, 5 ) ;

        try
        {
          Thread.sleep( waitTime ) ;
        }
        catch( InterruptedException e )
        {}
      }
      System.out.println( "Program Exited" ) ;
    }

   
  }

  private Thread gamePlay ;
  private boolean running = true ;
  private Game game ;

  private final int DISPLAY_X ; // value assigned in constructor
  private final int DISPLAY_Y ; // value assigned in constructor

  private static final int DISPLAY_W = 600 ;
  private static final int DISPLAY_H = 600 ;

  int size, hsize = 0, score1 = 0, score2 = 0, highscore = 0 ;

  /****Creates JMenuBar */
  private JMenuBar menubar ;
  /****Creates JMenu to house items */
  private JMenu gameMenu = new JMenu( "Game" ) ;
  private JMenuItem gameStart = new JMenuItem( "Start" ) ;
  private JMenuItem gameQuit = new JMenuItem( "Quit" ) ;

  private JMenu bgMenu = new JMenu( "Backgrounds" ) ;
  private ButtonGroup bgGroup = new ButtonGroup() ;
  private JRadioButtonMenuItem bg1 = new JRadioButtonMenuItem( "Default" ) ;
  private JRadioButtonMenuItem bg2 = new JRadioButtonMenuItem( "Long grass" ) ;
  private JRadioButtonMenuItem bg3 = new JRadioButtonMenuItem( "Yellow Sand" ) ;
  private JRadioButtonMenuItem bg4 = new JRadioButtonMenuItem( "Blue Glass" ) ;

  private JMenu soundMenu = new JMenu( "Enable sounds" ) ;
  private JCheckBoxMenuItem soundMusic = new JCheckBoxMenuItem( "Music" ) ;
  private JCheckBoxMenuItem soundSound = new JCheckBoxMenuItem( "Sounds" ) ;

  private JMenu helpMenu = new JMenu( "Help" ) ;
  private JMenuItem userInstruct = new JMenuItem( "User Instructions" ) ;
  private JMenuItem helpAbout = new JMenuItem( "About" ) ;

  /******JaySnake constructor*/
  public JaySnake()
  {
    /*****Sets title for main window*/
    //setTitle("JaySnake Game");
    //getContentPane().setLayout( new BorderLayout() ) ;
    //setResizable( false ) ;
    //Causes Menu Titles to not show up when un commented
    //setIgnoreRepaint( true ) ;
    game = new Game() ;
    getContentPane().add( game, BorderLayout.CENTER ) ;
    this.setJMenuBar( menubar );

    menubar.add( gameMenu ) ;
    gameMenu.add( gameStart ) ;
    gameMenu.add( gameQuit ) ;

    // ActionListener to quit the game when quit is clicked
    gameQuit.addActionListener( new ActionListener(){  
   
               public void actionPerformed( ActionEvent e )
     {
        System.exit( 0 );
     }
      } ) ;                                                  
                         
    menubar.add( bgMenu ) ;
    bgMenu.add( bg1 ) ;
    bgMenu.add( bg2 ) ;
    bgMenu.add( bg3 ) ;
    bgMenu.add( bg4 ) ;

    bgGroup.add( bg1 ) ;
    bgGroup.add( bg2 ) ;
    bgGroup.add( bg3 ) ;
    bgGroup.add( bg4 ) ;

    menubar.add( soundMenu ) ;
    soundMenu.add( soundMusic ) ;
    soundMenu.add( soundSound ) ;

    menubar.add( helpMenu ) ;
    helpMenu.add( userInstruct ) ;
    helpMenu.add( helpAbout ) ;

    addWindowListener( new WindowAdapter()
    {
      public void windowClosing( WindowEvent e )
      {
        dispose();
        System.exit( 0 ) ;
      }
    } ) ;

    Insets insets = getInsets() ;
    DISPLAY_X = insets.left ;
    DISPLAY_Y = insets.top ;
    resizeToInternalSize( DISPLAY_W, DISPLAY_H ) ;
  }

  public void resizeToInternalSize( int internalWidth, int internalHeight )
  {
    Insets insets = getInsets() ;
    final int newWidth = internalWidth + insets.left + insets.right ;
    final int newHeight = internalHeight + insets.top + insets.bottom ;

    Runnable resize = new Runnable()
    {
      public void run()
      {
        setSize( newWidth, newHeight ) ;
      }
    } ;

    if( !SwingUtilities.isEventDispatchThread() )
    {
      try
      {
        SwingUtilities.invokeAndWait( resize ) ;
      }
      catch( Exception e )
      {}
    }
    else
      resize.run() ;

    validate() ;
  }

  public void start()
  {
    Thread gamePlay = new Thread( game ) ;
    gamePlay.start() ;
  }

  public static void main( String args[] )
  {
    System.out.println( "Starting JaySnake..." ) ;
    JaySnake app = new JaySnake() ;
    app.setSize( DISPLAY_W, DISPLAY_H ) ;
    app.setTitle( "JaySnake Game" ) ;
    app.setVisible( true ) ;
    app.start() ;
  }

/*Render method for graphics content*/
    public void render( Graphics g )
    {
     if( backgroundImage != null )
        g.drawImage( backgroundImage, 0, 0, this ) ;

      /******Draw scoreboard and player details, sets color for score and player
       ******draws rectangle in same green, draws strings and used variables score1
       ******and score2. Sets color again to black draws another rectangle
       ******that is used to highlight the playing area*/
      g.setColor( Color.green ) ;
      g.drawRect( 1, 0, 598, 32 ) ;
      g.drawString( "Player 1 score: " + score1, 10, 13 ) ;
      g.drawString( "Player 2 score: " + score2, 10, 27 ) ;
      g.drawString( "High score: " + highscore, 510, 15 ) ;
      g.setColor( Color.black ) ;
      g.drawRect( 1, 34, 598, 521 ) ;
     
    }

  /******declared class variables/containers*/
  private Image backgroundImage ;
}


Thanks all
0
Comment
Question by:pjcrooks2000
  • 9
  • 8
  • 7
24 Comments
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
And the question is..?

Make sure you don't need to call super.paintComponent too
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
lol sorry its  abit vague that question..   Yes well i want to be able to change my background image from the four loaded files when the menu items are selected.  The menu items are the background ones!

what do you mean CEHJ about super.paintComponent ?  thanks!
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 200 total points
Comment Utility
It also looks like you should be storing the images in an array - you seem to overwrite the one reference
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
Anymore on that CEHJ ??  
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
(Pseudo-code):

private BufferedImage[] backgroundImages;

...

backgroundImages[0] = ImageIO.read( new File( "default.jpg" ) );
backgroundImages[1] = ImageIO.read( new File( "blueGlass.jpg" ) );

etc.

in menu listener:

activeBackgroundImage = <select from menu> // 'activeBackgroundImage' is reference to current image
gamePanel.repaint();


in paintComponent

super.paintComponent(g);
drawImage(activeBackgroundImage.......................
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
...and don't forget

backgroundImages = new BufferedImage[4];

;-)

0
 
LVL 35

Assisted Solution

by:girionis
girionis earned 300 total points
Comment Utility
Do you really need to redraw the image? Simply by doing think I think it should work:

Add this method in your game class.

public void setImage(String fileName) throws Exception
     {
           if (fileName.equals("default"))
           {
          backgroundImage = ImageIO.read( new File( "default.jpg" ) );
          }
          else if (fileName.equals("Long grass"))
          {
                backgroundImage = ImageIO.read( new File( "grassBack.jpg" ) );
              
          }
          else if (fileName.equals("Yellow Sand"))
          {
              backgroundImage = ImageIO.read( new File( "sand.jpg" ) );
          }
          else
          {
                backgroundImage = ImageIO.read( new File( "blueGlass.jpg" ) );
          }
     }

Then add listeners to the radion button menu you have:

bg1.addActionListener(this);
    bg2.addActionListener(this);
    bg3.addActionListener(this);
    bg4.addActionListener(this);

make your class implement ActionListener

and add the proper method in the JaySnake class:

public void actionPerformed(ActionEvent e)
  {
       try
     {
          JMenuItem source = (JMenuItem)(e.getSource());
          System.out.println(source.getText());
          game.setImage(source.getText());
     }
     catch (Exception ex)
     {
          System.out.println(ex);
     }
  }

This should work. If you notice this is already done (changing backgroung) here: http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_21103478.html
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>Add this method in your game class.

Why should the image be loaded each time? The point is (which is one of the parts that's *right* so far) that the images should be preloaded and once only
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
Because they waste memory although it wouldn't be that much since there are only few.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>Because they waste memory although it wouldn't be that much since there are only few.

...and much better than waiting while each image is loaded each time. This is how your listener should look

public void actionPerformed(ActionEvent e)
{
      try
      {
            JMenuItem source = (JMenuItem)(e.getSource());
            // Using a previously instantiated Map (ask if you don't understand)
            activeBackgroundImage = (BufferedImage)imageMap.get(source.getText());
            repaint();
      }
      catch (Exception ex)
      {
            System.out.println(ex);
      }
}
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
If you use the Map i mentioned, you may not need the BufferedImage array
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
I think both solutions offer pros and cons. The user might never change the background image or change it just once, so loading it from the disk is better. On the other hand if the user keeps changing the background then loading up and storing into a collection/array is a better solution.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
Hmmm now you guys got me, ok to be fair I am going to try and do both methods and see what results I get but a valiant effor from you both thats for sure Phew!    

Ok I get the general Idea so I am going to close this one up for now and share points.  I will then post another one ssson I am sure :)  Hope thats ok guys
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
Sorry forgto tto mention Gironis gets slightly more because he helped me on this one yesterday also, as shown from the link he posted above

thanks guys!
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Up to you ...;-)
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
Based on CEH's code, to initialize the imageMap do:

HashMap imageMap = new HashMap(4);
imageMap.put("default.jpg",  ImageIO.read( new File( "default.jpg" ));
...
...
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
I think points should be split equally (if we both help you equally). It does not matter if I answered previous questions, the one that matters now is the current one :)
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
Thank you for accepting :)
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
Yes but Gironis I am was just making up for a previos effort on the link that you posted I think the posts went somewhere else on that one, the question as similar and you quoted it back to me.  Also I am sure CEHJ, you will be getting many more wins in the future from me too.   Once again good job both of you!

I do try to be fair you know!  :)  Sometimes it may seem like I even get that wrong ...
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
Guys I am getting very excited I have got 1320 points now ... lol   It's a bit like a drug isn't it ?
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
Hehe aye, it's like a drug :)
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
OK, if you end up using my code, i'm sure you'll reimburse me ;-)
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
I surely will indeedy no doubt I may even just make some stuff up for ya!  :)  I am dizzy with the drugs!  Not really heh
0
 
LVL 8

Author Comment

by:pjcrooks2000
Comment Utility
Ooooh Oooooooh incidentally

I will post a question now ok.. I have a class that is a splash screen check out the new question I am sure its an easy one i am just trying to accumulate some work for me to do tonight, when I am not watching the Olympics of corse.

Its called Adding a splash screen to my game :)
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

763 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now