Java ME Leere Canvas Seite

ben174

Mitglied
Hallo,

ich bin derzeit dabei in Java Me einzusteigen und habe mir bereits die absoluten Basics angeeignet (denke ich).

Ich versuche derzeit eine kleine App zu schreiben die mit einer Canvas Seite startet auf der ein Logo zu sehen ist (dieses wird vertical zentriert und auf die Breite des Screen scaliert), dann kommt nach 3 Sekunden ein einfaches Menü als Liste mit zwei Auswahlpunkten.

Großteils funktioniert das alles auch, nur kommt es meistens dazu dass die Canvas Klasse zwar ausgeführt wird, aber nichts anzeigt. In ca. 15% zeigt der Emulator alles richtig an, die restlichen Versuche und alle Versuche auf einem richtigen Handy (Nokia 2330 classic) ergeben nur eine weiße Seite (fullscreen) und nach 3 Sekunden kommt das Menü. Wenn es angezeigt wird funktioniert auch das scalieren und zentrieren.

Es kommt auch keinerlei Fehlermeldung und ich bin somit leider vollkommen überfragt wie ich dieses Problem lösen könnte. Auch in diversen englischen und deutschen Foren wurde nirgendwo so ein Problem besprochen.

Das ist der Quelltext für die Canvas Klasse:
Java:
public void run() {
        g = getGraphics();

        try{
            img =  Image.createImage("cookie/logo.png");
            // image auf bildschirm width scalieren

            int newWidth = getWidth();

            int percent = (img.getWidth()/newWidth);
            int newHeight = (img.getHeight()*percent);


            img = rescaleImage(img, newWidth, newHeight);
            
        }catch(Exception e){
            g.drawString("" + e, 0, 0, Graphics.TOP | Graphics.LEFT);
        }

       try{
            g.setColor(0xffffff);
            g.fillRect(0, 0, getWidth(), getHeight());
            int startPoint = ((getHeight()/2)-45);
            g.drawImage(img, 0, startPoint, Graphics.TOP | Graphics.LEFT);
        } catch(Exception e){
            g.drawString("" + e, 0, 0, Graphics.TOP | Graphics.LEFT);
        }
        
        try {
            Thread.sleep(3000);
	} catch (InterruptedException e) {

	}
       g = null;
       fParent.MenuList();
       fParent = null;
    }

Ich hoffe das hier jemand eventuell schon einmal so ein solches Problem hatte oder einen Fehler im Code sieht und mir ein wenig helfen kann. Im Vorraus schon einmal vielen Dank.

MfG
Ben
 

The_S

Top Contributor
Evtl. solltest du auch mal mit dem Java SE Basics anfangen. getGraphics() verwendet man weder beim Zeichnen in Java SE noch beim Zeichnen in Java ME. Das sollte sich bei ME alles in der paint-Methode bzw. in Methoden, die von der paint-Methode aus aufgerufen werden, abspielen.
 

ben174

Mitglied
Danke für den Tipp, ich habe es jetzt mit Hilfe eines Tutorials zu der Funktion umgebaut und es geht im Emulator hervoragend, aber nicht auf dem Handy:

Java:
 public void paint(Graphics g) {
    try{
            img =  Image.createImage("cookie/logo.png");

            int newWidth = getWidth();

            int percent = (img.getWidth()/newWidth);
            int newHeight = (img.getHeight()*percent);


            img = rescaleImage(img, newWidth, newHeight);

        }catch(Exception e){
            g.drawString("" + e, 0, 0, Graphics.TOP | Graphics.LEFT);
        }

       try{
            g.setColor(0xffffff);
            g.fillRect(0, 0, getWidth(), getHeight());
            int startPoint = ((getHeight()/2)-img.getHeight());
            g.drawImage(img, 0, startPoint, Graphics.TOP | Graphics.LEFT);
        } catch(Exception e){
            g.drawString("" + e, 0, 0, Graphics.TOP | Graphics.LEFT);
        }
  }

    public void run() {

        repaint();
}

Kannst du mir vielleicht nocheinmal dabei helfen?
 

ben174

Mitglied
hab es jetzt so abgeändert:

Java:
catch(Exception e){
            Alert a = new Alert("" + e );
        }

aber es wird kein Fehler ausgegeben sondern das MIDlet läuft wie es soll im Emulator und auf dem Handy ist es einfach weiß.
 

The_S

Top Contributor
Passt die veränderte Größe des Images? Ist die Position korrekt? Also alle Werte korrekt berechnet? Lass dir die Werte am Besten auch mal ausgeben.
 

ben174

Mitglied
Ja, das passt alles, ich denke es liegt an Nokia. Dort bleibt der Screen immer weiß, auf dem Sony Ericsson SE W810i funktioniert es wie es soll.

Vermutlich gibt es bei Nokia spezielle Klassen dafür ohne die es nicht geht!?
 

The_S

Top Contributor
Nein.

Poste doch mal deinen neuen Quellcode inkl. Fehlerausgabe über Alert und Ausgabe der Position und Größe des Bildes. Und dann natürlich noch die Informationen die Ausgegeben werden.
Funktioniert es, wenn du das Bild nicht skalierst?
 

ben174

Mitglied
Also es wird leider nie was ausgegeben, wenn das Bild nicht scaliert wird funktioniert es auch nur auf dem Sony Ericsson.

Das ist die komplette Klasse die vom MIDlet aufgerufen wird für die Canvas Page:
Java:
public class clsCanvas extends Canvas implements Runnable {
    
    private Graphics g;
    private fortunecookie fParent;
    private Image img;

    public clsCanvas(fortunecookie m) {

        fParent = m;
        setFullScreenMode(true);
    }

    public void start(){
        Thread runner = new Thread(this);
        runner.start();
    }

    public void run() {

        repaint();
         try {
            Thread.sleep(3000);
	} catch (InterruptedException e) {

	}
        fParent.MenuList();
        fParent = null;
    }
    
    public void paint(Graphics g) {
    try{
            img =  Image.createImage("cookie/logo.png");

            int newWidth = getWidth();

            int percent = (img.getWidth()/newWidth);
            int newHeight = (img.getHeight()*percent);

/*
            Alert a = new Alert("alte Breite: " + img.getWidth() );
            a = new Alert("alte Höhe: " + img.getHeight() );
            a = new Alert("neue Breite: " + newWidth );
            a = new Alert("neue Höhe: " + newHeight );

 *
 */
            img = rescaleImage(img, newWidth, newHeight);

        }catch(Exception e){
            Alert a = new Alert("" + e );
        }

       try{
            g.setColor(0xffffff);
            g.fillRect(0, 0, getWidth(), getHeight());
            int startPoint = ((getHeight()/2)-img.getHeight());
            g.drawImage(img, 0, startPoint, Graphics.TOP | Graphics.LEFT);
        } catch(Exception e){
           Alert a = new Alert("" + e );
        }
  }

    private Image rescaleImage(Image image, int width, int height)
	{
		int sourceWidth = image.getWidth();
		int sourceHeight = image.getHeight();

		Image newImage = Image.createImage(width, height);
		Graphics n = newImage.getGraphics();

		for(int y=0; y<height; y++)
		{
			for(int x=0; x<width; x++)
			{
				n.setClip(x, y, 1, 1);
				int dx = x * sourceWidth / width;
				int dy = y * sourceHeight / height;
				n.drawImage(image, x-dx, y-dy, Graphics.LEFT | Graphics.TOP);
			}
		}

		return Image.createImage(newImage);
	}

}
 

ben174

Mitglied
Ok, ich habe das mit den Alerts nun gemacht, er gibt alles aus, auch nach dem rescaling.

Kann es nicht doch an einer Nokia spezifischen Methode liegen? Im Emulator und auf dem Sony Ericsson geht es ja.
 

The_S

Top Contributor
Dann poste jetzt noch einmal deinen kompletten Code (der die Alerts für die Ausgaben enthält) UND die Ausgaben der Alerts.
 

ben174

Mitglied
Java:
public class clsCanvas extends Canvas implements Runnable {
    
    private Graphics g;
    private fortunecookie fParent;
    private Image img;

    public clsCanvas(fortunecookie m) {

        fParent = m;
        setFullScreenMode(true);
    }

    public void start(){
        Thread runner = new Thread(this);
        runner.start();
    }

    public void run() {
        repaint();
         try {
            Thread.sleep(3000);
	} catch (InterruptedException e) {

	}
        fParent.MenuList();
        fParent = null;
    }

    public void paint(Graphics g) {
             
    try{
            img =  Image.createImage("cookie/logo.png");

                fParent.showAlert(new Alert("alte Breite: " + img.getWidth() ));
                fParent.showAlert(new Alert("alte Höhe: " + img.getHeight() ));

            int newWidth = getWidth();

                fParent.showAlert(new Alert("neue Breite: " + newWidth ));

            int percent = (newWidth/img.getWidth());
            percent = 1;

            int newHeight = (int) (img.getHeight()*percent);
            fParent.showAlert(new Alert("neue Höhe: " + newHeight ));

           img = rescaleImage(img, newWidth, newHeight);


        }catch(Exception e){
           fParent.showAlert(new Alert("" + e ));
        }
                  
       try{
            g.setColor(0xffffff);
            g.fillRect(0, 0, getWidth(), getHeight());
            int startPoint = ((getHeight()/2)-img.getHeight());
            g.drawImage(img, 0, startPoint, Graphics.TOP | Graphics.LEFT);
        } catch(Exception e){
          fParent.showAlert(new Alert("" + e ));
        }

  }

    private Image rescaleImage(Image image, int width, int height)
	{
		int sourceWidth = image.getWidth();
		int sourceHeight = image.getHeight();

		Image newImage = Image.createImage(width, height);
		Graphics n = newImage.getGraphics();

		for(int y=0; y<height; y++)
		{
			for(int x=0; x<width; x++)
			{
				n.setClip(x, y, 1, 1);
				int dx = x * sourceWidth / width;
				int dy = y * sourceHeight / height;
				n.drawImage(image, x-dx, y-dy, Graphics.LEFT | Graphics.TOP);
			}
		}

		return Image.createImage(newImage);
	}

}

Ich habs jetzt so gelöst das er eine Methode im MIDlet aufruft für die Alerts.

Die Ausgaben sind:
alte Breite: 175
alte Höhe: 45

neue Breite: 170
neue Höhe: 45

Eigentlich müsste die neue Höhe ca. 44 sein, da er aber bei der Prozentrechnung seltsamerweise weder float noch double nimmt und int immer 0 ergeben würde habe ich die pauschal auf 1 gesetzt.
 

The_S

Top Contributor
ich sehe in deinem Code nicht, wo du dir die Höhe und die Breite (und die Position wo es gezeichnet werden soll schon einmal gar nicht) ausgibst.

float und double gibt es erst ab CLDC 1.1
 

ben174

Mitglied
Java:
fParent.showAlert(new Alert("neue Höhe: " + newHeight ));


Das gibt es aus.

Die Position hatte ich vergessen, da gibt er für die y variable 65 aus.
 

The_S

Top Contributor
ok, tatsche. Habe ich übersehen. Dann schau doch mal, ob deine rescale-Methode überhaupt abgeschlossen wird bzw. zu einem Ende kommt.
 

ben174

Mitglied
Ich habe den Fehler, die Nokia Handys finden das Bild nicht, da kommt immer null pointer exception wenn das Bild im Spiel ist. Aber das müsste stimmen mit den Pfaden.

Ich entwickle mit NetBeans und das ganze läuft im Package "cookie" und so habe ich das Bild in der createImage Funktion:

Java:
img =  Image.createImage("/cookie/logo.png");

und das Bild ist im jar File auch definitv drin. Muss ich da was beachten für Nokia Handys was die Einbindung angeht?
 

The_S

Top Contributor
Laut deinen Postings lädst du das Bild ohne führenden /. Den brauchst du aber eigentlich. Hatte noch nie Probleme auf einem Nokia das Bild auf diese Art zu laden. Den Fehler hättest du btw schon viel früher finden müssen. Du solltest doch alle Fehler catchen und ausgeben - dabei wäre das sicher auch aufgefallen.
 

ben174

Mitglied
Ja, eigentlich schon, ich hatte das Alert vorher nur auf dem Emulator geteset, und der hat das Bild auch ohne "/" gefunden und deshalb keine Fehlermeldung ausgegeben, sorry.

Jetzt geht es jedenfalls, vielen Dank für deine Hilfe.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W App crash bei leere Zeile Android & Cross-Platform Mobile Apps 1
Arif Android Canvas wird nicht gezeichnet? Android & Cross-Platform Mobile Apps 0
Dechasa Android Android - Canvas NullpointException Android & Cross-Platform Mobile Apps 2
Z Canvas onDraw() Variablen muss in der Methode initialisiert werden Android & Cross-Platform Mobile Apps 1
F Mit Canvas zeichen und durch einen Timer aktualiesieren Android & Cross-Platform Mobile Apps 1
J Canvas mit dem Accelorometersensor bewegen Android & Cross-Platform Mobile Apps 0
E Android Zeichnen auf Canvas - Teilbereich als Bild speichern Android & Cross-Platform Mobile Apps 3
B onDraw Canvas jede Millisekunde aufrufen? Android & Cross-Platform Mobile Apps 12
G canvas in view anzeigen Android & Cross-Platform Mobile Apps 10
S Android Canvas - drawText - Update Text in ActionListener Android & Cross-Platform Mobile Apps 8
B Java ME Canvas Android & Cross-Platform Mobile Apps 2
J Java ME Canvas Klasse Gameloop und Funktion Android & Cross-Platform Mobile Apps 2
P Java ME Texteingabe Canvas Android & Cross-Platform Mobile Apps 2
D wie geht Klassenvererbung von Canvas Klassen Android & Cross-Platform Mobile Apps 2
U Probleme mit der drawString Methode bei Canvas Android & Cross-Platform Mobile Apps 8
H Canvas kann nichts auf Graphics drawen Android & Cross-Platform Mobile Apps 3
M Textfeld in Canvas, implementation der keys aendern Android & Cross-Platform Mobile Apps 8
M Text in Canvas scrollen lassen Android & Cross-Platform Mobile Apps 13
M Wie in einer anderen "nicht canvas" klasse zeichne Android & Cross-Platform Mobile Apps 5
U ein texteingabefeld auf einem Canvas . Android & Cross-Platform Mobile Apps 2
A Problem: Canvas-Grösse Motorola RAZR v3r Android & Cross-Platform Mobile Apps 8
F Canvas Stringlänge Android & Cross-Platform Mobile Apps 2
Dimax Web-Seite in native app convertieren mit Android Studio Android & Cross-Platform Mobile Apps 8
H Android Mit Animation den ContentView zur Seite wischen Android & Cross-Platform Mobile Apps 3
S Android Probleme beim Verbinden mit einer HTTPS Seite Android & Cross-Platform Mobile Apps 4
T Android ScrollView Ganze Seite Scrollen Android & Cross-Platform Mobile Apps 3
A Android Problem mit Zurücktaste und ausgabe der Aktuellen Seite Android & Cross-Platform Mobile Apps 6
I Android WebKit: Seite auslesen (Nur Quellcode) Android & Cross-Platform Mobile Apps 12
L HTML Seite anzeigen in Handy-Applikation Android & Cross-Platform Mobile Apps 5

Ähnliche Java Themen

Neue Themen


Oben