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.
Related
I'm working on a Java project in Eclipse that has a class extending PApplet to run a Processing sketch.
First I have a JFrame login screen, and after the user logs in there, I call
PApplet.main("Game"); //"Game" is the class that extends PApplet
to start the sketch.
Now when the game ends I want to close the sketch window, but not the original JFrame window.
Normally I would call
exit();
in Processing but this closes the entire application (ie all windows).
I have also tried
dispose();
but this does nothing.
I guess I'm looking for something like
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
but for PApplet.
First, you have to get the instance holding your sketch. That means using the runSketch() function instead of calling main() directly:
Game game = new Game();
String[] args = {};
PApplet.runSketch(args, game);
Now that you have a reference to your sketch instance, you can use it to get to the internal window. How you do this depends on which renderer you're using, but you can figure it out using a mix of the Processing JavaDoc and the Processing source code.
Here's an untested example using the default renderer:
PSurface surface = game.getSurface();
SmoothCanvas smoothCanvas = (SmoothCanvas)surface.getNative();
JFrame frame = (JFrame) smoothCanvas.getFrame();
Now that you have the parent window, you can do whatever you want with it, including:
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setVisible(false);
Like I said I haven't tested this code, and this is going to depend on exactly which renderer you're using, but this process of using the source code and JavaDoc to figure out what's going on under the hood to get to the underlying window is what you have to do.
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.
So I have two classes.
One is a class called Main. The Main class is supposed to process some data.
Then I have another class called MainApplet, an Applet of course.
How can I display MainApplet from the Main class? This is what I have so far, but the applet does not show:
public class Main {
public static void main(String args[]) {
System.out.println("Starting application.");
MainApplet Main = new MainApplet();
Main.setVisible(true);
Main.show();
} }
How can I display MainApplet from the Main class?
You don't. You display an applet from HTML code.
Are you sure your GUI is in fact an applet? Does it extend JApplet or Applet? If so and you want to show it on the desktop through code, then don't make it an applet but instead display a JFrame. The Java Swing tutorials will show you how to do this: How to use Swing Components
Edit
you state:
Basically I have a Main class that is not an applet. It doesn't extend anything. Then I have another class named MainApplet that is an applet (extends JApplet). I want to run Main first, then display MainApplet after... but I can do it the other way around if needed.
You don't sound like you're running your code from a web page (for some reason you're still keeping this information from us), so the solution is not to use applets for this. Instead create a JFrame. Please check out the tutorials that I've linked to above since an applet is not appropriate for your needs.
You will have a main that creates your GUI, that passes any information into the GUI via constructor or method parameters, and then that tells the GUI to show itself (by calling setVisible(true) if it's a JFrame).
Your mainApplet class must extend Applet. You would then replace your main(...) method with init(...) as this is the method that gets called when you open an Applet. You can test this in most environments such as Eclipse. It order to actually put the Applet on a webpage, you must tell the applet to display using HTML in the page.
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
}});
I am in the process of turning my java application into a web applet. So far I can export the jar, sign it, and apparently launch it. The Java loading image plays endlessly and my application's JFrame window pops up and connects to my application's server. Unfortunately, as an applet, the JFrame seems to be frozen. It never renders anything and the window's content is merely the shadows of the frame buffer of objects dragged across it.
The application version runs fine, and the applet version runs fine through Eclipse's applet player. It's only on the web that the rendering craps out. I thought that signing the applet would let it work as it did as an application.
It seems that making an application into an applet is a bit more complicated than I first anticipated. What considerations should I make when making this conversion?
If you can see the applet's console, you might be able to see an exception there.
You might also want to set an AWT uncaught exception handler:
static public final class UncaughtAwtExceptionHandler {
public static void installAsUncaughtAwtExceptionHandler() {
System.setProperty("sun.awt.exception.handler",
UncaughtAwtExceptionHandler.class.getName() );
}
public UncaughtAwtExceptionHandler() {
/* Nothing to construct */
}
public void handle(Throwable ex) {
/* Do something here to transmit the exception
to your server, or log it, or whatever */
}
}
Since an exception on the AWT thread is probably what's causing your problem, this will give you the option of better discovering what that problem is.