Reputation: 47
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
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)
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
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...
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