Avatar billede nielle Nybegynder
22. maj 2006 - 17:54 Der er 24 kommentarer og
2 løsninger

gif-filer indenfor i en jar-fil

Jeg er ved at lægge sidste hånd på et projekt, som snart skal afleveres. Alt er faktisk på plads, men der mangler lige dét.

I mit projekt benytter jeg et antal gif-filer, og disse ligger pt. på harddisken. Dette virker, men... Jeg vil gerne have dem indenfor i jar-filen, som en ressource, sådan at det færdige program kan gives videre som en selvstændig jar-fil.

Hvordan gøres dette egentlig? Der skal vel kodes noget, og så skal projektet vel også sættes op til det. Jeg bruger JBuilder.
Avatar billede _carsten Nybegynder
22. maj 2006 - 17:57 #1
Eksempel

minLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/billede.gif")));
Avatar billede _carsten Nybegynder
22. maj 2006 - 17:59 #2
Hvor billeder selvfølgelig skal ligge i package images i jar filen

Og jar fil addes til project i JBuilder - som jeg ikke kender noget til
Avatar billede nielle Nybegynder
22. maj 2006 - 18:05 #3
Hvor får du getClass()-metode fra? Hvilken klasse implementere denn?
Avatar billede _carsten Nybegynder
22. maj 2006 - 18:53 #4
Sorry - var lige i byen

Den klasse som benytter dit image
Avatar billede nielle Nybegynder
22. maj 2006 - 19:00 #5
Min gif-fil bruges af forskellige klasser i applikationen.  Jeg har derfor indkapslet gif-håndteringen i en egen klasse som så bruges rundt omkring.

Min klasse, GifRessource arver ikke fra andet end Object og den har derfor ikke defineret nogen funktion som hedder getClass(). Hvis jeg selv skulle skrive sådan en metode, hvordan skulle det så se ud kodemæssigt?
Avatar billede _carsten Nybegynder
22. maj 2006 - 20:21 #6
Skulle lige have noget at spise.

Fint nok - så er det bare ...


public class GifRessource{
    public GifRessource(){
        path = getClass().getResource(".").toString();
    }

    public Icon getIcon(String billedNavnOgType){
        // billedNavnOgType = "xxx.gif" eller med package "images/xxx.gif"
        return path + billedNavnOgType;
    }

    private String path;
}
Avatar billede _carsten Nybegynder
22. maj 2006 - 20:22 #7
Hov - skal nok være

eller med package "/images/xxx.gif"

skråstreg foran packagenavn (kan ikke lige huske det)
Avatar billede arne_v Ekspert
22. maj 2006 - 20:24 #8
getClass er i Object saa alle har den
Avatar billede nielle Nybegynder
22. maj 2006 - 20:41 #9
Ok, jeg tror da i det mindste at jeg er på rigtig vej :^)

Hvor er det smarteste at lægge gif-filerne i projektets filstruktur? Foreløbig har jeg lagt dem i et gif-bibliotek, som ligger side-om-side med src-, classes- og doc-bibliotekerne. Men er det bedre at lægge gif-biblioteket ind som et underbibliotek af src, eller måske af classes-biblioteket?
Avatar billede _carsten Nybegynder
22. maj 2006 - 20:58 #10
Man skal så vidt muligt altid starte i en package, så


src/mainPackage
src/mainPackage/image
src/mainPackage/whatever
src/mainPackage/otherFiles
src/mainPackage/yetAndotherDir/dir
src/mainPackage/....


Ville være min foretrukne struktur
Avatar billede _carsten Nybegynder
22. maj 2006 - 21:00 #11
Sagt på en anden måde - INGEN filer i src, start med en package, og byg op herfra
Avatar billede nielle Nybegynder
22. maj 2006 - 21:39 #12
Jeg har lagt billederne ind i et images-bibliotek under src (jeg har ingen package i min app).

Når jeg prøver med:

resourcePath = getClass().getResource("./images/").toString();

- kan jeg imidlertid se at den mapper dette til:

C:/projectes path/classes/images/

Er der en god forklaring på dette, eller skal mine images-bibliotek i virkeligheden ligge under classes i stedet for src?
Avatar billede nielle Nybegynder
22. maj 2006 - 21:42 #13
Ok, jeg kan se at dette blivver dannet automatisk når jeg builder.

Af en eller anden grund kan jeg dog ikke se billederne selv om de altså ligger der...
Avatar billede _carsten Nybegynder
22. maj 2006 - 21:45 #14
Når opbygger det i en IDE, ja så skal du også lægge i classes.

Skyldes at IDE'en compiler dine java filer som ligger i src og smider dem i classes

Nu kender jeg ikke lige JBuilder, men den er nok ikke ret meget anderledes
Avatar billede arne_v Ekspert
22. maj 2006 - 22:41 #15
du boer bruge packages (du bruger vel ogsaa namespaces i C# ?)

----------

getRessource(0 henter fra classpath d.v.s. at du skal:
1) bede JBuilder pakke filerne med ned i jar filen for at de kan bruges
  i test/production
2) have det dir i classpath for JBuilder saa du kan teste under udvikling


----------

Jeg ville foele det fristende at have et image dir helt oppe paa niveau med
src og build, men det er formentligt fordi jeg taenker mere ant end IDE
Avatar billede nielle Nybegynder
22. maj 2006 - 22:43 #16
Hmmmm, getResource() driller. Med:

    String resourcePath = getClass().getResource("./images/").toString();
    System.out.println(resourcePath);

- får jeg dette ud på konsolen:

    file:/C:/Source.Java/TicTacToe/classes/images/

Når jeg laver:

    String gifFile = resourcePath + "Kryds.gif"

- får jeg dermed:

    file:/C:/Source.Java/TicTacToe/classes/images/Kryds.gif

Det vil:

    Image image = Toolkit.getDefaultToolkit().getImage(gifFile)

- bare ikke acceptere. Der kommer ingen fejl, eller exceptions, men billedet er blank.

Det der "file:/" i starten af strengen ser jo uskyldigt ud - det angiver bare at der er tale om en fil. Men nej, det er det ikke, for hvis jeg fjerner det med:

    String resourcePath = getClass().getResource("./images/").toString();
    resourcePath = resourcePath.substring(6);
    System.out.println(resourcePath);

- så vises billederne pludseligt som forventet.

Så, mit spørgsmål er nu: Hvorfor kommer det "file:/" og hvad er den rigtige fremgangsmåde til at løse problemet med at billederne ikke vises? Jeg synes ikke umiddelbart at løsningen med substring(6) virker som om at det er den rigtige.
Avatar billede arne_v Ekspert
22. maj 2006 - 22:49 #17
getRessource returnerer en URL

du skal bruge den URL som argument til ImageIcon constructor

ikke .toString() af den

og synes du at file: er grim saa vent til du ser den URL naar det er inde i en
jar fil !
Avatar billede nielle Nybegynder
22. maj 2006 - 23:05 #18
Jeg sagde ikke at "file:/" var grim, men at løsningen med at substring'e den væk var grim.

Nu begynder det at ligne noget, for dette virker:

        URL url = getClass().getResource("./images/Kryds.gif");
        Image image = Toolkit.getDefaultToolkit().getImage(url);

- og så er der ikke noget kode som - for mig i hvert fald - ser nær så klamphukket ud som at bruge en substring().

Et sidste spørgsmål, inden at jeg lukker denne her: Da jeg oprindeligt skrev klassen GifResource, startede jeg med at loade alle gifferne til memory (gemt i et HashMap<xxx, Image>). Pointen med det var at forhindre at der blev læst fra disk hver gang at jeg brugte et billede.

Når man brugere en resource i stedet, hvad sker der så? Vil den læse fra jar-filen, som ligger på disken, eller vil den hente billederne i jar-filen, som bliver loadet til memory når jeg starter programmet?
Avatar billede arne_v Ekspert
23. maj 2006 - 03:20 #19
Hvis jar filen er en file URL vil styresystemet cache filen.

Hvis jar filen er en HTTP URL vil Java cache en lokal kopi af jar file
og styresystemet vil cache den.

Jeg tror ikke at Java vil cache ressourcen.

Hvis du vil kan du gemme dit Image i en cache.
Avatar billede nielle Nybegynder
23. maj 2006 - 09:12 #20
Hmmm, det virker ikke helt endnu. :^|

Hvordan kan det være at:

URL url = getClass().getResource("./images/Kryds.gif");

- returnere et file-url som fungere korrekt når jeg afvikler programmet inde fra JBuilder, men at det returnere null når jeg køre jar-filen direkte?
Avatar billede nielle Nybegynder
23. maj 2006 - 11:45 #21
Det går meget bedre, hvis jeg fjerner punktummet:

URL url = getClass().getResource("/images/Kryds.gif");

Smid endeligt et svar begge to, men de fleste point går til arne_v.
Avatar billede arne_v Ekspert
23. maj 2006 - 13:22 #22
svar

og jeg synes nu at carsten har trukket det tunge læs
Avatar billede _carsten Nybegynder
23. maj 2006 - 13:47 #23
Svar

Så vidt jeg husker, var det også det jeg skrev i min første kommentar, men jeg fik vist ikke penslet det godt nok ud.

Det fungerer nemlig uanset om vi snakker jar eller filsystem, men ikke nødvendigvis i en IDE.

Du skal fordele point som DU finder det rigtigt.
Avatar billede _carsten Nybegynder
23. maj 2006 - 13:47 #24
Prøver igen
Avatar billede nielle Nybegynder
23. maj 2006 - 15:12 #25
Jeg undskylder meget, når jeg gennemlæser tråden igen kan jeg se at jeg udelukkende har mig selv at takke for at der sneg sig fejl ind undervejs. :^| *blush*

Jeg fordobler og fordeler :^)
Avatar billede arne_v Ekspert
23. maj 2006 - 15:26 #26
og husk nu de packages
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