Erste Schritte Zeichenproblem

Schrubber

Bekanntes Mitglied
Hallo Leute,

ich hänge (mal wieder) beim Zeichnungsvorgang.
Ich hab mir zwar einige Posts durchgelesen, werde jedoch immernoch net schlau und verstehs mehr oder weniger auch nicht.

Hier mein bisheriger Code:

Java:
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class Main implements KeyListener {
	
	private Window window = new Window();
	
	static int wx = 500;
	static int wy = 500;
	static int lx = 200;
	static int ly = 200;
	
	public static void main(String[] args) {
		new Main().init();
	}
	
	public void init() {
		JFrame mainwindow;
		
		String gamename = "Schrubber's TestRPG";
		
		mainwindow = new JFrame(gamename);
		mainwindow.add(window.init());
		
		mainwindow.addKeyListener(new Main());
		mainwindow.setVisible(true);
		mainwindow.setPreferredSize(new Dimension(wx,wy));
		mainwindow.setLocation(lx,ly);
		mainwindow.setResizable(false);
		mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainwindow.pack();
		mainwindow.repaint();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		int keycode = e.getKeyCode();
		//System.out.println(keycode);
		
		if(keycode == 38) {
			System.out.println("Pfeiltaste hoch");
		} else {
			if(keycode == 37) {
				System.out.println("Pfeiltaste links");
			} else {
				if(keycode == 40) {
					System.out.println("Pfeiltaste runter");
				} else {
					if(keycode == 39) {
						System.out.println("Pfeiltaste rechts");
					} else {
						if(keycode == 73) {
							System.out.println("Taste I"); //Inventory
						} else {
							if(keycode == 67) {
								System.out.println("Taste C"); //Character
							}
						}
					}
				}
			}
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}

	@Override
	public void keyTyped(KeyEvent e) {		
	}
}

Java:
import java.awt.Dimension;

import javax.swing.JPanel;

public class Window {
	public JPanel init() {
		JPanel mainpanel = new JPanel();
		
		mainpanel.add(new Spielfeld().spielfeld());
		mainpanel.add(new Navi().navigation());
		
		mainpanel.setLayout(null);
		mainpanel.setSize(new Dimension(500,500));
		mainpanel.setVisible(true);
		
		return mainpanel;
	}
}

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

public class Spielfeld extends JPanel {	
	public JPanel spielfeld() {
		JPanel spielfeld = new JPanel();
		
		
		spielfeld.setBounds(0,0,Main.wx,Main.wy-100);
		spielfeld.setPreferredSize(new Dimension(Main.wx,Main.wy-100));
		spielfeld.setBackground(Color.green);
		
		return spielfeld;
	}	
	
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
	    g.drawLine(50,50,150,80);
	}
}

Nun würde ich gerne die Methode paintComponent() aus Spielfeld aufrufen, um auf dem Panel dann zu zeichnen. Jedoch habe ich weder nen Plan, wie ich das mach, noch eine hilfreiche Lösung im Netz gefunden :(


Hoffe, ihr könnt mir helfen :)

Grüße,
Schrubber
 

pro2

Bekanntes Mitglied
Nun würde ich gerne die Methode paintComponent() aus Spielfeld aufrufen, um auf dem Panel dann zu zeichnen. Jedoch habe ich weder nen Plan, wie ich das mach, noch eine hilfreiche Lösung im Netz gefunden

Die Methode ruft man nicht direkt auf, sondern man ruft immer repaint(); auf, was dann alle Zeichenmethoden ausführt :)
 

Schrubber

Bekanntes Mitglied
Aber selbst ein mainwindow.repaint() in meiner Main-Class, weder ein spielfeld.repaint() in meiner Spielfeld-Class bringen den erhofften Erfolg :-/ Oder mach ich wiedermal nen Denkfehler?
 
S

Stumpä

Gast
Vieleicht so, dass Widget(Button oder so) das die "actionPerformed()-Methode" aufruft, ruft dann seinerseits die entsprechende Zeichen-Klasse auf. Wobei die repaint() - Methode, je nach dem, in der actionPerformed() steht oder Zeichenklasse(paintComponent()).
 

Marco13

Top Contributor
OK, habs nochmal überlogen (aber nur kurz, bin total übermüdet) : Bei sowas wie
new Spielfeld().spielfeld()
wird die "spielfeld"-Methode aufgerufen, die gibt aber KEIN Spielfeld zurück, sondern nur ein JPanel. Schau dir ggf. mal den Link an, ansonsten schau ich morgen nochmal genauer.
 

Milo

Bekanntes Mitglied
Hi,

das Problem hat Marco schon gut beschrieben. Du musst Deine Spielfeldklasse so abändern und verwenden, dass Du eine Instanz von dieser verarbeitest. Du könntest bspw. all Deine Initialisierungen direkt im Konstruktor machen. Da Spielfeld von JPanel erbt, kannst Du alle öffentlichen Methoden direkt nutzen.

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
 
import javax.swing.JPanel;
 
public class Spielfeld extends JPanel { 
	public Spielfeld() {
        this.setBounds(0,0,Main.wx,Main.wy-100);
        this.setPreferredSize(new Dimension(Main.wx,Main.wy-100));
        this.setBackground(Color.green);
    }   
    
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawLine(50,50,150,80);
    }
}

In der Windowklasse muss es dann nur noch so heißen:

Java:
mainpanel.add(new Spielfeld());

Gruß Micha
 

Schrubber

Bekanntes Mitglied
Okay nun gehts :) Eine letzte Frage:

Ich möchte meinen Kreis (habe Strich gegen Kreis getauscht) nun wandern lassen. Hierzu habe ich 3 Variablen. 1x für Radius, 1x für x und 1x für y. Diese änder ich per KeyListener, was auch geht. Nun meine Frage: Wie kann ich nun machen, dass er die Zeichnung neuzeichnet? repaint() brachte irgendwie nichts :-/
 

Terep

Mitglied
Guten Morgen Schrubber

Kann Dir zwar keine Lösung anbieten, aber ich habe den gleichen Sachverhalt auch gerade ganz frisch gepostet. Vielleicht haben wir ja beide Glück und kommen mit unseren Projekten weiter.

Terep
 

Marco13

Top Contributor
Auch dazu ist in dem verlinkten Thread einiges geschrieben. Ganz grob könnte man sowas machen
Java:
class PaintPanel extends JPanel
{
    // Das Objekt, das gezeichnet werden soll
    private Rectangle objectToPaint = new Rectangle(0,0,10,10);
 
    // Setzt das Objekt, das gezeichnet werden soll, und
    // löst ein Neuzeichnen aus.
    public void setCircleValues(int x, int y, int radius)
    {
        objectToPaint.x = x-radius;
        objectToPaint.y = y-radius;
        objectToPaint.width = 2*radius;
        objectToPaint.height = 2*radius;
        repaint();
    }
 
    // Die paintComponent-Methode wird immer aufgerufen,
    // wenn das Panel neu gezeichnet wird
    @Override
    protected void paintComponent(Graphics graphics)
    {
        super.paintComponent(graphics);
        Graphics2D g = (Graphics2D) graphics;
 
        // Hier wird das zu zeichnende Objekt gemalt: ------ ABER ALS KREIS (Oval) 
        if (objectToPaint != null)
        {
            g.setColor(Color.BLACK);
            g.drawOval(objectToPaint.x, objectToPaint.y, objectToPaint.width, objectToPaint.height);
        }
    }
}
Aber schau dir auch mal an, wie es in dem Thead weitergeht, zum zeichnen von mehreren Objekten (vermutlich willst du ja nicht nur EINEN Kreis zeichnen), mit dem dort beschriebenen "Paintable" interface. In diesem Fall würde man die Änderungen der Positionen der Objekte nicht mehr in der PaintPanel-Klasse machen, sondern außerhalb, und die PaintPanel-Klasse würde nur ganz "dumm" alles zeichnen, was man ihr vorsetzt.
 
F

Flavinius

Gast
Die Beispiele von Marco sind doch ganz gut auch das Tutorial, einfach mal durchlesen.

Und vielleicht könnte dir dieser Code auch behilflich sein.

Java:
for (int i = 0; i < 210; i++) {

   x++;
   y++;

   Spielfeld.repaint();

   try {
    Thread.sleep(50);
   } catch (Exception e) { }
  }
 }

 class Spielfeld extends JPanel {

  public void paintComponent(Graphics g) {
   g.setColor(Color.white);
   g.fillRect(0,0,this.getWidth(),this.getHeight());

   g.setColor(Color.green);
   g.fillOval(x,y,40,40);
  }
 }
}
 

Neue Themen


Oben