ulthanex
ulthanex

Reputation: 47

Java Background gaps between frame and image

Been having fun transitioning through a variety of layouts/nulls and other methods in an attempt to get my background image to fit my frame perfectly without annoying gaps which I have so far been unable to clear. Every attempt has either led to larger gaps. if the layout was set to left, the image inevitably fills gaps on the left but widen's the ones on the right and the last attempt by adding the image to the frame directly filled it perfectly, but led to the other elements on screen no longer receiving the repaint calls

enter image description here

At the moment my game sets up a jframe, creates my game system class which extends JPanel, and the game system class creates inner classes which handle either the start screen or actual game screen elements. Inside the game container class which is created by the System is where the background is being painted.

Shortened down code extract

Main Class:

    public class Test extends JPanel {

////////////////
////Variables //
////////////////////////////
/**/private static Test test;
/**/private static JFrame stage;
/**/private static Container CurrentMenu;
/**/private boolean isRunning = true; //used to state whether game is running
////////////////////////////////////

////////////////
// initialize //
////////////////
/**/public static void main(String[] args) {
/**/stage = new JFrame("Touhou FBE");//creates game window
/**/stage.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//sets up default handler for closing window
/**/test = new Test();//creates an object of our game
/**/stage.getContentPane().add(test);//add game object to frame 
/**/stage.pack();
/**/stage.setVisible(true);//sets frame to visible
/**/stage.setResizable(false);
/**/test.Game_loop();
/**/}
////////////////////////////

/////////////////
// constructor //
/////////////////
/**/public Test(){
/**////////////////////////////////
/**/// create starting game menu //
/**////////////////////////////////          //////////////////
/**/CurrentMenu = new Container(this,stage);     // swap GameMenu with GameContainer to be able to see difference with painting
/**/this.add(CurrentMenu);                   //////////////////
/**/}
///////////////////////


    ////////////////////////////////////////////
    // Game loop which manages object updates //
    ////////////////////////////////////////////
    /**/public void Game_loop(){
    /**/while (isRunning) {
    /**/test.repaint();
    /**/}
    /**/}
    /////////////////////////////////////////////////

    /////////////////////////////////
    // Rendering canvas for images //
    /////////////////////////////////
    /**/public void paint(Graphics g) {
    /**/super.paint(g); //Refresh Panel
    /**/}
    /////////////////////////////////////////////////////// 

Container Class:

    //////////////////////////
// game container class //
//////////////////////////
/**/public class Container extends JPanel{
/**/    
///////////////
//Variables //
///////////////
/**/public Test Game; 
/**/public JFrame stage; 
/**/private Image img;  

////////////////
//Constructor //
////////////////
/**/public Container(Test game, JFrame Stage){
/**/Game = game;
/**/stage = Stage;  
/**/img = (new ImageIcon("resources/background.png").getImage());
/**/Dimension size = new Dimension(700, 400);
/**/setPreferredSize(size);
/**/setMinimumSize(size);
/**/setMaximumSize(size);
/**/setLayout(null);
/**/setSize(size);
/**/}
/**/    
////////////////////////////

//////////////////
//Paint sprite //
//////////////////
/**/public void paintComponent(Graphics g) {
/**///super.paint(g);
/**/g.drawImage(img, 0,0, this);
/**/}
////////////////////////////////////
}

Image used in program and example (Rename to background) enter image description here http://img716.imageshack.us/img716/6410/seq6.png

At the moment I've reached the point where if I Have to, I would leave the gap in as it doesn't effect the overall game, however it's bugging me so bad and every attempt at swapping layouts, removing hgap/vgap, forcing the location of the image or following tutorials has led to no real change. Help would be greatly appreciated and will help make sure I never come across issues like this again.

Upvotes: 1

Views: 788

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

Calling setResizable changes the size of the frame.

Instead, try calling setResizable first, then pack, the setVisible

For example...

Updated

The continuing "padding" is caused by the fact that Test extends from JPanel and Container is added to it.

The default layout manager for JPanel is FlowLayout, which, by default, adds 5 pixels by default all around the container.

Depending on your needs, I would either change the layout manager for Test to BorderLayout or simply add Container directly to the frame (which uses a BorderLayout by default)

For example...

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestResize {

    private JFrame stage;
    private Container CurrentMenu;
    private boolean isRunning = true; //used to state whether game is running

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestResize();
            }
        });
    }

    public TestResize() {
        CurrentMenu = new Container(this, stage);     // swap GameMenu with GameContainer to be able to see difference with painting
        stage = new JFrame("Touhou FBE");//creates game window
        stage.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//sets up default handler for closing window
        stage.add(CurrentMenu);
        stage.setResizable(false);
        stage.pack();
        stage.setVisible(true);//sets frame to visible
        // This needs to be started in a separate thread
//        test.Game_loop();
    }

    public void Game_loop() {
//        while (isRunning) {
//            test.repaint();
//        }
    }

    public class Container extends JPanel {

        public TestResize Game;
        public JFrame stage;
        private Image img;

        public Container(TestResize game, JFrame Stage) {
            Game = game;
            stage = Stage;
            img = (new ImageIcon("resources/background.png").getImage());
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension size = img == null ? new Dimension(700, 400) : new Dimension(img.getWidth(this), img.getHeight(this));
            return size;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, 0, 0, this);
            g.setColor(Color.RED);
            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);            
        }
    }
}

Upvotes: 2

Related Questions