Avatar billede naesbygaard Nybegynder
15. juni 2004 - 15:14 Der er 37 kommentarer og
1 løsning

Flere .class-filer - men hvordan køres de?

Når jeg runner min app i JCreator så kører det fint nok, men når jeg vil køre den fra cmd (w2k) så kan jeg ikke starte den. Efter det er compilet står jeg med 3 .class-filer. Men hvis jeg prøver: java minfil.class så virker det ikke på nogle af dem.
Når jeg kører dem får jeg:  java.lang.NoClassDefFoundError...

Andet skridt er at få de 3 filer smidt i en (executable) jar!

Har lidt på fornemmeren at jeg er gal på den, så en lille guide over de commands jeg skal bruge ville være rart.

/NbG
Avatar billede naesbygaard Nybegynder
15. juni 2004 - 15:16 #1
hmm - jeg prøvede jo lige at undlade at skrive .class og så virkede det... :)

Så mangler vi bare jar-problemet!

/NbG
Avatar billede mikkelbm Nybegynder
15. juni 2004 - 15:23 #2
Først laver du et manifest (i notesblok)

manifest.mf :

Main-Class: minfil // HUSK!! Der skal være linjeskift efter denne linje

Gemmer denne fil enten sammen med klassefilerne eller som de fleste gør i en mappe:
META-INF

så skriver du i cmd:
jar cvfm MinFil.jar META-INF/manifest.mf *.class
Avatar billede naesbygaard Nybegynder
15. juni 2004 - 15:26 #3
mine 3 filer hedder: gui.class, converter.class og converter$1.class

gui er starteren, er det kun den der skal ind i mf?

/NbG
Avatar billede mikkelbm Nybegynder
15. juni 2004 - 15:27 #4
Den klasse du henviser til i manifestet skal være den klasse der indeholder main-metoden.
Avatar billede naesbygaard Nybegynder
15. juni 2004 - 15:33 #5
og hvordan kører jeg den så?
Avatar billede mikkelbm Nybegynder
15. juni 2004 - 15:33 #6
Hvis Windows er sat op til det skulle du kunne dobbeltklikke på den - ellers:
javaw -jar MinFil.jar
Avatar billede mikkelbm Nybegynder
15. juni 2004 - 15:59 #7
Virker det?
Avatar billede naesbygaard Nybegynder
15. juni 2004 - 16:10 #8
ja det virker helt fint og tak for det! Nu jeg har en ekspert ved roret, så skal vil jeg i min GUI gerne lave en stop-knap, programmet kører en laaaang løkke, kan jeg breake den undervejs med en knap? Hvordan?

Smid svar og du bliver pointbelastet :)

Tak endnu en gang

/NbG
Avatar billede mikkelbm Nybegynder
15. juni 2004 - 16:12 #9
Vi bliver nok nødt til at se lidt kode, for at få indblik i hvad det er du vil.
Avatar billede mikkelbm Nybegynder
15. juni 2004 - 16:15 #10
Men normalt har man:

JButton luk = new JButton("Luk");

luk.addActionListener(new ActionListener()
{
  public void actionPerformed(ActionEvent e)
  {
      // kald til en metode som stoppe en tråd/løkke
  }
});
Avatar billede mikkelbm Nybegynder
16. juni 2004 - 13:43 #11
Kommet videre?
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 10:42 #12
Ja, j
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 10:46 #13
Ja jeg er kommet lidt videre, men den der stopknap driller lidt.
Ligeså snart jeg har startet programmet (med startknappen) så er den ligesom holdt nede så længe løkken kører, og det betyder så at alle andre knapper ikke virker til noget. Trykne bliver dog buffered, men de kommer først igennem når løkken er kørt til ende så det dur ikke rigtig. Jeg må lige prøve at lave et testprogram som er lidt mere simpelt. (med mindre du har noget liggende med start og stop-knapper) :)

/NbG
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 17:58 #14
Det er som regel en dårlig idé, at have tråde/løkker og så gui blandet sammen. Gui'en kører i sin egen tråd, og hvis du laver en løkke der trækker lidt cpu-kraft, vil gui tråden blive nedprioriteret og først blive udført bagefter!

Men som sagt er det svært at blive mere præcis mht dit problem, hvis ikke vi kan se lidt kode...
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 18:09 #15
Prøv at granske følgende 2 eksempler:
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 18:09 #16
Eksempel 1:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame
{
    private JProgressBar bar = new JProgressBar();
    private JButton start = new JButton("Start");
   
    public Test()
    {
        setSize(200, 50);
       
        this.getContentPane().add(start, BorderLayout.EAST);
        this.getContentPane().add(bar, BorderLayout.CENTER);
       
        start.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                start();   
            }
        });
    }
   
    public void start()
    {
        for (int i = 0; i<100; i++)
        {   
            bar.setValue(i);
            try
            {
                Thread.currentThread().sleep(50);
            }
            catch (Exception ex)
            {
            }
        }
    }
   
    public static void main(String[] args)
    {
        new Test().setVisible(true);   
    }
}
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 18:09 #17
Eksempel 2:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test2 extends JFrame
{
    private JProgressBar bar = new JProgressBar();
    private JButton start = new JButton("Start");
   
    public Test2()
    {
        setSize(200, 50);
       
        this.getContentPane().add(start, BorderLayout.EAST);
        this.getContentPane().add(bar, BorderLayout.CENTER);
       
        start.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                new TestThread(bar).start();   
            }
        });
    }
       
    public static void main(String[] args)
    {
        new Test2().setVisible(true);   
    }
}

class TestThread extends Thread
{
    private JProgressBar bar;
   
    public TestThread(JProgressBar bar)
    {
        this.bar = bar;   
    }
   
    public void run()
    {
        for (int i = 0; i<100; i++)       
        {
            try
            {
                bar.setValue(i);
                sleep(50);
            }
            catch (Exception ex)
            {
            }   
        }
    }
}
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 18:12 #18
Det er muligvis ikke en progressbar du arbejder med, men det giver et godt indblik i hvad der sker, når man blander sig i GUI tråden.

Eksempel 1:
Der køres en løkke inde i gui tråden.
Konsekvens:
Progressbaren bliver først opdateret efter løkken er kørt igennem.


Eksempel 2:
Tråden køres uden for gui tråden/klassen.
Fordel:
Progressbaren bliver opdateret løbende, da de to tråde kører uhindret af hinanden.



Håber du kan bruge det :)
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 18:22 #19
jeg har ikke arbejdet med java og tråde før, så det må jeg lige sætte mig ind i. Men er det den eneste løsning på dette problem. (altså ovenstående), fordi det er rigtigt fint eksempel som svarer godt til mit problem.
så endnu en gang tak

/NbG
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 18:38 #20
Prøv at kom med din kode, så kan vi se om der er alternativer...
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 18:43 #21
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.String;

public class CelsiusConverter implements ActionListener {
    JFrame converterFrame;
    JComboBox menu;
    JPanel converterPanel, textPanel, fieldPanel, southPanel;
    JTextField server, folder, errors;
    JLabel serverLabel, folderLabel, errorsLabel, infoLabel, prefixLabel;
    JButton getButton, stopButton;
    int count;
    HttpGet get = new HttpGet();

    public CelsiusConverter() {
        //Create and set up the window.
        converterFrame = new JFrame("Picture Downloader!");
       
        //Create and set up the panel.
        converterPanel = new JPanel();
        converterPanel.setLayout(new BorderLayout());
       
        textPanel = new JPanel();
        textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
       
        fieldPanel = new JPanel();
        fieldPanel.setLayout(new BoxLayout(fieldPanel, BoxLayout.Y_AXIS));
       
        southPanel = new JPanel();
        southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
       
        menu = new JComboBox();
        String t_1 = new String("001");
        String t_2 = new String("01");
        String t_3 = new String("1");
        menu.addItem(t_1);
        menu.addItem(t_2);
        menu.addItem(t_3);
       
       
        converterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //converterPanel.setPreferredSize(new Dimension(800, 300));
        converterPanel.setBackground(Color.WHITE);

        //Add the widgets.
        addWidgets();

        //Set the default button.
        converterFrame.getRootPane().setDefaultButton(getButton);

        //Add the panel to the window.
        converterFrame.getContentPane().add(converterPanel, BorderLayout.CENTER);

        //Display the window.
        converterFrame.pack();
        converterFrame.setVisible(true);
    }

    private void addWidgets() {
        //Create widgets.
        server = new JTextField("http://", 60);
        folder = new JTextField("folder", 30);
        errors = new JTextField("5", 10);
       
        getButton = new JButton("Get images...");
        stopButton = new JButton("Stop ...");
        serverLabel = new JLabel("Server _##_ = number ", SwingConstants.LEFT);
        folderLabel = new JLabel("Folder to put images...", SwingConstants.LEFT);
        errorsLabel = new JLabel("Antal fejl i træk", SwingConstants.LEFT);
        infoLabel = new JLabel("Info", SwingConstants.LEFT);
        prefixLabel = new JLabel("Prefix", SwingConstants.LEFT);

        //Listen to events from the Convert button.
        getButton.addActionListener(this);
       
        stopButton.addActionListener(new ActionListener(){
              public void actionPerformed(ActionEvent e){
                  // kald til en metode som stoppe en tråd/løkke
                  System.out.println("STOPP");
                  get.keepOn = false;
              }
        });

        //Add the widgets to the container.
        textPanel.add(serverLabel);
        textPanel.add(Box.createRigidArea(new Dimension (0,5)));
        textPanel.add(folderLabel);
        textPanel.add(Box.createRigidArea(new Dimension (0,5)));
        textPanel.add(errorsLabel);
        textPanel.add(Box.createRigidArea(new Dimension (0,5)));
        textPanel.add(prefixLabel);
        textPanel.add(Box.createRigidArea(new Dimension (0,5)));

        fieldPanel.add(server);
        fieldPanel.add(folder);
        fieldPanel.add(errors);
        fieldPanel.add(menu);
       
        southPanel.add(getButton);
        southPanel.add(stopButton);
        southPanel.add(Box.createRigidArea(new Dimension (0,10)));
        southPanel.add(infoLabel);
       
        converterPanel.add(southPanel, BorderLayout.SOUTH);
        converterPanel.add(fieldPanel, BorderLayout.CENTER);
        converterPanel.add(textPanel, BorderLayout.WEST);

        System.out.print("...\n\n\n");
    }

    public void actionPerformed(ActionEvent event) {
        String prefix;
        int err;
        count++;
       
        prefix = (String) menu.getSelectedItem();
        get.keepOn = true;
        get.getFiles(server.getText(), folder.getText(), Integer.parseInt(errors.getText()), prefix);
        infoLabel.setText("doing... " + server.getText());
    }
   
    private static void createAndShowGUI() {
        //Make sure we have nice window decorations.
        JFrame.setDefaultLookAndFeelDecorated(true);

        CelsiusConverter converter = new CelsiusConverter();
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 18:44 #22
getFiles() - kører en løkke hvor den henter filerne fra serveren.
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 18:54 #23
prøv følgende i din actionPerformed:

public void actionPerformed(ActionEvent event)
    {
        String prefix;
        int err;
        count++;
       
        prefix = (String) menu.getSelectedItem();
        get.keepOn = true;
        Thread t = new Thread()
        {
            public void run()
            {
                get.getFiles(server.getText(), folder.getText(), Integer.parseInt(errors.getText()), prefix);
            }
        };
        t.start();
        infoLabel.setText("doing... " + server.getText());
    }


Med ovenstående laver du et såkaldt asynkront kald til din metode getFiles. På den måde kan gui tråden fortsætte uhindret.

Jeg tror det vil virke :)
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 19:10 #24
Ja det kan du lige tro det gør! :)

Hvis jeg nu har noget output fra min getFiles-funktion (som jo kører i en anden fil/class) - kan jeg så på nogen måde få det smidt over i guien on the fly. Sådan at den viser hvor langt den er nået i løkken? Eller vil det så være smartere at samle det hele i en fil? Eller hva?

/NbG
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 19:20 #25
Det kræver lidt modificering

Men!
Du kan lave en metode i din gui-klasse:

public void visDette(String something)
{
    // kode til at vise info...
}

Og når du opretter din instans af HttpGet, smider du en reference med til gui'en.

Lidt ala:

public class CelsiusConverter
{
  private HttpGet get;

  public CelsiusConverter()
  {
      get = new HttpGet(this);
  }

  public void visDette(String something)
  {
      // kode til at vise info...
  }
} // + alt det andet du har i din klasse

Nu ved jeg så ikke hvordan din HttpGet klasse ser ud, men måske noget ala:

public class HttpGet
{
  private CelsiusConverter cel;

  public HttpGet(CelsiusConverter cel)
  {
      this.cel = cel;
  }

  public getFiles(.......)
  { 
      // al din kode til at hente filer...
      cel.visDette(... info ...);
  }
}

Det var i hvert fald en måde at gøre det på, hvis du hele tiden vil ha' gui'en opdateret...
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 20:13 #26
--------------------Configuration: j2sdk1.4.1 <Default>--------------------
C:\algodel\web\image\CelsiusConverter.java:19: cannot resolve symbol
symbol  : constructor HttpGet (CelsiusConverter)
location: class HttpGet
        get = new HttpGet(this);
              ^

Jeg har skrevet det som du skrevet det, men får altså denne fejl. Kan ikke helt se hvad der er galt. Kan du?
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:17 #27
Har du husket at ændre constructoren i HttpGet ?

den skal se ud som jeg skrev tidligere:

public class HttpGet
{
  private CelsiusConverter cel;

  public HttpGet(CelsiusConverter cel)
  {
      this.cel = cel;
  }
.......
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 20:21 #28
HttpGet.java

...

    private static CelsiusConverter cel;

    public static void HttpGet(CelsiusConverter cel){
        this.cel = celind;
    }
-----------------------

CelsiusConverter.java
....
    private HttpGet get;

    public CelsiusConverter() {
       
        get = new HttpGet(this);
        ....
    }
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:24 #29
HttpGet.java

...

    private static CelsiusConverter cel;

    public static void HttpGet(CelsiusConverter cel){
        this.cel = celind;
    }
-----------------------
ovenstående er en metode, du skal erlære det i constructoren:

...

    private CelsiusConverter cel;

    public HttpGet(CelsiusConverter cel){
        this.cel = cel;
    }
-----------------------

og så skal variablen kun erklæres static hvis dine metoder også er det!
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 20:30 #30
men er det ikke også det jeg gør? HttpGet(CelsiusConverter cel) er da constructoren.
ja det hele er static...

HttpGet.java

import java.util.*;
import java.net.*;
import java.io.*;
import java.lang.*;


public class HttpGet {
   
    public static int errcount;
    private static boolean useProxy = false;
    public static boolean keepOn = true;
    public static boolean newdir = false;
    private static CelsiusConverter cel;
   
    public void HttpGet(){
        //
    }
   
    public static void HttpGet(CelsiusConverter cel){
        this.cel = celind;
    }
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:32 #31
Nej! :)

Din constructor skal se ud som følgende:

public HttpGet(CelsiusConverter cel)
{
  this.cel = cel;
}

--> altså uden "static void"
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 20:36 #32
silly me :) Åndsvag fejl af mig. Undskyld!
og selvfølgeligt virker det :)
endnu en gang mange tak - vil du have flere point for arbejdet?

/NbG
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:37 #33
Tjaaa - hvis du synes :)
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 20:40 #34
nu er min forbindelse lidt ustabil for tiden så jeg har lidt svært ved at teste, men vil sådan en tråd have nogen indflydelse på den HttpURLConnection jeg laver i HttpGet. Det er ikke sådan noget med at den kan finde på at lukke inden den enkelte fil er hentet vel? Eller i så fald, kan den vel finde ud af at genoptage tråden igen.
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:42 #35
Den vil være lige så stabil som før. Og vi bruger også kun tråden til at simulere et såkaldt asynkront kald (Det vil sige at man ikke venter på metoden bliver udført).
Avatar billede naesbygaard Nybegynder
17. juni 2004 - 20:44 #36
hvordan kan jeg give dig flere point?
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:45 #37
Det kan du gøre ved at oprette et spørgsmål i denne kategori med overskriften:

Point til mikkelbm
Avatar billede mikkelbm Nybegynder
17. juni 2004 - 20:47 #38
Og husk at lægge et link til denne tråd, så folk kan se hvorfor du giver point!
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