Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 735
  • Last Modified:

Need java menus to change my JFrame background images

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
pjcrooks2000
Asked:
pjcrooks2000
  • 9
  • 8
  • 7
2 Solutions
 
CEHJCommented:
And the question is..?

Make sure you don't need to call super.paintComponent too
0
 
pjcrooks2000Author Commented:
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
 
CEHJCommented:
It also looks like you should be storing the images in an array - you seem to overwrite the one reference
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
pjcrooks2000Author Commented:
Anymore on that CEHJ ??  
0
 
CEHJCommented:
(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
 
CEHJCommented:
...and don't forget

backgroundImages = new BufferedImage[4];

;-)

0
 
girionisCommented:
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
 
CEHJCommented:
>>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
 
girionisCommented:
Because they waste memory although it wouldn't be that much since there are only few.
0
 
CEHJCommented:
>>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
 
CEHJCommented:
If you use the Map i mentioned, you may not need the BufferedImage array
0
 
girionisCommented:
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
 
pjcrooks2000Author Commented:
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
 
pjcrooks2000Author Commented:
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
 
CEHJCommented:
Up to you ...;-)
0
 
girionisCommented:
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
 
girionisCommented:
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
 
girionisCommented:
Thank you for accepting :)
0
 
pjcrooks2000Author Commented:
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
 
pjcrooks2000Author Commented:
Guys I am getting very excited I have got 1320 points now ... lol   It's a bit like a drug isn't it ?
0
 
girionisCommented:
Hehe aye, it's like a drug :)
0
 
CEHJCommented:
OK, if you end up using my code, i'm sure you'll reimburse me ;-)
0
 
pjcrooks2000Author Commented:
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
 
pjcrooks2000Author Commented:
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

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 9
  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now