Instanzen

Schlagdraufunschluss_124

Aktives Mitglied
Hallo,
ich habe heute ein Codeschnipsel im Internet gesehen:

Java:
import java.awt.*;
import javax.swing.JFrame;

public class PaintClass extends JFrame {
    public PaintClass(){
        super();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
  
    public void paint(Graphics g){
        g.drawLine(50,50,200,200);
    }
  
    public static void main(String[] args){
        PaintClass pc = new PaintClass();
        pc.setSize(400,400);
        pc.setVisible(true);
    }

}

Meine Frage: Warum wird die Paint-Methode aufgerufen obwohl sie überhaupt nicht irgendwo "via Code" angesprochen wird (Normalerweis muss man doch eine Methode irgendwo erwähnen, dass sie aufgerufen werden kann,oder?) ?

Edit: Übrigens habe ich meine Titel leider falsch benannt :)
 

RB-Development

Mitglied
Moin,
generell hast du Recht. Methoden müssen vorher "erstellt" werden.
Du Importierst hier aber zwei Bibliotheken
Java:
import java.awt.*;
import javax.swing.JFrame;
Diese Bibliotheken bieten dir diverse Funktionen (Methoden) an.
Unter anderem die besagte paint Methode.

Grüße
RB
 

Manuel.R

Bekanntes Mitglied
Ich glaube die Frage ist damit nicht ganz beantwortet, oder?

Es scheint mir, dass schlagdraufunschluss_124.55101 wissen möchte, warum die Methode paint aufgerufen wird, obwohl paint nicht explizit im code aufgerufen wird.
 

Schlagdraufunschluss_124

Aktives Mitglied
Ok, vielen Dank für eure Antworten!

Jetzt habe ich aber ein anderes Problem ;)

Ich habe eine Game-Loop gemacht mit den Methoden Render und Init. Diese rufen die Renderklasse auf, wo eben auch die paint-Methode drin ist. Wenn ich es aber richtig verstanden habe, so kann die Paint Methode nur aufgerufen werden, wenn ich den Frame in der selben Klasse erschaffen habe. Allerdings wird der Renderkostruktor durch die Gameloop ja sehr oft aufgerufen. Wie kann ich es also verhindern, dass nur die Paint-Methode aufgerufen wird, und nicht jedes Mal ein neues Frame erstellt wird ?

Edit: Rufe ich nur die paint Methode mit paint(Graphics g) von der Gameloop aus auf, so ist g in der Renderklasse ja immer "null"....

Code:
Java:
import java.awt.Graphics;

import javax.swing.JFrame;

public class Spiel extends JFrame implements Runnable {

    public final int fps = 60;
    public final long maxLoop = 1000 / fps;
    public boolean isRunning = true;
    Render render;
    Init init;



    public Spiel(Init init, Render render) {
       
        this.render = render;
       
        this.init = init;
       
        new Thread(this).start();
    }

    @Override
    public void run() {

        long oldTime;
        long curTime;

        while (isRunning) {
            oldTime = System.currentTimeMillis();
            init();
            render();
            curTime = System.currentTimeMillis();

            if ((curTime - oldTime) > maxLoop) {
                continue;
            } else {
                try {
                    Thread.sleep(maxLoop - (curTime - oldTime));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    void init() {
       
    }

    public void render() {
       
       
        render.paint(g);
       
    }
       
   
    }

Renderklasse:
Java:
import java.awt.Graphics;

import javax.swing.JFrame;

public class Render extends JFrame {

    public final int scwidth = 800;
    public final int scheight =800;
   
    public Render() {
        setSize(scwidth,scheight);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
       
       
    }
   
    public void paint(Graphics g){
        System.out.println("gg");
        g.fillRect(10, 50, 50, 50);
    }
   
   

}
 
Zuletzt bearbeitet:

mrBrown

Super-Moderator
Mitarbeiter
Moin,
generell hast du Recht. Methoden müssen vorher "erstellt" werden.
Du Importierst hier aber zwei Bibliotheken
Java:
import java.awt.*;
import javax.swing.JFrame;
Diese Bibliotheken bieten dir diverse Funktionen (Methoden) an.
Unter anderem die besagte paint Methode.
das klingt auf so vielen Ebenen merkwürdig...


Ich habe eine Game-Loop gemacht mit den Methoden Render und Init. Diese rufen die Renderklasse auf, wo eben auch die paint-Methode drin ist. Wenn ich es aber richtig verstanden habe, so kann die Paint Methode nur aufgerufen werden, wenn ich den Frame in der selben Klasse erschaffen habe. Allerdings wird der Renderkostruktor durch die Gameloop ja sehr oft aufgerufen. Wie kann ich es also verhindern, dass nur die Paint-Methode aufgerufen wird, und nicht jedes Mal ein neues Frame erstellt wird ?
*Nicht* von JFrame erben. Wenn du ein Fenster brauchst, deklariere ganz normal ein JFrame und inititialisiere es mit new JFrame
Wenn du zwingend die Paint-Methode überschreiben musst, erbe von JPanel.
 

Schlagdraufunschluss_124

Aktives Mitglied
Soll ich das Frame in dem Render - Konstruktor initialisieren, oder in einer eigenen Klasse (Da die Render Klasse von der Schleife ja aufgerufen wird, macht es ja mehr Sinn, wenn das Frame in einer eigenen Klasse initialisiert wird, oder?) ?
Und wieso wird die paintMethode zwar aufgerufen, zeichnet aber nix(Konsole gibt 2mal "gg" aus, das dann aber wieder verschwindet....)?

Java:
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Render extends JPanel {

    public final int scwidth = 800;
    public final int scheight =800;
   
    public Render() {
               
    }
    @Override
    public void paint(Graphics g){
        System.out.println("gg");
       
        g.fillRect(10, 50, 50, 50);
    }
   
   

}

Hier wäre dann meine extra GUI Klasse für das Frame.
Java:
import java.awt.Frame;

import javax.swing.JFrame;

public class Gui extends JFrame {
   
    public final int scwidth = 800;
    public final int scheight =800;
   
    public Gui(){
       
        JFrame gui =new JFrame ();
        gui.setSize(scwidth,scheight);
        gui.setDefaultCloseOperation(EXIT_ON_CLOSE);
        gui.setVisible(true);
       
       
    }

}

Edit: Oder macht es überhaupt keinen Sinn, dass die Render Methode in der Spielklasse eine Renderklasse aufruft?-> Sollte ich vielleicht das Rendern direkt in der Spielklasse ausführen ?

Java:
import java.awt.Graphics;

import javax.swing.JFrame;

public class Spiel extends JFrame implements Runnable {

    public final int fps = 60;
    public final long maxLoop = 1000 / fps;
    public boolean isRunning = true;
    Render render;
    Init init;



    public Spiel(Init init, Render render) {
       
        this.render = render;
       
        this.init = init;
       
        new Thread(this).start();
    }

    @Override
    public void run() {

        long oldTime;
        long curTime;

        while (isRunning) {
            oldTime = System.currentTimeMillis();
            init();
            render();
            curTime = System.currentTimeMillis();

            if ((curTime - oldTime) > maxLoop) {
                continue;
            } else {
                try {
                    Thread.sleep(maxLoop - (curTime - oldTime));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    void init() {
       
    }

    public void render() {
       
       
        new Render(); // Soll hier direkt gerendert werden ?
       
    }
       
   
    }
 

mrBrown

Super-Moderator
Mitarbeiter
Du erstellst immer noch drei verschiedene JFrames!

Ich würde dir empfehlen, dich erstmal mit Grundlagen auseinander zu setzen.
 

fhoffmann

Top Contributor
Java:
public class Gui extends JFrame {
     public Gui(){
         JFrame gui =new JFrame ();
Und hier erbst du von JFrame und hast eine lokale Variable vom Typ JFrame.
 

Schlagdraufunschluss_124

Aktives Mitglied
Gehts so wie ich's jetzt gemacht habe ?

Java:
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Spiel extends JFrame implements Runnable {

    Data data;
    public final int fps = 60;
    public final long maxLoop = 1000 / fps;
    public boolean isRunning = true;
    // Graphics g;



    public Spiel(Data data) {
        this.data = data;
     
        new Gui(data);
        new Thread(this).start();
    }

    @Override
    public void run() {

        long oldTime;
        long curTime;

        while (isRunning) {
            oldTime = System.currentTimeMillis();
            init();
            render();
            curTime = System.currentTimeMillis();

            if ((curTime - oldTime) > maxLoop) {
                continue;
            } else {
                try {
                    Thread.sleep(maxLoop - (curTime - oldTime));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    void init() {
        data.setEx_X(data.getEx_X()+1);
        data.setEx_Y(data.getEx_Y()+1);
        System.out.println("X:  "+data.getEx_X());
        System.out.println("Y:  "+data.getEx_Y() );
    }

    public void render() {
        System.out.println("Zeichne");
        repaint();
     
 
    }
Java:
import java.awt.Graphics;

import javax.swing.JFrame;

public class Gui extends JFrame {

    Data data;
    public Gui(Data data) {
        this.data = data;
        setSize(500, 500);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
     
    }
 
    public void paint(Graphics g){
        g.fillRect(data.getEx_X(), data.getEx_Y(), 100, 100);
        //repaint();
     
    }

}



1) Wenn ja : Warum "funktioniert" repaint() nicht ?
2) Wenn nein: Wie kann ich von der whileSchleife bzw. der RenderMethode aus eine Paint Methode aufrufen ohne, dass ich jedes mal z.B. einen Konstruktor aufrufe?
-> Wenn ich nur in der RenderMethode die PaintMethode aufrufe, dann muss ich ja der PaintMethode das "Graphics g" Objekt weiterreichen.-> "Graphics g " kann ich aber irgendwie nicht initialisieren.. :(
 

mrBrown

Super-Moderator
Mitarbeiter
Wie du selber feststellst: Nein, geht nicht.

Du lässt immer noch beiden Klassen von JFrame erben, das sollte *keine* Klasse machen.

1) Wenn ja : Warum "funktioniert" repaint() nicht ?

render ruft in Spiel repaint auf, was dann dann zu einem neuzeichnen von Spiel führt.
Das angezeigte Fenster ist Gui, das ist ein *anderes* Fenster und bekommt deshalb davon nichts mit.

2) Wenn nein: Wie kann ich von der whileSchleife bzw. der RenderMethode aus eine Paint Methode aufrufen ohne, dass ich jedes mal z.B. einen Konstruktor aufrufe?
-> Wenn ich nur in der RenderMethode die PaintMethode aufrufe, dann muss ich ja der PaintMethode das "Graphics g" Objekt weiterreichen.-> "Graphics g " kann ich aber irgendwie nicht initialisieren.. :(
Selber aufrufen musst du es nicht, das macht das Framework.
 

Schlagdraufunschluss_124

Aktives Mitglied
render ruft in Spiel repaint auf, was dann dann zu einem neuzeichnen von Spiel führt.
Das angezeigte Fenster ist Gui, das ist ein *anderes* Fenster und bekommt deshalb davon nichts mit.

Kommt es daher, weil ich jede Klasse von JFRame erben lasse ? -> Sprich Spiel erbt von "JFrame 1.0" und Gui von "JFrame 2.0" ?

Wo lasse ich dann zeichnen, wenn ich nicht alles in einer Klasse(Spiel) haben möchte?
-> Oder ist gar nicht schlimm wenn ich alles in einer Klasse habe ?

Edit: Danke für die Antwort :)
 

mrBrown

Super-Moderator
Mitarbeiter
Kommt es daher, weil ich jede Klasse von JFRame erben lasse ? -> Sprich Spiel erbt von "JFrame 1.0" und Gui von "JFrame 2.0" ?
Ja und nein. Spiel ist ein JFrame und Gui ist ein anderes JFrame, eben weil du erben lässt. Das extends ist an der Stelle falsch und sollte durch eine einfache Instantvariable ersetzt werden.

Wo lasse ich dann zeichnen, wenn ich nicht alles in einer Klasse(Spiel) haben möchte?
-> Oder ist gar nicht schlimm wenn ich alles in einer Klasse habe ?
Doch, das wäre irgendwann schlimm.
Du musst einfach das angezeigte Fenster neu zeichnen lassen.
 

Schlagdraufunschluss_124

Aktives Mitglied
Es funzt !!!!:)

Aber leider "hinterlässt das gezeichnete Recteck eine Spur beim Zeichnen"
-> es sieht so aus als ob repaint() einfach nur "drübermalt"...:D
Java:
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Spiel implements Runnable {

    Data data;
    Gui gui;
    public final int fps = 60;
    public final long maxLoop = 1000 / fps;
    public boolean isRunning = true;
    // Graphics g;



    public Spiel(Data data) {
        this.data = data;
        Gui gui = new Gui(data);
       
        this.gui = gui;
        /*gui.setSize(500, 500);
        gui.setDefaultCloseOperation(gui.EXIT_ON_CLOSE);
        gui.setVisible(true);*/
        //new Gui(data);
        new Thread(this).start();
    }

    @Override
    public void run() {

        long oldTime;
        long curTime;

        while (isRunning) {
            oldTime = System.currentTimeMillis();
            init();
            render();
            curTime = System.currentTimeMillis();

            if ((curTime - oldTime) > maxLoop) {
                continue;
            } else {
                try {
                    Thread.sleep(maxLoop - (curTime - oldTime));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    void init() {
        data.setEx_X(data.getEx_X()+1);
        data.setEx_Y(data.getEx_Y()+1);
        System.out.println("X:  "+data.getEx_X());
        System.out.println("Y:  "+data.getEx_Y() );
    }

    public void render() {
        System.out.println("Zeichne");
       
        gui.repaint();
       
   
    }
   
       
   
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Drachenbauer wie kann ich alle instanzen einer Klasse durchsehen, ohne, dass diese in einer Liste erzeugt wurden? Allgemeine Java-Themen 11
S Zugriff auf jUnit Test Suite Runner-Instanzen innerhalb von Test Classes Allgemeine Java-Themen 7
R Instanzen eines Programms Allgemeine Java-Themen 8
S Lambda Ausdrücke: @FunctionalInterface Instanzen auf null prüfen Allgemeine Java-Themen 9
A Thread: Code paralell ausführen in mehreren Instanzen Allgemeine Java-Themen 1
3 OOP Instanzen aus einer Klasse persistent speichern. Allgemeine Java-Themen 9
V Array aus Instanzen, NullPointer Allgemeine Java-Themen 4
H [Logback || log4j] Wie richtig loggen / Log Instanzen verwalten Allgemeine Java-Themen 2
B JUnit und mehrere Instanzen der selben Applikation Allgemeine Java-Themen 4
ruutaiokwu warum instanzen typisieren? Allgemeine Java-Themen 10
T Edit: JLabel+MouseListener oeffnet mehrere Instanzen Allgemeine Java-Themen 5
S Strings zu Color-Instanzen parsen? Allgemeine Java-Themen 7
P Mehrere Instanzen der selben Appl. verhindern Allgemeine Java-Themen 12
G enf instanzen Allgemeine Java-Themen 5
B 2 JList instanzen wo nur einer zur selben Zeit selektierbar? Allgemeine Java-Themen 8
B Instanzen einer Klasse als Array Allgemeine Java-Themen 7
K JNI: mehrere "Instanzen" einer C++ DLL? Allgemeine Java-Themen 3
C Mehrere Instanzen für einen Programm Allgemeine Java-Themen 3
X Mehrere Instanzen erzeugen Allgemeine Java-Themen 6
D Gehts praktischer? Thema:Verschiedene Instanzen einer Klasse Allgemeine Java-Themen 3
P Mehrere Instanzen beim IE verhindern Allgemeine Java-Themen 11
F Das Anlegen von Objekt-Instanzen... Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben