drawImage() for .png files doesn't work in Java applet? - java

I made this pacman game using an applet. When the applet finishes loading, it is meant to display a 'start menu' graphic i made which says 'Double click to start the game', etc. The graphic would take up the whole 400x400 applet. Here's the code:
public void paint(Graphics g)
{
if (! isRunning)
{
switch (result)
{
case 0:
showStartScreen(g);
break;
case 1:
showWonScreen(g);
break;
case -1:
showLostScreen(g);
break;
}
return;
}
//Code for rendering other stuff if game is here
}
showStartScreen:
public void showStartScreen(Graphics g)
{
Image intro=img.getImg("pacman-intro.png");
g.drawImage(intro, 0, 0, this);
}
This works fine when I run this locally on Eclipse, but in the web browser, when the applet is loaded I just see a blank box where the java's loading animation previously was. Surprisingly, if I double click randomly where the applet is meant to be, the game starts and works as normal. So this makes me think that the problem is just with drawing .png files using drawImage.
The same thing occurs when you win or lose the game,it just hangs instead of drawing the graphic it needs to.
You can see this here (you can use arrow keys to control)
P.S I am using double buffering here.
Any thoughts..?
EDIT: Code for ImgHelper class which is used to load the img:
import java.awt.Image;
import java.net.URL;
import javax.swing.ImageIcon;
public class ImgHelper
{
public Image getImg(String file)
{
//Engine is the name of the base applet class
URL url=Engine.class.getClassLoader().getResource("assets/" + file);
return new ImageIcon(url).getImage();
}
}

Ah, I checked the contents of your jar file.
Replace "pacman-intro.png" with "pacman-intro.PNG". It's case-sensitive.

Are the pngs in the right directory? Is "." in the path env-variable on the server?
Try "./pacman-intro.png" i.e.

Related

Background not showing up in java processing project

I think I'm doing everything right in my code but my background won't show up in my processing project, here is my code.
package finalproject;
import processing.core.PApplet;
import processing.core.PImage;
public class FinalProject extends PApplet {
PImage background;
PImage player;
public void setup() {
size(1360, 1080);
player = loadImage("player.png");
background = loadImage("rust.png");
}
public void draw() {
background(background);
image(player, 500, 500);
}
}
Processing expects files to be inside a data directory next to the code.
You're presumably running this from an IDE like Eclipse instead of the Processing editor, so where you put that data directory depends on how your code is setup. And you haven't posted a MCVE, so it's hard to help you with that.
But basically, you need to debug your sketch to figure out exactly where Processing is looking for the files. Then you need to move the files there. This is probably something simple like putting them inside a data directory.
If you still can't get it working, please post a MCVE along with a screenshot or a description of your directory structure.
If you are using the processing IDE than the data folder should be located in your sketch folder next to all the .pde files. Make sure that the image you are using has the same resolution as the sketch window. If you are still having issues I would recommend that you try moving your setup and draw methods out of your class and into the main processing sketch.

How to force ImageJ to close all its windows without close event error?

I am writing a Java application for image analysis which at one point opens ImageJ with
ImageJ ij = new ImageJ();
and also opens a Windows containing an ImagePlus.
Now, whenever one closes ImageJ first, the ImagePlus will not close when pushing the close button. The other way around works, however in both cases an exception is thrown after closing ImageJ:
java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(EventQueue.java:1288)
at java.awt.Window.doDispose(Window.java:1209)
at java.awt.Window.dispose(Window.java:1147)
at ij.ImageJ.run(ImageJ.java:784)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:56)
at java.awt.AWTEvent.<init>(AWTEvent.java:337)
at java.awt.event.InvocationEvent.<init>(InvocationEvent.java:285)
at java.awt.event.InvocationEvent.<init>(InvocationEvent.java:174)
at sun.awt.X11.XBaseMenuWindow.dispose(XBaseMenuWindow.java:907)
...
I don't know whether it is related as it happens in both cases.
Any suggestions on how to force ImageJ to close all its windows?
The exception
This happens when using OpenJDK 7 on Linux. The exception is fixed in Java 8.
Also: note that that exception is not the actual cause of the quitting issue you are seeing.
The disposal problem
ImageJ 1.x's application disposal is a convoluted mess. (See this news post for some technical discussion.) It was really intended primarily to run as a standalone application, and is mostly tested with the exitWhenQuitting flag set to true such that the JVM shuts down upon closure of the main window. So it is not surprising that using ImageJ in a different fashion results in hanging image windows.
I have tested various workarounds—e.g.:
ij.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(final WindowEvent e) {
// dispose all image windows
for (final int id : WindowManager.getIDList()) {
final ImagePlus imp = WindowManager.getImage(id);
if (imp == null) continue;
final ImageWindow win = imp.getWindow();
if (win != null) win.dispose();
}
// dispose all other ImageJ windows
for (final Window w : WindowManager.getAllNonImageWindows()) {
w.dispose();
}
}
});
But none of them work as one might hope. It cost me weeks of development and experimentation to make quitting work as we wanted in ImageJ2, according to the news posted linked above.
Here is some code using ImageJ2 that almost behaves the way you want:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import net.imagej.ImageJ;
public class IJDispose {
public static void main(final String... args) {
final ImageJ ij = new ImageJ();
ij.ui().showUI();
final JFrame frame = new JFrame("Hello");
final JButton b = new JButton("Close ImageJ");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
ij.getContext().dispose();
}
});
frame.getContentPane().add(b);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
After launching it, press Shift+B to open the Blobs sample image. Then click the "Close ImageJ" button from the non-ImageJ frame. You'll see that the ImageJ main window and the image window dispose as desired (using this code from ImageJ Legacy).
However, there are (at least) three problems:
This example does not hook up the ij.getContext().dispose() call to the actual ImageJ1 UI window closing event. And doing that would not be trivial (I say without having dug deeply in this code recently).
After disposing ImageJ, as well as the extra JFrame, the JVM is supposed to shut down. We put a lot of effort into making it do so, actually. But it actually doesn't with the current version of ImageJ, presumably due to some undisposed resource(s) somewhere. This is a bug.
Clicking the X on the main ImageJ window shuts down the entire JVM, because ImageJ1's exitWhenQuitting flag gets set to true. You could toggle it back to false yourself, but this is actually tricky due to class loading issues relating to the fact that ImageJ2 patches ImageJ1 at runtime using Javassist.
The next question is: How badly do you really need this to work?

How am I supposed to draw an image from my Java Applet?

I am not sure how to fully express this but, I have probably gone through 10 pages of Google links on this topic and not one of them has helped me solve my issue.
I thought it would be simple enough, I was just trying to add an image to the paint function of my java applet, like any other shape, but this has turned out to be a nightmare for me.
The problem is that every time I try to run the drawImage function it keeps saying Access Denied ("java.io.FilePermission" "Image.jpg" "read"). Yet, none of the tutorials mention this at all, all they ever say is that I should do the following:
import java.applet.*;
import java.awt.*;
Image img;
//These would go in the paint function
img=getImage(getDocumentBase(),"/Image.jpg"); //I have tried without the slash too
g.drawImage(img,20,20,this);
This is all they do and it works for them, but it just won't work for me. Other methods are far too complex for the sake of just adding an image, and even when I go through the toil of doing those it keeps giving me the "Access Denied" message. There's also the method of "signing" it, but I really don't think that's going to help given all that I have tried, so I am afraid it might just be another wasted endeavor. None of the tutorials even tell you to have your applet signed.
I have the image in the "build" (also called bin) folder together with the classes.
The program seemed to run when I included the entire file path, but even then the image did not display. That is not to mention I can't really include the complete path from my own computer because then it wouldn't work when I actually send it to another person.
Please, I just want to know why it doesn't work for me yet seems to work perfectly for others. That, and if there's a way around this.
This is an example of what I am doing:
import java.applet.*;
import java.awt.*;
public class JavaProject extends JApplet
{
Image img;
public void init()
{
img=getImage(getDocumentBase(),"/Image.jpg");
}
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(img,20,20,this);
}
}
This is my HTML file:
<html>
<head>
<title> My First Web Page </title>
</head>
<body>
<applet code="JavaProject.class" width="400" height="500">
</applet>
</body>
</html>
According JApplet java docs method getImage(URL url, String name) should have two parameter: URL-link to picture and String name.
Is method getDocumentBase() returnig an URL-link?
You must start by understanding that an Applet, unless signed, may not read from the file system. It must use either classpath resources or things fetched from the same place it was fetched from. You have to decide which of these applies to you. If the image is a fixed image, you can put it in your classpath as a resource, and use Class.getResourceAsStream. If it's a different image every time, you'll have to use HTTP.
Try this one if the image in the "build" (also called bin) folder together with the classes.
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import javax.swing.JApplet;
public class JavaProject extends JApplet {
Image img;
public void init() {
img = getImage(getDocumentBase(), "images/222.png");
// Please ensure that 222.png is placed under bin/images folder directly
}
#Override
public void paint(Graphics g) {
update(g);
}
#Override
public void update(Graphics g) {
g.drawImage(img, 20, 20, this);
}
}
Try with HTTP URL first
URL myURL = new URL("https://www.gravatar.com/avatar/a94613cea642e6e9e2105867bc2e103e?s=32&d=identicon&r=PG&f=1");
img = getImage(myURL);
If you are using Eclipse under Windows then have a look at below screenshot:
Please have a look at below post to get some understanding about it.
java.io.FilePermission exception - Read from jar file?

Java graphics are flashing

Okay, I understand your need for an SSCCE, so I created (my first) one.
I managed to replicate the problem with under 200 lines of code. On my system this demo compiled and ran perfectly (only the flickering was still there of course).
I stripped everything that had nothing to do with it. So basically we have two source files now: the screen manager and the game manager.
The screen manager:
http://pastebin.com/WeKpxEXW
The game manager:
http://pastebin.com/p3C5m8UN
You can compile this code with this make file (I use a ported version of Linux' make for Windows):
CC = javac
BASE = nl/jorikoolstra/jLevel
CLASS_FILES = classes/$(BASE)/Game/GameMain.class classes/$(BASE)/Graphics/ScreenManager.class
jLevel: $(CLASS_FILES)
#echo Done.
classes/%.class : src/%.java
#echo Compiling src/$*.java to $# [command: $(CC) src/$*.java ] ...
#$(CC) -Xlint:unchecked -d classes -classpath src src/$*.java
Where the source files are placed in the /src directory and the classes in the /classes directory.
After compilation to byte-code the game can be started using the following .bat file:
#set STARUP_CLASS=nl.jorikoolstra.jLevel.Game.GameMain
#set ARGUMENTS=1280 1024 32
#java -cp classes;resources %STARUP_CLASS% %ARGUMENTS%
Note that the ARGUMENT variable depends on your own screen settings and that you have to change it so that the game is displayed in the right resolution for your screen.
I see why it is flickering ----
BufferStrategy is doing a separate painting job from the Component's paint() method and they seem to use different Graphics objects and they are refreshing at a different rate --
when paint() is invoked before show(), it's fine. But
when paint() is invoked after show(), it will repaint the component to its initial blank look -- so flashing happens.
It's very easy to eliminate the flickering: override paint() method of your JFrame (GameMain) as you don't need it to do anything (BufferStrategy can give you more precise control on painting stuffs):
#Override
public void paint (Graphics g) {}
That's all. (I have tested it and it works fine, hope this may help :))
===== Update =====
Instead of overriding paint() method, a better way is to call setIgnoreRepaint(true) for your JFrame (GameMain) -- this method is just designed for such purposes! USE IT!
private GameMain(String ... args)
{
setIgnoreRepaint(true);
.....
}
This is how i implement double buffering, might help you get the concept.
Note it's implemented in a JPanel, but i think it can be implemented in other containers:
TheJApplet.java:
import java.awt.*;
import javax.swing.*;
public class TheJApplet extends JApplet
{
private Image myImage;
java.net.URL GameURL = CheckerGameJApplet.class.getResource("GameIMG");
String GamePath = GameURL.getPath();
#Override
public void init()
{
String GraphPath = GamePath+"/";
File myImage_File = new File(GraphPath+"myImage.jpg");
try
{
myImage = ImageIO.read(myImage_File);
}
catch (IOException ex)
{
// Add how you like to catch the IOExeption
}
final TheJPanel myJPanel = new TheJPanel(myImage);
add(myJPanel);
}
}
TheJPanel.java:
import java.awt.*;
import javax.swing.*;
public class TheJPanel extends JPanel
{
private int screenWidth = 500;
private int screenHeight = 500;
private BufferedImage BuffImg = new BufferedImage
(screenWidth,
screenHeight,
BufferedImage.TYPE_INT_RGB);
private Graphics2D Graph = BuffImg.createGraphics();
private Image myImage;
public TheJPanel(Image myImage)
{
this.myImage = myImage;
repaint();
}
#Override
public void paintComponent(Graphics G)
{
Graphics2D Graph2D = (Graphics2D)G;
super.paintComponent(Graph2D);
if(BuffImg == null)
{
System.err.println("BuffImg is null");
}
Graph.drawImage(myImage, 0, 0, this);
Graph2D.drawImage(BuffImg, 0, 0, this);
}
}
Hope this helps, good luck.
I have a cross-platform Java AWT-based program with animation. It had flashing problems until I strictly followed the example code at in the Java BufferStrategy documentation. However I'm using an AWT Canvas embedded in a Swing hierarchy, not full screen as you. You can see the code here if interested.
Another thing to note is that the AWT pipeline uses OpenGL primitives for good performance, and OpenGL support is buggy in many video drivers. Try installing latest versions of drivers for your platform.
It may work for you, when you set your hwnd.createBufferStrategy(2) in its own method.
There was a problem with Java rendering transparent background GIF images. That could be the problem.
I find it rather difficult to answer your question without an SCCSE. I also wonder what the RepaintManagerResetter does.
You might want to set your background color to some fancy colors like 0xFF00FF to find out if someone "clears" the background before the drawing happens. If the flicker image is purple, it's that - if it contains garbage or old images, it's probably the double-buffering.
In any case I would try to ensure that noone draws expect yourself. First, try to prevent native Windows code from drawing the window background. Set this once:
/*
* Set a Windows specific AWT property that prevents heavyweight components
* from erasing their background.
*/
System.setProperty("sun.awt.noerasebackground", "true");
Also, make sure that you override this in your JFrame(if you are using Swing components)
#Override
public void paintComponent(Graphics G)
{
// do not call super.pC() here
...
}
If that doesn't help, please provide a working example of your code, so people can reproduce the problem.

Eclipse displaying images in a java applet

I want to display a simple image of a ball in my applet (using getCodeBase()), but when I run my applet, either nothing is displayed, or I get a syntax error from eclipse on my String argument in the getImage method.
My error is "Syntax error: invalid escape sequences. Only \b \n \f \" \' allowed."
My image is stored in C:\Java\eclipse\Images(Java)\ball.gif
Here is my code:
import java.awt.*;
import java.applet.*;
public class Image1 extends Applet {
private static final long serialVersionUID = 1L;
Image pic;
public void init(){
pic = getImage(getCodeBase(), "\Images(Java)\ball.gif");
}
public void paint(Graphics g){
g.drawImage(pic,0,0,this);
g.drawImage(pic, 100,100,125,100,this);
}
}
Just some tips...
A) You cannot get local image with getCodeBase() method because it
returns http://... applet location path. In your IDE case, http is not available...
B) To get host image with getCodeBase() you have to deploy your
applet on a real host instead of testing it with AppletViewer
C) If you just need an image for testing your applet in IDE you can simply get it
by using ImageIO. As I can remember AppletViewer is OK with io.*; lib
Good luck

Categories