Java repaint() Doesn't Work In Browser - java

I've made a game in Java which works without any problem when I run it in Eclipse. Everything looks great and it is effectively done (at least until I come up with something else to do with it). So I've been trying to put it on my website, but whenever I run the game in browser I simply get a white screen, though checking the Java console shows no errors. I've managed to narrow the problem down to the painting of the screen. I have a timer which runs the game and makes stuff happen. At the end of it, it calls the repaint() method. In Eclipse, that works fine, but in the browser, nothing happens.
Here's the relevant code (All of which is inside the main class called FinalProject):
public class FinalProject extends JApplet implements ActionListener,
KeyListener, MouseListener, MouseMotionListener {
public void init(){
//...initialize program
System.out.println("game started");
}
/**
* A method called every so often by a timer to control the game world.
* Mainly calls other functions to control objects directly, but this
* is used as the only timer, which also calls repaint() at it's end.
*/
private void runGame(){
//...Run game and do important stuff
//This Draws The Screen
System.out.println("about to paint");
repaint();
}
public void paint(Graphics g){
System.out.println("painting");
//...paint screen
}
public void update(Graphics gr){
System.out.println("updating");
paint(gr);
}
}
runGame() is called by a timer. In Eclipse the output is:
game started
painting
painting
about to paint
painting
about to paint
painting
about to paint
painting
...
When doing this in a browser (Running offline directly on my machine. All browsers have the same problem as well), the console shows:
...(loading stuff)
game started
basic: Applet initialized
basic: Starting applet
basic: completed perf rollup
basic: Applet made visible
basic: Applet started
basic: Told clients applet is started
about to paint
about to paint
about to paint
...
I don't know what else to try at this point. Despite my efforts I still don't fully understand exactly what repaint() does, all I know is that it ultimately calls update() and paint(). Except that doesn't seem to be happening in the browser. I'm using Windows 7 64x with Java Version 7 Update 5. Thanks in advance for any help.

Turns out, the problem was in removing the menu bar. I had found some code a while ago which would remove the menu bar from the program and it worked without any problems. However it seems that it prevented it from repainting when placed in a browser. I have no idea why repainting broke because of removing the menu bar, but apparently it does.
The code I had used (in init()):
Frame[] frames = Frame.getFrames();
for (Frame frame : frames){
frame.setMenuBar(null);
frame.pack();
}
This code did remove the menu bar as desired, but also exploded the program whenever it was put online. Removing this fixed the issue. Fortunately, the menu bars don't show up online anyways, so you aren't losing much by removing this bit of code.

Related

Query about applets in java

I am unable to understand why the println() statement inside paint() is executing twice.This is the code-
import java.awt.*;
import java.applet.*;
public class FirstApplet extends Applet
{
public void init()
{
System.out.println(getBackground());
}
public void paint(Graphics g)
{
setBackground(Color.CYAN);
setForeground(Color.RED);
g.drawString("This is my first Applet",250,250);
System.out.println(getBackground());
}
}
OUTPUT:
java.awt.Color[r=255,g=255,b=255]
java.awt.Color[r=0,g=255,b=255]
java.awt.Color[r=0,g=255,b=255]
Can somebody please explain me why the println() inside paint() is executing twice?
public void paint(Graphics g)
{
setBackground(Color.CYAN); // will trigger repaint()!
setForeground(Color.RED); // will trigger repaint()!
g.drawString("This is my first Applet",250,250);
System.out.println(getBackground());
}
The paint(Graphics) method is called whenever the toolkit feels it is necessary to do so. There are many things that will cause a repaint() (which in turn, leads to a call to paint(Graphics)). Some of them are:
A window moves in front of, or is removed from in front of, the app.
The size of the app. changes.
The background or foreground color changes or a component state changes.
A menu opens or closes.
...
Obviously, a paint does not happen only the times the programmer wants (or expects) it to. If that 'paint whenever needed' is a problem for the app., it is the apps. problem to sort, not the toolkits.
Queries for you:
Why code an applet? If it is due to the teacher specifying it, please refer them to Why CS teachers should stop teaching Java applets.
Why use AWT? See this answer for many good reasons to abandon AWT using components in favor of Swing.

Why won't Applets run on NetBeans? And how do I get them to run?

I use NetBeans for Java programming, and whenever I try to make an Applet, it doesn't work. The code is completely correct and I did not make any mistakes on it. When I hit "Run" a message appears in the output box that says, "BUILD SUCCESSFUL (total time: 0 seconds)" There are no error messages and no errors in the code, the Applet doesn't appear. The code is:
import java.applet.*;
import java.awt.*;
public class myProject extends Applet
{
public void init()
{
}
public void paint(Graphics g)
{
setSize(500,500);
}
public static void main(String[] args)
{
}
}
Get rid of the main method. If you're running the code as an applet, main will just confuse you and the IDE.
Make sure that you're telling NetBeans to run it as an applet, not as an application. Again, removing main should help you with this, since without main it can't run it as an app.
Consider not creating applets since they're considered somewhat dead technology.
Don't have setSize(...) within a paint method. Ever. GUI painting methods, such as paint(...) for AWT components and paintComponent(...) for Swing components derived from JComponent, should just do painting and nothing else.
Check out the Java Swing tutorials which can be found here: Swing Info

Libgdx on desktop, how to handle disposing when window is closed

I'm using libgdx (com.badlogic.gdx.Game and Screens and that stuff) to make a game. I have the following problem: on desktop, when I close the window (from the cross on top), of course the application closes. But I would like to go back to menu screen and dispose there, since I do disposing of resources there (via asset manager). I have buttons for exiting in the game and if exiting is done that way, it's fine. The trouble is that the red cross can be pressed. So how could I handle disposing properly in that case?
On the android version, I catch the back key and handle leaving different parts of the game and the whole game in my own way. And there it works OK.
Another related question I have:
On desktop the application cannot get stopped and then disposed (on it's own, without user explicitly exiting it) like the android version can (the android life cycle), right? So is it a good idea, if I do a temporary save on pause() and restore game state from that on resume(), that I don't restore on desktop (since the restoring isn't a complete restore and I don't want restoring to happen if, on desktop, the window is just minimized (as I noticed, pause()/resume() gets called when minimizing/restoring window )).
Hope this wasn't too unclear :D. I've tried to google for answers but don't seem to find anything. Any help is much appreciated.
I suggest using the libgdx life-cycle methods
To dispose you should use the dispose() method. You don't need to call dispose yourself! It will be called automatically when the application gets destroyed, see documentation:
dispose () Called when the application is destroyed. It is preceded by a call to pause().
So just implement the dispose method in your Screens:
#Override
public void dispose () {
//your code needs to get added here, like for example:
stage.dispose();
texture.dispose();
//etc..
}
Update: Note that dispose() of AppliacationListener gets called automatically, not dispose() of Screen, see comment of Springrbua
You can call dispose() of your Screen by calling it explicitly from your Game Class dispose() like this
MyScreen Class:
public class MyScreen implements Screen {
// Not going to write all other methods that need to be overridden
#Override
public void dispose() {
// Clear you Screen Resources here
}
}
MyGame Class:
public class MyGame extends Game {
// Not going to write all other methods that need to be overridden
#Override
public void create() {
setScreen(new MyScreen());
}
#Override
public void dispose() {
// Clear you Screen Explicitly
getScreen().dispose();
}
}
Hope this helps
As mentioned above, the Screen interface contains a dispose method. Additionally, the dispose method of Game can be overridden to dispose of the current screen automatically. However, there is a reason this is not the default. Let's say you have multiple Screens - Screen1and Screen2. Screen1 was active, then changed the screen to 2. The game is then exited, and the dispose method is called, which calls the current screen's dispose method - leaving screen 1 alone.
My preferred method is to have the game keep track of screens set by overriding the setScreen method and adding a Screen[] screens, a boolean[] scrDiss, and an index. When dispose is called on Game, it checks through all screens set, checks if previously disposed, and disposes if not. Additionally, the Screen dispose methods should call a method on the Game that finds it in the array, and marks it disposed. This way, screens can be disposed before the end of the Game, but when Game is disposed, all Screens will be as well.
Call dispose on all your screens when your application is disposed.

How to preload Swing components

I know this is sort of a vague question, but I will try to make it as clear as possible. When my Java app launches for the first time, it does some checking to see if files and directories exist and checks for an internet connection.
The app then allows the user to move on to the dashboard, which requires loading and adding many Swing components to the Background Panel. This takes time.
I was wondering how I could make it so that during the loading process at the start, the app loads all of the Swing components Images etc. so that they appear instantly when the user executes the command to do so.
I can load all of the components like this:
JButton = new JButton("blah");
but I'm not sure that's enough to make the components appear instantly, wouldn't adding several image filled Swing components at the same time still lag the UI thread, even if it was already "loaded" as seen above?
Thanks!
on the components use
setVisible(false)
for example
public class myParentPanel extends JPanel{
public myParentPanel{
//add all the child components
//Do what ever takes along time
setVisible(false); //this then makes in invisible but still
//allows all the set up code to run
}
public void showParent(){
setVisible(true);
invalidate();
}
}
and then create a method to make them visible when required. Hence all your setting in the constructors ca be called then when you call your method say:
drawWindow()
it then only has to call setVisible(true) and invalidate the screen to call their painting methods :).
An advancement on this would be to *run your setups i.e your checking and loading the panels methods on a separate threads*so you don't have to wait for a sequential loading. So on your loading you may to use an anonymous class
SwingUtilities.invokeLater(new Runnable(){ public void run(){
//do my display set up
}});

JApplet will not launch JComponent in browsers, works in Eclipse

I have coded a game proto-type in Java during my spare-time. This game was merely for my educational purposes only. I have it working fine via a JNLP launch file on the web, as well as on my main machine, via a JFrame.
My main intention is to make this proto-type playable in web-browsers via the use of a JApplet. I have coded a class, called AppletPlayer.java. The intention of this class is to essentially serve as a launcher for my Game's main class. The AppletPlayer.java file is pretty much as follows:
public class AppletPlayer extends JApplet {
private Game myGame_; // This is my game's main class
private boolean started_ = false;
public void init() {}
public void start() {
if (!started_) {
started_ = true;
myGame_ = new Game();
this.setContentPane(myGame_);
myGame_.start() // I set focusable, and enabled to 'true' in the Game's start method
// My Game class has no init method. Just a start method that spawns a new thread, that the game runs in
}
}
Now, the Game class itself extends JComponent, and implements Runnable, KeyListener, and FocusListener. If I launch AppletPlayer via Eclipse it works like a charm in its Applet Viewer. However, when I deploy to the web I see two things:
On a Windows XP machine the Applet loads, stays stuck on the main title screen, never receiving focus, hence never registering any type of user input.
On a Windows 7 Machine the Applet loads, I hear my game's music, but the Applet screen itself renders a plain white box and nothing else.
These issues occur in both IE and Firefox.
I have been perusing Google and StackOverFlow for awhile now, trying to dig up a solution but haven't had any luck. I am a bit unfamiliar with Applets, and was hoping for a nudge in the right direction.
One thing that may be the reason: Swing is not thread-safe, so all changes on the GUI (with includes your setContentPane) should occur in the AWT event dispatch thread. The start() method of an applet is not called on this thread.
Wrap all your GUI-related method calls in an EventQueue.invokeLater(...) call (or invokeAndWait, if you need some results, and SwingUtilities also has these methods, if you prefer) and look if you see some changes.

Categories

Resources