Avatar billede martin_schou Nybegynder
03. april 2002 - 11:44 Der er 17 kommentarer og
1 løsning

Billede (og andet) fra jar-file

Jeg har en applet, der køres fra en jar-fil via en webserver. I jar-filen har jeg gemt nogle billeder, som jeg gerne vil have fingrene i - men jeg kan ikke finde nogen metode til det.

Javaworlds lektion/tip #49 (http://www.javaworld.com/javaworld/javatips/jw-javatip49.html) virker tilsyneladende kun på jarfiler, der ligger på det lokale filsystem, og det kan jeg ikke bruge til noget (med mindre en af jer tilfældigvis har fundet ud af, hvordan man kan få ovennævnte trick til at virke over netværk).
Avatar billede martin_schou Nybegynder
03. april 2002 - 11:45 #1
Glemte lige noget. Løsningen skal virke i java 1.1 (skal som sagt køre fra en applet, og IEs jre 1.1 er bundskraberen/laveste fællesnævner :-/ )
Avatar billede disky Nybegynder
03. april 2002 - 12:11 #2
Det er en velkendt bug der endnu ikke er løst:
http://developer.java.sun.com/developer/bugParade/bugs/4238086.html

men andre steder ser det ud til at virke:
http://developer.java.sun.com/developer/bugParade/bugs/4157932.html
Avatar billede disky Nybegynder
03. april 2002 - 12:12 #3
var et svar
Avatar billede martin_schou Nybegynder
03. april 2002 - 12:21 #4
Disky: Det holder da vist ikke helt :-)

http://developer.java.sun.com/developer/bugParade/bugs/4238086.html

"When trying to load an ImageIcon from an application jar file that resides on an unmapped network directory, the image
will not load.  If you map the path to a drive instead of using the UNC path, the image is able to be loaded."

Det er ikke ret behjælpeligt, når jar-filen skal virke i en vilkårlig browser. (Min fejl - skulle have beskrevet scenariet bedre).

http://developer.java.sun.com/developer/bugParade/bugs/4157932.html

"ImageIcon properly loads images from a jar file when within the JApplet init()
method."

Er JApplet ikke en del af swing og dermed en del af jdk1.2+?

Internet Exploders JRE 1.1 er laveste fællesnævner, så løsningen skal kunne virke i den - og der er ikke mulighed for at mappe et netværksdrev ;-).
Avatar billede disky Nybegynder
03. april 2002 - 13:04 #5
Prøv denne her:
It is possible to access images stored in JAR files by going through the
class loader mechanism.  The following code from xxxxx@xxxxx evaluation
will successfully load an image.

        URLClassLoader cl = (URLClassLoader)this.getClass().getClassLoader();
        System.out.println("AppletClassLoader: " + cl);
        url = cl.findResource("Exodus/Splash.gif");
        if (url != null)
            System.out.println("Resource URL: " + url);

        splash = getImage(url);

This paradigm can be followed to access audio clips as well.
Avatar billede carstenknudsen Nybegynder
03. april 2002 - 13:34 #6
Jeg har haft et lignende problem og har
løst det med en lille klasse jeg skrev hvor
ud også kan hente images fra url'er.
ImageLoader.java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;

/**
* The ImageLoader class is used for loading images
* from various sources, including regular files,
* and files located in a jar file included in the classpath, as well as from urls.
* The class has no public constructor, it is used through
* the static methods {@link #getImage(String)} and
* {@link #getImage(InputStream)}.
* <br><b>Example of use:</b><br>
* If the image is located in a jar file it can be retrieved
* with the method invocation:
* <pre>
* Image image = ImageLoader.getImage( "myPic.gif" );
* </pre>
* If the image is located in a subdirectory images in the jar file use:
* <pre>
* Image image = ImageLoader.getImage( "images/myPic.gif" );
* </pre>
* or the previous invocation, though the latter is preferred,
* as it is more efficient if the full path is provided.
* <br>To load from a url use:
* <pre>
* Image image = ImageLoader.getImage( "http://www.fys.dtu.dk/~janet/janetlogo.gif" );
* </pre>
* To create a label with an image use:
* <pre>
* Image image = ImageLoader.getImage( "http://www.fys.dtu.dk/~janet/janetlogo.gif" );
* JLabel label = new JLabel( new ImageIcon( image ) );
* </pre>
* @author Carsten Knudsen
* @version 1.0
**/
public class ImageLoader {

    private static String classpath = null;
    private static String pathseparator = null;
    private static String fileseparator = null;
    private static int bufferSize = 4096;

    private ImageLoader() {
    } // constructor

    /**
    * The static method getImage tries to locate a file with the
    * provided name.
    * The named image may be located in a file, at a url,
    * or located in a jar file, which must be in the classpath.
    * If the image could not be located null is returned.
    * @return the image requested or null if it could not be located
    * @param name is the name of the file in which the requested image is located
    **/
    public static synchronized Image getImage( String name ) {
    Image image = null;
    URL url = null;
    // attempt to load image from a file
    File file = new File( name );
    if ( file.exists() ) {
        image = Toolkit.getDefaultToolkit().getImage( name );
        if ( image != null )
        return image;
    } // if
    // attempt to load image from a url
    try {
        url = new URL( name );
        if ( url != null ) {
        image = Toolkit.getDefaultToolkit().getImage( url );
        if ( image != null )
            return image;
        } // if
    } // try
    catch ( MalformedURLException murle ) {
    } // catch
    // attempt to load image as a resource
    url = Class.class.getResource( name );
    if ( url != null ) {
        image = Toolkit.getDefaultToolkit().getImage( url );
        if ( image != null )
        return image;
    } // if
    // attempt to load image from a Java archive manually
    if ( classpath == null ) {
        classpath = System.getProperty( "java.class.path" );
        pathseparator = System.getProperty( "path.separator" );
        fileseparator = System.getProperty( "file.separator" );
    } // if
    StringTokenizer tokenizer = new StringTokenizer( classpath, pathseparator );
    while ( tokenizer.hasMoreTokens() ) {
        String token = tokenizer.nextToken();
        int idx = token.lastIndexOf( fileseparator );
        // Extract the packagename, e.g. Janet.jar from absolute path
        String packageName = token.substring( idx + 1, token.length() );
        if ( packageName.endsWith( ".jar" ) ) {
        try {
            JarFile jar = new JarFile( token );
            Enumeration enum = jar.entries();
            String filename;
            // iterate through all jar entries
            while ( enum.hasMoreElements() ) {
            JarEntry entry = (JarEntry)enum.nextElement();
            filename = entry.getName();
            // is it a file?
            if ( ! filename.endsWith( fileseparator ) ) {
                // is the current entry a candidate for the requested image
                if ( filename.endsWith( name ) ) {
                image = getImage( jar.getInputStream( entry ) );
                if ( image != null )
                    return image;
                } // if
            } // if
            } // while
        } // try
        catch ( IOException ioe ) {
            // do not return null as there may be another file with the
            // same name that may be what we are looking for
        } // catch
        } // if
    } // while
    return null;
    } // getImage
   
    public static synchronized Image getImage( InputStream is ) {
    int bytes_read;
    is = new BufferedInputStream( is );
    byte[] buffer = new byte[ bufferSize ];
    java.util.List bytes = new ArrayList();
    java.util.List lengths = new ArrayList();
    try {
        while ( ( bytes_read = is.read( buffer ) ) != -1 ) {
        bytes.add( buffer );
        lengths.add( new Integer( bytes_read ) );
        buffer = new byte[ bufferSize ];
        } // while
        is.close();
    } // try
    catch ( IOException ioe ) { // if anything went wrong we did our best
        return null;
    } // catch
    int size = 0;
    int[] ints = new int[ lengths.size() ];
    for (int i = 0, n = lengths.size(); i < n; i++) {
        size += ( ints[ i ] = ((Integer)lengths.get( i )).intValue() );
    } // for
    byte[] array = new byte[ size ];
    int k = 0;
    for (int i = 0, n = bytes.size(); i < n; i++) {
        byte[] b = (byte[])bytes.get( i );
        int m = ints[ i ];
        for (int j = 0; j < m; j++) {
        array[ k++ ] = b[ j ];
        }
    } // for
    return new ImageIcon( array ).getImage();
    } // getImage
   
    /**
    * The method setBufferSize sets the size of the buffer used
    * when loading images.
    * The size must be a positive quantity.
    * @see #getBufferSize()
    * @param size the new size of the buffer used
    **/
    public synchronized void setBufferSize( int size ) {
    if ( size > 0 )
        bufferSize = size;
    } // setBufferSize
   
    /**
    * The method returns the buffer size used when loading images.
    * @see #setBufferSize(int)
    * @return the buffer size used when loading images
    **/
    public synchronized int getBufferSize() {
    return bufferSize;
    } // getBufferSize

    public static void main( String[] args ) throws MalformedURLException {
    Image image = ImageLoader.getImage( args[ 0 ] );
    if ( image != null ) {
        final JFrame frame = new JFrame();
        frame.getContentPane().add( new JLabel( new ImageIcon( image ) ) );
        frame.pack();
        frame.addWindowListener( new WindowAdapter() {
            public void windowClosing( WindowEvent we ) {
            frame.dispose();
            }
        }
                    );
        frame.show();
    }
    } // main

} // ImageLoader
Avatar billede martin_schou Nybegynder
03. april 2002 - 14:00 #7
Disky: Det virker en hel del bedre :-)
Carsten: Jeg her ikke testet, om din løsning virker - primært fordi det er en STOR løsning, når jeg har MEGET lidt plads at give af (mindre end 500(!) bytes).

Næste opgave for mig er så at få Internet Explorer til at give en bedre fejlkode end:

java.lang.NoClassDefFoundError
java.lang.ClassNotFoundException: IBI.ImageCanvas

Gad vide om Internet Explorer kan håndtere pakker?
Avatar billede disky Nybegynder
03. april 2002 - 14:13 #8
Martin:
Glæder mig det virker :)

Angående sidste spørgsmål, hvad mener du med pakker ? Mener du packages ? det kan den godt.

Carsten: hold da ferie en masse for så lidt :)
Avatar billede martin_schou Nybegynder
03. april 2002 - 14:17 #9
Disky:
Ja, jeg ville jo også mene, at den kan håndtere packages, men det er sgu ikke nemt at vide, hvad fejlen er, når Internet Explorer ikke vil fortælle mig, hvor fanden fejlen gemmer sig.

ARGH! Jeg hader at lave applets til IE.
Avatar billede carstenknudsen Nybegynder
03. april 2002 - 14:36 #10
disky: det er faktisk ikke meget for den kan
lokalisere filer selv om du ikke kan hele
deres path, de andre løsninger kan kun
finde dem hvis de har hele path'en.
Se det er smart.
Avatar billede disky Nybegynder
03. april 2002 - 14:52 #11
martin: helt enig.

carsten: jeg ved nu altid hvor mine billeder ligger gemt, så jeg har ikke brug for at programmet skal tænke for mig :-) Men ellers sikkert en smart ting.
Avatar billede martin_schou Nybegynder
03. april 2002 - 14:53 #12
Pis! java.net.URLClassLoader er fra jdk1.2 og kan altså ikke tilgåes fra IEs jre1.1 ...

Og så undrer folk sig over, at vi java-programmører brokker os over Microsoft?
Avatar billede bearhugx Nybegynder
03. april 2002 - 19:47 #13
Sikkert et dumt spørgsmål ... Men hvorfor "downgrade" til jre1.1 -- Hvad version af IE er i brug... - Please enlighten me!

Kan man ikke DL'e seperat VM til IE fra sun???

/Søren
Avatar billede martin_schou Nybegynder
04. april 2002 - 09:12 #14
Bearhugx:
IE x.x - der er som sagt tale om en _vilkårlig_ browser.

Man kan godt downloade en seperat VM til IE (jre 1.4 virker fint), men det hjælper ikke ret meget, for systemet skal kunne virke i en vilkårlig browser - f.eks. også på håndholdte computere og mobiltelefoner, der kan køre Java.

Endvidere har jeg kun 256 kilobytes at gøre godt med - alt i alt, så jeg kan ikke engang placere en JVM på webserveren.
Avatar billede bearhugx Nybegynder
04. april 2002 - 18:10 #15
So you tell me.... Men hvorfor denne grænse på 256kb på webserveren -- Er det en PDA, der skal hoste eller ???

*Nysgerrigt interesseret*

/Søren

PS: er du den Martin Schou, som var HB-rep for PROSA/Stud for et par år siden ???
Avatar billede martin_schou Nybegynder
07. april 2002 - 20:37 #16
bearhugx:
"So you tell me.... Men hvorfor denne grænse på 256kb på webserveren - - Er det en PDA, der skal hoste eller ???"

Nej, det er en embedded webserver, der også kører på LON. Hardwaredesignerne har åbenbart ment, at 256 kbytes måtte være rigeligt ;-)

"er du den Martin Schou, som var HB-rep for PROSA/Stud for et par år siden ???"

Og som gik totalt kold pga. stress og aldrig fik meldt fra overfor PROSA/Stud og HB - ja, det er mig.

Hvad da?
Avatar billede bearhugx Nybegynder
07. april 2002 - 23:11 #17
Jeg er Søren M Skrøder - Ham, som efterfulgte dig i den position :-)

/Søren
Avatar billede bearhugx Nybegynder
07. april 2002 - 23:12 #18
PS : Nice initiativ omkring Stop CopyDan :-) ... Jeg er også med på underskriftssiden... Men hvad skete der nogensinde med det... Har ikke hørt fra det i lang tid...

/Søren
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester