Hey there!
My current JPanel/JFrame has a size of 960x540.
Is there a possiblity to stretch the whole Frame to fullscreen without having to recalculate imagesizes and positions?
That depends on the layout manager you are using. I don’t think any of them will simply scale all the components, including images, but you could try this:
frame.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
If you want to make it actually fullscreen, where you can’t see the title bar or OS taskbar, then take a look here.
I haven’t messed with Swing in a while, but that’s what I remember.
I don’t want to make a normal fullscreen.
I want a STRETCHED fullscreen… hard to explain.
like this picture:
https://dl.dropboxusercontent.com/u/13341521/fullscreen.jpg
Widowed: like it is now.
Fullscreen(red) how it is, when I use fullscreen,
Coordinate 1920x1080 IS 1920x1080.
Stretched fullscreen (green) how I want it to be.
Coordinate 1920x1080 is now 960x540!
Yea, I get it, everything should simply scale 2x.
Well, if you are drawing to a BufferedImage or similar then drawing that to the JPanel (you should be), then simply scale the BufferedImage to the JPanel’s size when you draw it:
/*I am assuming that this paint() is for the JPanel, but it could be for the JFrame, if you skip the JPanel; and that buffer is a 960 by 540 image*/
public void paint(Graphics g) {
/*do stuff here if required*/
g.drawImage(buffer, 0, 0, 960, 540, 0, 0, 1920, 1080, null);
}
I highly recommend using frame.getWidth() and .getHeight() instead of hardcoding 1920 and 1080.
Now, the buffer is still 960x540, but gets scaled to 1920x1080 on the fly. Is this what you wanted?
yeah, scaling is the word I was searching for.
I’m not drawing onto a bufferedImage, how do I do that?
How are you doing it currently?
Well, I simple create an Graphics2D-Object with
Graphics2D g;
g = (Graphics2D) getGraphics();
It might depend on what (where) you are calling getGraphics() on, but I think this will work:
Replace that line with:
BufferedImage buffer = new BufferedImage(960,540,BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffer.createGraphics();
/*do rendering here*/
g.dispose();
Always remember to dispose the Graphics object when you are done with it.
Then in your JPanel or JFrame’s paint() method:
public void paint(Graphics g) {
g.drawImage(buffer, 0, 0, buffer.getWidth(), buffer.getHeight(), 0, 0, getWidth(), getHeight(), null);
}
Well, I’m not using the paintComponent() Method.
I always send the Graphics object as parameter to the desired Screen and then to the object that has to be drawn.
public void run()
{
initialize();
while (isRunning)
{
beginTime = System.currentTimeMillis();
framesSkipped = 0; // resetting the frames skipped
update();
render();
// calculate how long did the cycle take
timeDiff = System.currentTimeMillis() - beginTime;
// calculate sleep time
sleepTime = (int) (FRAME_PERIOD - timeDiff);
if (sleepTime > 0)
{
// if sleepTime > 0 we're OK
try
{
// send the thread to sleep for a short period
// very useful for battery saving
Thread.sleep(sleepTime);
}
catch (InterruptedException e)
{
}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS)
{
// we need to catch up
// update without rendering
update();
// add frame period to check if in next frame
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
}
setVisible(false);
}
public void render()
{
gameScreenManager.render(g);
}
package Core.GameState;
import Core.GameCore;
import Game.Screens.TitleScreen;
import java.awt.Graphics2D;
import java.util.ArrayList;
public class GameScreenManager {
public ArrayList<GameScreen> gameScreens;
public static int currentState;
public GameScreen screen;
public static final int SCREEN_TITLE = 0;
public static final int SCREEN_LEVEL = 1;
public GameScreenManager() {
gameScreens = new ArrayList<GameScreen>();
currentState = SCREEN_TITLE;
screen = new TitleScreen(this);
gameScreens.add(screen);
}
public void setState(int state) {
currentState = state;
gameScreens.get(currentState).init();
}
public void update() {
gameScreens.get(currentState).update();
}
public void render(Graphics2D g) {
gameScreens.get(currentState).render(g);
}
public void keyPressed(int k) {
gameScreens.get(currentState).keyPressed(k);
}
public void keyReleased(int k) {
gameScreens.get(currentState).keyReleased(k);
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Game.Screens;
import Core.GameCore;
import Core.GameState.GameScreen;
import Core.GameState.GameScreenManager;
import Core.OptionsManager;
import Graphics.ScreenObject;
import Graphics.UserInterface.VolumeBar;
import Sound.BackgroundMusic;
import Sound.SoundLibrary;
import World.Layer1;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
/**
*
* @author Nils
*/
public class TitleScreen extends GameScreen
{
//music
BackgroundMusic titleMusic;
String musicFile = "/Music/Title.mp3";
Layer1 bg;
BufferedImage bgImage;
ScreenObject title;
ScreenObject lara;
Color selected;
Color deselected;
int currentScreen;
String[] options = new String[]
{
"Start", "Load", "Options", "Quit"
};
private int currentChoice;
private VolumeBar vb;
public TitleScreen(GameScreenManager manager)
{
this.gameStateManager = manager;
init();
}
@Override
public void init()
{
GameCore.options.volume = 100;
GameCore.options.targetting = true;
GameCore.options.graphics = 0;
GameCore.g.setRenderingHints(OptionsManager.graphicslow);
soundlib = new SoundLibrary("Title");
titleMusic = new BackgroundMusic(musicFile);
titleMusic.start();
selected = new Color(222, 217, 216);
deselected = new Color(80, 69, 67);
currentChoice = 0;
currentScreen = 0;
bg = new Layer1("/Graphics/Backgrounds/Cloud.jpg", 1);
title = new ScreenObject("/Graphics/Pictures/TitleLogo.png");
lara = new ScreenObject("/Graphics/Pictures/TitleLara.png");
lara.setPosition(40, 100);
title.setPosition((Core.GameCore.WIDTH / 2) - title.image.getWidth() / 2,
100);
}
@Override
public void update()
{
bg.setVector(-0.4, 0);
bg.update();
if (currentScreen == 0)
{
//Titlescreen
}
if (currentScreen == 1)
{
}
if (currentScreen == 2)
{
//Options
vb.update();
}
}
@Override
public void render(Graphics2D g)
{
bg.render(g);
}
@Override
public void keyPressed(int k)
{
[...]
}
@Override
public void keyReleased(int k)
{
}
}
this is a chain, how Graphics g is used.
When I put buffer.drawImage();
right after
gameScreens.get(currentState).render(g);
nothing is shown.
Alright, so change this
public void render()
{
gameScreenManager.render(g);
}
to this:
public void render()
{
gameScreenManager.render(buffer.createGraphics());
g.drawImage(buffer, 0, 0, buffer.getWidth(), buffer.getHeight(), 0, 0, getWidth(), getHeight(), null);
}
and have the
BufferedImage buffer;
in that class, and this in your initialize() method:
buffer = new BufferedImage(960,540,BufferedImage.TYPE_INT_RGB);
Ok, it now shows everything as normal.
I have changed the line to this:
g.drawImage(buffer, 0, 0, OptionsManager.currentDimension.width, OptionsManager.currentDimension.height, 0, 0, getWidth(), getHeight(), null);
this is my OptionsManager-Class
package Core;
import java.awt.Dimension;
import java.awt.RenderingHints;
import java.awt.Toolkit;
public class OptionsManager
{
public static int volume = 100;
public static int graphics = 0;
public static boolean targetting = true;
public static boolean fullscreen = false;
public static Dimension currentDimension = new Dimension(960, 540);
public static Dimension fullscreenDimension = Toolkit.getDefaultToolkit().getScreenSize();
public static Dimension windowDimension = new Dimension(960, 540);
public OptionsManager()
{
}
public static void toggleFullscreen()
{
if (fullscreen == false)
{
GameCore.frame.setSize(fullscreenDimension);
OptionsManager.currentDimension = fullscreenDimension;
fullscreen = true;
System.out.println(fullscreen);
}
else if (fullscreen == true)
{
GameCore.frame.setSize(windowDimension);
OptionsManager.currentDimension = windowDimension;
fullscreen = false;
System.out.println(fullscreen);
}
}
}
but it still doesn’t scale the Image
Only the frame changes it’s size.
If you want to render an image with a different width/height from the image itself, do this: [icode]g.drawImage(BufferedImage yourImage, int x, int y, int width, int height, ImageObserver imageObserver);[/icode]
ImageObserver can be null and width and height should be the width and height of your display if you want it to scale to your screen size.
So the image stays the same size within the frame, even when you resize the frame?
You might (probably) need to call
g.dispose();
g = (Graphics2D) getGraphics();
whenever the frame changes size to “refresh” the graphics object.
The image is still small, when changing screensizes
:
Do a quick
System.out.println("Width: "+getWidth()+", Height: "+getHeight());
before
g.drawImage(buffer, 0, 0, OptionsManager.currentDimension.width, OptionsManager.currentDimension.height, 0, 0, getWidth(), getHeight(), null);
to make sure that the frame is returning the correct numbers.
The Panel and Frame sizes are all correct…
Ahem
Try to draw the image using this method instead: [icode]g.drawImage(BufferedImage yourImage, int x, int y, int width, int height, ImageObserver imageObserver);
[/icode]
As I said before, ImageObserver can be null and the width and height should be the width and height of your display.
Oh, that works. ???
I should read javadoc first when using methods :
Thanks to you guys :]
Just another question:
before I used a bufferedImage, I used RenderingHints.
But now with the bufferedImage, they don’t work.
Some workaround to make them work again?
Are you setting the hints on the BufferedImage’s graphics object? 'Cause since that’s where the rendering happening, and that’s where the hints should be a applied.
I guess not.
My render-method looks like above:
public void render()
{
gameScreenManager.render(buffer.createGraphics());
g.drawImage(buffer, 0, 0, OptionsManager.currentDimension.width, OptionsManager.currentDimension.height,null);
}
Works now, I created a new Graphics-Object.