Java Grafik-Programmierung?

oOJavaNeulingOo

Bekanntes Mitglied
Guten Morgen!

Ich wollte hier mal nachfragen, wie schwer es ist in Java 2D-Grafik Programme (Spiele, ..) zu erstellen, und ob es dazu bestimmte Engines gibt, usw, usw.. Bis jetzt habe ich immer nur ein paar sehr kleine Konsolen-Programme und Addons zu bestimmten Spielen programmiert. Daher würde ich sagen, ein klitzkleines bisschen kenne ich die "Grundlagen" (<-- Keine Ahnung wie ich es anders formulieren soll..), doch habe ich keine Ahnung wie ich jetzt mit Grafikprogrammierung anfangen sollte.

MfG
 
Hallo,

wenn du die Grundlagen beherrschst ist die Grafikprogrammierung kein Problem für dich. Anfangen solltest du dann erstmal mit kleinen GUI-Programmen, bevor du wirklich selbst anfängst zu zeichnen.
 
Vielen Dank für die schnelle Antwort!

Die Grundlagen "beherrschen" würde ich es jetzt eher nicht nennen, aber eben so ein kleines bisschen 😀

Naja, aber wie fange ich denn mit solchen GUI-Programmen an? Welche Library? Was für ein Programm?
 
Ich versuche mich auch gerade in die Grafikprogrammierung von Java hineinzuarbeiten.
Daher möchte ich keinen neuen Thread aufmachen sondern diesen hier mit nutzen.

Man lehrte uns, die Bibliothek awt - "Graphics" einzubziehen.. Sie wird für die 2D - Programmierung genutzt.

Damit kann man Linien, Kreise, Rechtecke, Quadrate usw. zeichnen.
Dazu habe ich auch ein Tutorial gefunden. Leider aber auf Englisch:
Java Programming Tutorial - 84 - Drawing Graphics - YouTube

Wir nutzen gerade den Window Builder. Er dient als Java GUI Designer:
Eclipse Tutorial: GUI-Anwendungen mit WindowBuilder: Der Einstieg - YouTube
Er soll als Hilfe dienen um Fenster schneller aufbauen zu können.

Nun bin ich gerade dabei, einfache Rechtecke in einem JPanel zu zeichnen.
Es funktioniert auch. Aber, ich diese Rechtecke werden auf der Grundfläche im content Pane gezeichnet.
Ich möchte diese Rechtecke aber in einem weiteren JPanel zeichnen lassen.
Also die Bounds davon als Bezugspunkt nutzen.
Wie bekomme ich das hin? ???:L

Hier mein aktueller Quelltext:

Java:
package Sinus;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;		// für Grafiken in der GUI
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JTextField;


public class Sinus extends JFrame {

	
	
	JPanel contentPane = new JPanel();
	private JPanel Sinuspanel;
	private JTextField textField;
	private Graphics g2D;
	
	
	/**
	 * Launch the application.
	 */
	

	
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					
					Sinus frame = new Sinus();
					frame.setVisible(true);
					
					
				} catch (Exception e) {
					
					
					e.printStackTrace();
					
					
				}
			}
		});
	}

	
	
	
	
	/**
	 * Create the frame.
	 */
	
	
	public Sinus() {
		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 800, 400);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JPanel Sinuspanel = new JPanel();
		Sinuspanel.setBounds(50, 50, 450, 207);
		contentPane.add(Sinuspanel);
		Sinuspanel.setLayout(null);
		
		textField = new JTextField();
		textField.setBounds(25, 251, 86, 20);
		contentPane.add(textField);
		textField.setColumns(10);
		contentPane.add(Sinuspanel);
		
		// 900 = Start des Fensters vom linken Bildschirmrand bis zum Beginn der linken Seite des Fensters
		// 400 = Start des Fensters vom oberen Bildschirmrand bis zum Beginn der Kopfseite des Fensters
		// 130 = Die Breite des Fensters
		// 300 = Die Höhe des Fensters
	

		
	}		// Wie kann ich diesen Teil in einem JPanel ( in meinem Fall: "Sinuspanel") integrieren?
	public void paint (Graphics g2D){
		
		g2D.setColor(Color.BLUE);
		g2D.fillRect(25,35,100,30);
		
		}
	}
 
@ TKausL

Okok, da sich die Mehtode in der Basisklasse auch "paintComponent" nennt, sollte man nun auch den Namen weiterhin verwenden. In Ordnung habe ich umgetzt.
Hmm.. der Variablenname selbst kann ja auch andere bezeichnungen als "g" haben.
Deshalb habe ich nun mal g2D für 2D Grafiken gewählt.


In der ersten Zeile meiner Konfiguration der Methode paintComponent soll den Aufruf der Mehtode in der Baisklasse sein.
Wenn ich das mit in den Quellcode nehme, wird NICHTS mehr gezeichnet.
Egal, wo ich die Startpunkte setze :-/
Was geschieht bei diesem Methodenaufruf, das meine Funktion außer Kraft gesetzt wird?
 
Hmm.. der Variablenname selbst kann ja auch andere bezeichnungen als "g" haben.
Deshalb habe ich nun mal g2D für 2D Grafiken gewählt.

Ist aber Verwirrend da du ein Graphics-Object übergeben bekommst, und kein Graphics2D-Object.
In vielen PaintComponents siehst du dann sowas:

Java:
public void paintComponent(Graphics g){
  Graphics2D g2d = (Graphics2D) g;
  //Draw blabla
}

Das was du danach erklärst verstehe ich leider nicht so ganz 🙁
 
Ich habe das so mitbekommen, das dieses Objekt g aus der Klasse Graphics wohl nur für 2D Grafiken genutzt wird. Seit dem wir in bei der eigentlichen Programmierung von Java sind mit OOA - OOD und OOP haben sich die Ereignisse recht schnell überschlagen und ich hab wohl etwas den Anschluss verpasst.

Ich bekomme keinen Fehler angezeigt, aber mein blaues Rechteck wird nicht mehr gezeichnet:

Das Objekt g vom Datentyp Graphics habe ich neben den Elementen der GUI mit instanziert.

Java:
	public Sinus() {
	
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(0,0, 800, 400);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JPanel Sinuspanel = new JPanel();
		Sinuspanel.setBounds(50, 50, 450, 207);
		contentPane.add(Sinuspanel);
		Sinuspanel.setLayout(null);
		
		txtTest = new JTextField();
		txtTest.setText("Test");
		txtTest.setBounds(50, 268, 86, 20);
		contentPane.add(txtTest);
		txtTest.setColumns(10);
		contentPane.add(Sinuspanel);

	}			
	public void paintComponent (Graphics g2D){
		super.paintComponents(g2D);
		
		g.setColor(Color.BLUE);
		g.fillRect(20,30,35,50);
			
		}
	}

Aber nun wird gar nix mehr angezeigt .. Was mache ich denn falsch?
 
Abend, wollt mich nochmal melden. :meld:
Das was ich erreichen wollte habe ich nun auch geschafft.

Aber, ich würde diese geschaffen Funktion gerne auf einem JPanel aufzeichnen, sodass ich nachher im JFrame auch zwischen den Reitern wechseln kann.. ich hoffe, ihr versteht mein ursprüngliches Problem nun so besser.



Das Objekt "achsenWerte" wird in dieser Klasse erzeugt, der Bauplan befindet sich in der Klasse Sinuskonfiguration.

Java:
package Sinus;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;		// für Grafiken in der GUI
import java.awt.Image;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JTextField;

public class Sinus extends JFrame {

	private JPanel contentPane = new JPanel();
	private JTextField textField;
	private Graphics g2D;
	private JPanel Sinuspanel = new JPanel();
	private int height=240;
	private int width=440;
	private Sinuskonfiguration achsenWerte = new Sinuskonfiguration ();
	int pixelX[] = new int [361];
	int pixelY[] = new int [361];
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Sinus frame = new Sinus();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
					}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Sinus() {
		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		setSize(800, 500);
		setLocationRelativeTo(null);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		Sinuspanel.setBounds(50, 50, 450, 207);
		contentPane.add(Sinuspanel);
		Sinuspanel.setLayout(null);
		
		textField = new JTextField();
		textField.setBounds(50, 268, 86, 20);
		contentPane.add(textField);
		textField.setColumns(10);
		contentPane.add(Sinuspanel);
	
		for (double winkelalpha = 0; winkelalpha <= 360; winkelalpha += 1){
			
			double sinus,udach,augenblickswert;
			sinus=augenblickswert= 0;
			udach=50;
			int alpha = (int) winkelalpha;
			
				//	=SIN(2*PI()*alpha/360)
				sinus = Math.sin(2 * Math.PI * (winkelalpha/360));
				augenblickswert = sinus * udach;
				pixelX[alpha]= Math.round(Math.round((winkelalpha/360)*width));
				pixelY[alpha]= Math.round(Math.round((augenblickswert/udach)*height/2));
				System.out.println("Sinus von: " + sinus + " bei einem Winkel von " + winkelalpha + "° & einem Augenblickswert von: " + augenblickswert + "V" +
						" ---   X-Achse: " + pixelX[alpha] + " Y-Achse: " + pixelY[alpha]);
				
				achsenWerte.setAchsenwerte(pixelX, pixelY, alpha);
		}
	
}	
	
	public void paint (Graphics g2D){
		super.paintComponents(g2D);
		
		g2D.setColor(Color.BLUE);
		g2D.fillRect(8,31,200,80);
		
		// 8 = Anfangspunkt bezogen auf 8 Pixel von der linken Seite des Fensters bis zur linken Seite des Rechtecks
		// 31  = Anfangspunkt bezogen auf 31 Pixel vom oberen Seitenrand des Fensters bis zur Kopfseite des Rechtecks
		// 200 = Endposition des Rechtecks auf der X-Achse  (Beginn von der linken Seite des Fensters)
		// 80 = Endposition des Rechtecks auf der Y-Achse  (Beginn vom oberen Seitenpunkt des Fensters)
		
		g2D.setColor(Color.BLACK);
		g2D.drawLine(250, 50, 250, 300);
		
				// 250 = Anfangspunkt bezogen auf 250 Pixel von der linken Seite des Fensters bis zur linken Seite der Linie
				// 50  = Anfangspunkte bezogen auf 50 Pixel vom oberen Seitenrand des Fensters bis zum oberen Anfangspunkt der Linie
				// 250 = Endposition der Linie auf der X-Achse  (Beginn von der linken Seite des Fensters)
				// 300 = Endposition der Linie auf der Y-Achse  (Beginn vom oberen Seitenpunkt des Fensters)
		
		g2D.drawLine(250, 175, 700, 175);

			// Nur als Beispiel:
			
			g2D.setColor(Color.BLACK);
			g2D.fillRect(450, 175, 1, 1);
			g2D.fillRect(650, 175, 1, 1);
			
//			g2D.drawLine(450, 175, 1, 1);

			// 450 = Anfangspunkt bezogen auf 450 Pixel von der linken Seite des Fensters bis zur linken Seite der Linie
			// 175  = Anfangspunkte bezogen auf 175 Pixel vom oberen Seitenrand des Fensters bis zum oberen Anfangspunkt der Linie
			// 1 = Breite des Quadrats auf der X-Achse  (Beginn vom Anfangspunkt X-Achse)
			// 1 = Höhe des Quadrats auf der Y-Achse  (Beginn vom Anfangspunkt Y-Achse)
	
			for (int alpha = 0; alpha <= 360; alpha += 1){
				int pixelX = achsenWerte.getpixelX(alpha);
				int pixelY = achsenWerte.getpixelY(alpha);
				System.out.println("Winkel: " + alpha + "° --- X-Achse: " + pixelX + " --- Y-Achse: " + pixelY);
				g2D.fillRect(pixelX + 250, 175 - pixelY, 1, 1);
			}
		
		}
	
	}

Klasse Sinuskonfiguration im selben Package (Sinus)
Java:
package Sinus;
public class Sinuskonfiguration {

	private int pixelX [] = new int [361];
	private int pixelY [] = new int [361];
	
	Sinuskonfiguration () {	}

	public void setAchsenwerte (int pixelX[], int pixelY[], int alpha){
		this.pixelX[alpha]=pixelX[alpha];
		this.pixelY[alpha]=pixelY[alpha];
		}
		
	public int getpixelX (int alpha){
		return pixelX[alpha];
	}	
	
	public int getpixelY (int alpha){
		return pixelY[alpha];
	}
	
}

glmssvf9.jpg


Mühsam ernährt sich das Eichhörnchen 🙂
Das Schöne daran ist, das ich nun mit einem Lächeln nächtigen gehe.
Vielen Dank an euch!
 
Bei so etwas kann es an verschiedenen Stellen Probleme geben. Wenn man selbst zeichnet, muss man auf mehrer Dinge achten. z.B. nutzt man einen LayoutManager und orientiert sich dieser an der PreferredSize der Kompnonente. Wenn man selbst zeichnet muss man sich auch selbst darum kümmern, dass die korrekte PreferredSize der Komponente richtig gesetzt ist.
Wenn man die Komponente in den CENTER Bereich eines BorderLayouts setzt (s.u.), spielt das alles keine Rolle.

Aber grundsätzlich gilt in 99,9% der Fälle:
- man erbt von JPanel oder JComponent und überschreibt deren paintComponent(Graphic)
- und ruft darin als erstes deren super.paintComponent(Graphic) auf
Java:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 500, 200);
frame.setLocationRelativeTo(null);

frame.add(new JPanel() {
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		int yM = this.getHeight()/2;
		g.drawLine(0, yM, this.getWidth(), yM);
		for (int x = 0; x < this.getWidth(); x++) {
			double sin = Math.sin(Math.toRadians(x)) * (yM-20);
			g.drawLine(x, yM -(int)sin, x, yM -(int)sin);
		}
	}
});
 

Zurück
Oben