2D-Grafik PNG Datei in JLabel Array Problem

LeckerPepper

Mitglied
Hallo liebe Java-Freunde,

Ich möchte sozusagen ein kleines Super Mario programmieren, mein Test hat sogar einwandfrei funktioniert:

04608-b830b722-d2b1-4ef1-9003-ec4d904e1f8f.png


Doch nun wo ich die farbigen Quadrate mit Texturen ersetzen wollte, ergab sich das Problem, dass pro Frame nur ca. zwei Quadrate mit Texturen angezeigt werden, aber immer an unterschiedlichen Stellen. Also eigentlich ist vom Code her nahezu alles richtig, nur die Quadrate mit den Texturen bleiben einfach nicht sichtbar sondern verschwinden, wenn die nächsten Quadrate erscheinen. Ich hoffe ihr versteht was mein Problem ist 😳

04608-b3abea40-01a6-4676-9ca4-ab4f9ea133f0.png


Hier noch der Code von der Frame-Klasse, in der sich alles wichtige abspielt:
Java:
package SMv1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class FrameSMv1 extends JFrame {

	int frameWidth = 1200, frameHeight = 700, xAnzahl=0;
	public String name;
	int u =25*15;
	JLabel label1[] = new JLabel[u];
	char[][] field = new char[25][15];
	ImageIcon dirtI = new ImageIcon("dirt.png");
	ImageIcon grasI = new ImageIcon("gras.png");
	ImageIcon skyI = new ImageIcon("sky.png");

	public FrameSMv1(String name) {

		super("Test");
		this.name = name;

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(frameWidth, frameHeight);

		getContentPane().setBackground(Color.WHITE);
		setVisible(true);
		setResizable(false);
		setLocationRelativeTo(null);
	}


	@SuppressWarnings("resource")
	public void readFile() {
		File file1 = new File(name);
		try {
			Scanner scann1 = new Scanner(file1);
			int y = 0;
			char[] tempChar = null;
			for (int i = 0; i < 14; i++) {
				 if(scann1.hasNext()){
				String tempString = scann1.next();
				tempChar = tempString.toCharArray();
				 }
				for (int x = 0; x < 24; x++) {
					field[x][y] = tempChar[x];
				}
				y++;

			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

	}
	public void Screen() {
		for (int z = 0; z < u; z++) {
		    label1[z]= new JLabel();
		    add(label1[z]);
		
	
			for (int x = 0; x < 24; x++) {
				for (int y = 0; y < 14; y++) {
					
					
						if (field[x][y] == 'd') {
						   
							label1[z].setIcon(dirtI);
							label1[z].setBounds(x * 50, y * 50, 50, 50);
					
						}
						if (field[x][y] == 'g') {
						  
							label1[z].setIcon(grasI);
							label1[z].setBounds(x * 50, y * 50, 50, 50);
						}
						if (field[x][y] == 's') {
							  
							label1[z].setIcon(skyI);
							label1[z].setBounds(x * 50, y * 50, 50, 50);
						}
				}
			}
			
			}
		
		
	}
}
 
Okay, ich hab jetzt einfach meinen Plan mit dem JLabel Array über den Haufen geworfen und in einer Kopie der Frame-Klasse etwas anderes versucht:

Java:
package SMv1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class CopyOfFrameSMv1 extends JFrame {

	int frameWidth = 1200, frameHeight = 700, xAnzahl = 0;
	public String name;
	int u = 25 * 15;
	JLabel dirt[] = new JLabel[u];
	JLabel gras[] = new JLabel[u];
	JLabel sky[] = new JLabel[u];
	char[][] field = new char[25][15];
	ImageIcon dirtI = new ImageIcon("dirt.png");
	ImageIcon grasI = new ImageIcon("gras.png");
	ImageIcon skyI = new ImageIcon("sky.png");

	public CopyOfFrameSMv1(String name) {

		super("Test");
		this.name = name;
		

		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(frameWidth, frameHeight);

		getContentPane().setBackground(Color.WHITE);
		setVisible(true);
		setResizable(false);
		setLocationRelativeTo(null);
	}

	@SuppressWarnings("resource")
	public void readFile() {
		File file1 = new File(name);
		try {
			Scanner scann1 = new Scanner(file1);
			int y = 0;
			char[] tempChar = null;
			for (int i = 0; i < 14; i++) {
				if (scann1.hasNext()) {
					String tempString = scann1.next();
					tempChar = tempString.toCharArray();
				}
				for (int x = 0; x < 24; x++) {
					field[x][y] = tempChar[x];
				}
				y++;

			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

	}
	public void paint(Graphics g) {
	    Graphics2D g2 = (Graphics2D) g;
	    Image dirtIm = Toolkit.getDefaultToolkit().getImage("dirt.png");
	    Image grasIm = Toolkit.getDefaultToolkit().getImage("gras.png");
	    Image skyIm = Toolkit.getDefaultToolkit().getImage("sky.png");

	    
	    for (int x = 0; x < 24; x++) {
			for (int y = 0; y < 15; y++) {			
				System.out.println(x+" "+y);
				if (field[x][y] == 'd') {

					g2.drawImage(dirtIm, x*50, y*50, this);

				}
				if (field[x][y] == 'g') {

					g2.drawImage(grasIm, x*50, y*50, this);

				}
				if (field[x][y] == 's') {

					g2.drawImage(skyIm, x*50, y*50, this);
					
				}
			}
		}
	    
	    
	}
}

Klappt soweit so gut, nur manchmal wird nur die Hälfte gezeichnet, manchmal nur zwei Reihen, manchmal 1/3 etc:
04608-1e53446a-8316-4b3d-a062-a14acd3dfe90.png

Außerdem wird komischerweise nur gezeichnet wenn ich System.out.println(x+" "+y); aufrufe ;( 😡

Irgendwie versteh ich grad nur Bahnhof :/
 
"Außerdem wird komischerweise nur gezeichnet wenn ich System.out.println(x+" "+y); aufrufe"
Wie raufst du das auf?

Ich sollte vermutlich anmerken, dass es deutlich mehr Sinn machen würde, nicht von JFrame zu erben, sondern von JPanel und dort die paintComponent Methode zu überschreiben um dein Bild zu zeichnen.
Generell sollte man von der paint Methode bei JComponent eher die Finger lassen. Wenn man da Murx macht, kann das leicht zu visuellen Artefakten führen.
 
"Außerdem wird komischerweise nur gezeichnet wenn ich System.out.println(x+" "+y); aufrufe"
Wie raufst du das auf?

Ich sollte vermutlich anmerken, dass es deutlich mehr Sinn machen würde, nicht von JFrame zu erben, sondern von JPanel und dort die paintComponent Methode zu überschreiben um dein Bild zu zeichnen.
Generell sollte man von der paint Methode bei JComponent eher die Finger lassen. Wenn man da Murx macht, kann das leicht zu visuellen Artefakten führen.


Also ich hab das mit dem JPanel nun gemacht und jetzt wird zwar bei jedem ca. 10 Versuch das komplette Level gezeichnet, nur leider bei den anderen 9 Versuchen ca. 5 mal gar nicht und sonst auch nur teilweise...
Kannst du mir bitte nochmal helfen?
04608-099a3ece-0cb9-4e14-9494-eef6f136624b.png
 
Wie njans (schon) wieder richtig anmerkte 😉, solltest du von JPanel erben und nicht von JFrame.

Das habe ich mal gemacht und das Ergebnis ist hier und ich habe auch einen Screenshot angehängt. Meine Icons sind 50*50 Pixel gross und da praktisch per Zufall gefüllt wird, siehst aus, wie ein Flickenteppich. Alle Felder werden aber gezeichnet

Java:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class FrameSMv1 extends JPanel {

	int frameWidth = 1200, frameHeight = 700, xAnzahl = 0;
	public String name;
	int u = 25 * 15;
	JLabel dirt[] = new JLabel[u];
	JLabel gras[] = new JLabel[u];
	JLabel sky[] = new JLabel[u];
	char[][] field = new char[25][15];
	ImageIcon dirtI;
	ImageIcon grasI;
	ImageIcon skyI;
	Random random;

	public static void main(String[] args) {
		JFrame frame = new JFrame("Turtle");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		FrameSMv1 frameSMv1 = new FrameSMv1();
		frameSMv1.setPreferredSize(new Dimension(1300, 900));
		frame.add(frameSMv1);
		frame.pack();
		frame.setVisible(true);
	}

	public FrameSMv1() {
		random = new Random();
		dirtI = new ImageIcon(getClass().getResource("/images/dirt.png"));
		grasI = new ImageIcon(getClass().getResource("/images/gras.png"));
		skyI = new ImageIcon(getClass().getResource("/images/sky.png"));
		readFile();
	}

	public void readFile() {
		String possible = "dgs";
		for (int y = 0; y < 14; y++) {
			for (int x = 0; x < 24; x++) {
				int nextInt = random.nextInt(3);
				field[x][y] = possible.charAt(nextInt);
			}
		}

	}

	public void paint(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;

		for (int x = 0; x < 24; x++) {
			for (int y = 0; y < 15; y++) {
				System.out.println(x + " " + y);
				if (field[x][y] == 'd') {

					g2.drawImage(dirtI.getImage(), x * 50, y * 50, this);

				}
				if (field[x][y] == 'g') {

					g2.drawImage(grasI.getImage(), x * 50, y * 50, this);

				}
				if (field[x][y] == 's') {

					g2.drawImage(skyI.getImage(), x * 50, y * 50, this);

				}
			}
		}

	}
}
 

Anhänge

  • turtle.jpg
    turtle.jpg
    153,8 KB · Aufrufe: 42
Zuletzt bearbeitet:

Zurück
Oben