Solved

Need java menus to change my JFrame background images

Posted on 2004-08-24
24
725 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
ID: 11882384
And the question is..?

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

Author Comment

by:pjcrooks2000
ID: 11882446
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
ID: 11882475
It also looks like you should be storing the images in an array - you seem to overwrite the one reference
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Author Comment

by:pjcrooks2000
ID: 11882554
Anymore on that CEHJ ??  
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11882560
(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
ID: 11882581
...and don't forget

backgroundImages = new BufferedImage[4];

;-)

0
 
LVL 35

Assisted Solution

by:girionis
girionis earned 300 total points
ID: 11883305
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
ID: 11883345
>>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
ID: 11883374
Because they waste memory although it wouldn't be that much since there are only few.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11883414
>>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
ID: 11883446
If you use the Map i mentioned, you may not need the BufferedImage array
0
 
LVL 35

Expert Comment

by:girionis
ID: 11883475
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
 
LVL 8

Author Comment

by:pjcrooks2000
ID: 11883476
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
ID: 11883488
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
ID: 11883515
Up to you ...;-)
0
 
LVL 35

Expert Comment

by:girionis
ID: 11883516
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
ID: 11883537
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
ID: 11883600
Thank you for accepting :)
0
 
LVL 8

Author Comment

by:pjcrooks2000
ID: 11883669
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
ID: 11883717
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
ID: 11883766
Hehe aye, it's like a drug :)
0
 
LVL 86

Expert Comment

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

Author Comment

by:pjcrooks2000
ID: 11883929
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
ID: 11883959
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
jsp login check 12 52
ejb on wildfly 5 45
import as existing maven project 3 34
Coding for the first time 9 62
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…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

685 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