Graphics2D. repaint()

Status
Nicht offen für weitere Antworten.
A

Alex___

Gast
Hallo zusammen,

ich zeichne ein Spielfeld mit

Code:
BufferedImage bi = ImageIO.read(new File("feld.jpg"));
		    g2 = bi.createGraphics();
	        g2.setPaint(Color.red);
	        	        
	        label = new JLabel(new ImageIcon(bi));

später setze ich dort ein paar Werte:

Code:
g2.drawString(logik.getBox(x, y), logik.get_kastenMitteHorizontal(x), logik.get_kastenMitteVertikal(y));


nun habe ich aber das Problem, dass der Inhalt nicht immer sichtbar wird. Wenn nichts zu sehen ist, muss ich das Fenster erst verkleinern und wieder vergrößern - dann ist alles da.
Ein repaint() hilft komischerweise nicht.

Hat jemand eine Idee woran es liegt?

Grüße
Alex
 
A

Alex_____

Gast
Hi,

nein, der Aufruf. Hier ist die ganze Klasse:

Code:
public class zahlen_GUI extends JFrame implements MouseListener {

//	private Point mousePos;
	Dimension prefSize;
	private static BufferedImage image;
	static JLabel label;
	static Graphics2D g2;
	boolean klickFlag = false;
	int klick1X, klick1Y, klick2X, klick2Y;
		
		zahlen_GUI() throws IOException {
	    	BufferedImage bi = ImageIO.read(new File("feld.jpg"));
		    g2 = bi.createGraphics();
	        g2.setPaint(Color.red);
	        	        
	        label = new JLabel(new ImageIcon(bi));
	        JFrame f = new JFrame();
	        
	        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	        f.getContentPane().add(label, "West");
  
	        f.pack();
	        f.setVisible(true);
		}
		
		//Bekommt einen Wert aus der LogikMatrix und zeichnet diesen ins Feld ein
		public static void getBoxContents(Graphics2D g, int x, int y) {
			g.drawString(logik.getBox(x, y), logik.get_kastenMitteHorizontal(x), logik.get_kastenMitteVertikal(y));
		}
		
		//Löscht den grafischen Inhalt einer Box
		public void deleteBox(Graphics2D g, int x, int y) {
			g.setColor(Color.black);
			g.fillRect(x-10, y-15, 20, 17);
			repaint();
		}
	
		//Setzt einen Wert in das Spielfeld und die LogikMatrix
		public static void setBoxContents(Graphics2D g, int x, int y, String inhalt) {
			g.setColor(Color.white);			
			logik.setBox(x, y, inhalt);
			getBoxContents(g, x, y);
		}
		
		//Zeichnet das Startfeld
		public static void drawInit(Graphics2D g, int feldBreite,int startReihen){
			for(int i=0; i<=feldBreite; i++) {
				for (int i2=0; i2<= startReihen; i2++) {
					getBoxContents(g, i, i2);
				}
			}
		}

	    synchronized public void mouseClicked(MouseEvent e){
//	    	mousePos = e.getPoint();
	    	System.out.println("x: " + e.getX() );
	    	System.out.println("y: " + e.getY() );
	    	
//	    	System.out.println("Kasten hor: " + logik.get_kasten_h(e.getX()) );
//	    	System.out.println("Kasten ver: " + logik.get_kasten_v(e.getY()) ); 
//	    	System.out.println("Kasten Inahlt: " + logik.get_feld( logik.get_kasten_h(e.getX()), logik.get_kasten_v(e.getY())) ); 	
	    	
	    	//klick1X, klick1Y, klick2X, klick2Y definieren die angeklicken Kästchen
	    	if (klickFlag == false) {
	    		klickFlag = true;
	    		klick1X = logik.get_kasten_h(e.getX());
	    		klick1Y = logik.get_kasten_v(e.getY());
	    	}
	    	else
	    	{
	    		klickFlag = false;
	    		klick2X = logik.get_kasten_h(e.getX());
	    		klick2Y = logik.get_kasten_v(e.getY());
	    		System.out.println("Klick 1: " + klick1X + "," + klick1Y );
	    		System.out.println("Klick 2: " + klick2X + "," + klick2Y );
	    		
	    		if (logik.moveValid(klick1X, klick1Y, klick2X, klick2Y)) {
	    			System.out.println("Zug gültig");
	    			if (Integer.valueOf(logik.getBox(klick1X, klick1Y)) + Integer.valueOf(logik.getBox(klick2X, klick2Y)) == 10 ) {
	    				System.out.println("Summe ergibt 10!");
	    				
	    				deleteBox(g2, logik.get_kastenMitteHorizontal(klick1X), logik.get_kastenMitteVertikal(klick1Y));
	    				deleteBox(g2, logik.get_kastenMitteHorizontal(klick2X), logik.get_kastenMitteVertikal(klick2Y));
	    				setBoxContents(g2, klick1X, klick1Y, ".");
	    				setBoxContents(g2, klick2X, klick2Y, ".");
	    			}
	    		}
	    	}
	    }
	    
		/**
	    leere Implementierung (nur aus formalen Gründen vorhanden)
	    */
	    public void mouseEntered(MouseEvent e){
	    }
	    public void mouseExited(MouseEvent e){
	    }
	    public void mousePressed(MouseEvent e){
	    }
	    public void mouseReleased(MouseEvent e){
	    }
	    
	    public static void main(String[] args) throws IOException {
	    	zahlen_GUI GUI = new zahlen_GUI();
	        label.addMouseListener(GUI);
	        
	        feldoperationen.initFeld();
	        drawInit(g2, 8, 2);
	        
	        setBoxContents(g2, 5, 5, ".");
	        setBoxContents(g2, 6, 5, ".");
	        setBoxContents(g2, 4, 5, "9");
	        setBoxContents(g2, 7, 5, "1");
	        setBoxContents(g2, 8, 5, "x");
	    }
}


Die Methode "deleteBox" zB. zeichnet das Rechteckt nicht. Bzw es wird erst dann sichtbar, wenn ich das Fenster verkleinere und wieder vergrößere.
 

0x7F800000

Top Contributor
ich weiss nicht was das programm tun soll, aber ich kann folgendes sagen:
1) ich habe da gar keine paint() methode entdeckt? :bahnhof: bin ich blind oder wie?
2) du hast ein gewaltiges problem, was die trennung von logik und grafik angeht. Methoden wie "drawInit()" haben absolut nirgendwo in keinem kontext eine existenzberechtigung, sowas ist einfach sinnlos
3) natürlich sihst du erstmal nichts wenn du eine von diesen tollen "zeichenmethoden" wie "deleteBox" aufrufst: swing ist doppeltgepuffert. Wenn du da mit dem graphics-objekt irgendetwas darauf zeichnest, zeichnest du zunächst nur im backbuffer. Erst wenn du das fenster verzerrst wird die komponente neugezeichnet, und die veränderungen kommen zum vorschein. Du müsstest zumindest mal die repaint() manuell aufrufen, damit du etwas siehst.

Aber konzentriere dich bitte vor allem auf den zweiten punkt. So ein Logik-Grafik mix ist echt einfach nur verwirrend...
 
G

Guest

Gast
Hi,

in der Methode deleteBox wird repain() aufgerufen. Trotzdem passiert dort nix.
Wohin soll denn drawInit deiner Meinung nach ausgelagert werden?

Gruß
Alex
 

0x7F800000

Top Contributor
repaint() wird da aufgerufen? meinst du echt? :wink:

na dann schau dir doch bitte nochmal an, die repaint()-methode welcher klasse da aufgerufen wird:

zahlen_GUI() throws IOException {
BufferedImage bi = ImageIO.read(new File("feld.jpg"));
g2 = bi.createGraphics();
g2.setPaint(Color.red);

label = new JLabel(new ImageIcon(bi));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(label, "West");

f.pack();
f.setVisible(true);
}

dein bild auf dem du da herumpinselst ist diese BufferedImage bi
Es ist im JLabel label
label wiederum befindet sich in einem JFrame f
und das JFrame f wird völlig unabhängig von zahlen_GUI in dem konstruktor erstellt und dargestellt

und was tust du?

du ruftst einfach so repaint() auf. Von der zahlen_GUI klasse, die nicht einmal sichtbar ist... Was glaubst du wieviel der Label label von dieser aktion mitbekommt? richtig: gar nix...


Also: schmeiss diese ganzen bescheuerten JLabels und Panels und zusätzliche Frames einfach mal aus der kette raus, die machen einfach keinen sinn.


so sollte es aussehen (Klassennamen schreibt man übrigens GROß):
Code:
public class Zahlen_GUI extends JPanel implements BlahBlahListener{

    //DAS BILD IST NUR ALS HÜBSCHER HINTERGRUND, NICHT FÜR DIE LOGIK!!!
    private BufferedImage background;

    public Zahlen_GUI(){
        super();
        background=...//laden usw usw, das ist alles mehr oder weniger okay 
        
    }

    public void paint(Graphics g){
        g.drawImage(background,0,0,getWidth(),getHeight(),this);

        for(alleFelderDurchgehen){
            //LOGISCHEN zustand irgendwo sonst auslesen
            //dem zusatnd entsprechend das feld zeichnen
        }
    }
    
    public void mouseClicked(ActionEvent lalala){
        //NIX ZEICHNEN sondern nur den LOGISCHEN ZUSTAND DER FELDER ÄNDERN
        //fürs zeichnen ist schon das hier, und evtl ein paar hilfstfuktionen verantwortlich:
        repaint(); 
    }

    public static void main(String[] args){
        JFrame f=new JFrame("...");

        ...
        f.getContentPane().add(new Zahlen_GUI);
    }
}

auf diese art und weise strukturiert dürfte es 1) funktionieren 2) halbwegst vernünftigen code aufbau aufweisen 3)leicht in applet umzuwandeln sein

good luck have fun...
 
G

Guest

Gast
Nein, so funktioniert´s leider nicht:

Exception in thread "main" java.lang.IllegalArgumentException: adding a window to a container
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at zahlen_GUI.main(zahlen_GUI.java:120)
 

0x7F800000

Top Contributor
ich weiß nicht was du da angestellt hast, in meinem code war Zahlen_GUI noch ein JPanel... Keine ahnung, vielleicht hast du während des umkrempel-vorgangs vergessen "JFrame" durch "JPanel" bzw "JComponent" zu ersetzen? ich bin mir relativ sicher dass mein code funktionieren dürfte...
 
G

Guest

Gast
Also ich hab´s nochmal überarbeitet. Der Fehler ist jetzt weg, allerdings wird das Hintergrund-JPG nicht angezeigt.

Hier ist der Code:

Code:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

import javax.imageio.ImageIO;
import javax.swing.*;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;


public class zahlen_GUI extends JPanel implements MouseListener {

	private static BufferedImage image;
	static Graphics2D g2;

		zahlen_GUI() throws IOException {
			super();
	    	BufferedImage bi = ImageIO.read(new File("feld.jpg"));
		    g2 = bi.createGraphics();
		}


	    synchronized public void mouseClicked(MouseEvent e){
	    	System.out.println("Mouseklick");
	    }
	    
	    public void paint(Graphics2D g) {
	    	g.drawImage(image,0,0,getWidth(),getHeight(),this);
	    }
	    
		/**
	    leere Implementierung (nur aus formalen Gründen vorhanden)
	    */
	    public void mouseEntered(MouseEvent e){
	    }
	    public void mouseExited(MouseEvent e){
	    }
	    public void mousePressed(MouseEvent e){
	    }
	    public void mouseReleased(MouseEvent e){
	    }
	    
	    public static void main(String[] args) throws IOException {
	    	JFrame f=new JFrame("...");
	    	zahlen_GUI GUI = new zahlen_GUI();
	    	f.getContentPane().add(GUI);
	    	f.pack();
	    	f.setVisible(true);
	    	
	    }
}


Wie würde man nun einen Mouselistener für die Klicks auf dem Hintergrund-JPG erstellen (wenn es mal angezeigt wird)?

Gruß
Alex
 
G

Guest

Gast
ok, der Mouselistener funktioniert. Nur noch das Anzeigen des jpg funktioniert nicht.
 

0x7F800000

Top Contributor
von dem Thread, der die ganzen graphischen sachen zeichnet wird die methode
Code:
public void paint(Graphics g){
...
}
erwartet, mit deiner
Code:
public void paint(Graphics2D g){
...
}
kann er nichts anfangen
 
G

Guest

Gast
auch dann wird kein jpg gezeichnet. probiere doch mal diesen code aus:

Code:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

import javax.imageio.ImageIO;
import javax.swing.*;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;


public class test extends JPanel implements MouseListener {

   private static BufferedImage image;
   static Graphics2D g2;

      test() throws IOException {
         super();
          BufferedImage bi = ImageIO.read(new File("feld.jpg"));
          g2 = bi.createGraphics();
      }


       synchronized public void mouseClicked(MouseEvent e){
          System.out.println("Mouseklick");
       }
      
       public void paint(Graphics g) {
          g.drawImage(image,0,0,getWidth(),getHeight(),this);
          
       }
      
      /**
       leere Implementierung (nur aus formalen Gründen vorhanden)
       */
       public void mouseEntered(MouseEvent e){
       }
       public void mouseExited(MouseEvent e){
       }
       public void mousePressed(MouseEvent e){
       }
       public void mouseReleased(MouseEvent e){
       }
      
       public static void main(String[] args) throws IOException {
          JFrame f=new JFrame("...");
          test GUI = new test();
          
          
          f.getContentPane().add(GUI);
          f.pack();
          f.setVisible(true);
          
       }
 

0x7F800000

Top Contributor
rofl...

du hast schon in diesem kleinen codeabschnitt das totale chaos: die Ursache dafür dass es "nicht funktioniert" ist schlicht und einfach die, dass du zwei bilder hast: image bleibt immer null, und das versuchst du zu zeichnen, bi ist eine lokale variable im konstruktor, wird geladen und weggeworfen...

so läuft es definitiv:

Code:
import java.awt.*; 
import java.awt.image.BufferedImage; 
import java.io.*; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 


public class Test extends JPanel implements MouseListener { 

   private BufferedImage image; 
   static Graphics2D g2; 

      Test(){ 
    	  super(); 
    	  try{
    		  image = ImageIO.read(new File("Sonnenuntergang.jpg"));
    		  MediaTracker tracker=new MediaTracker(this);
    		  tracker.addImage(image, 0);
    		  tracker.waitForAll();
    		  System.out.println(image);
    		  g2 = (Graphics2D)(image.getGraphics()); 
    	  }catch (Exception e){
    		  System.out.println(e);
    	  }
          addMouseListener(this);
      } 


       synchronized public void mouseClicked(MouseEvent e){ 
          System.out.println("Mouseklick"); 
          repaint();
       } 
      
       public void paint(Graphics g){ 
          g.drawImage(image,0,0,getWidth(),getHeight(),this);
       }
      
      /** 
       leere Implementierung (nur aus formalen Gründen vorhanden) 
       */ 
       public void mouseEntered(MouseEvent e){ 
       } 
       public void mouseExited(MouseEvent e){ 
       } 
       public void mousePressed(MouseEvent e){ 
       } 
       public void mouseReleased(MouseEvent e){ 
       } 
      
       public static void main(String[] args){ 
          JFrame f=new JFrame("..."); 
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          f.setSize(800,600);
          Test GUI = new Test(); 
          f.getContentPane().add(GUI);
          f.setVisible(true); 
          
       }
}
dateinamen halt beliebig ändern, habe jetzt dieses Beispielbild von Windows XP in den Projektordner gepackt...[/b]
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M JPanel mit Graphics2D Objekten mit JScrollpane Spiele- und Multimedia-Programmierung 6
H Screenshot einer Graphics2D Anwendung erstellen Spiele- und Multimedia-Programmierung 6
S Graphics2D Oval vs. Rect -Performance Spiele- und Multimedia-Programmierung 17
X Polygon in Graphics2D löschen Spiele- und Multimedia-Programmierung 4
S Graphics.drawString (Graphics2D.drawString) Y-Problem Spiele- und Multimedia-Programmierung 4
M Graphics2D problem Spiele- und Multimedia-Programmierung 5
V Graphics oder Graphics2D Zeichenfunktion gesucht? Spiele- und Multimedia-Programmierung 4
H Größenänderung von Graphics2D Strings bzw Fonts Spiele- und Multimedia-Programmierung 2
G Paint mit Graphics2D? Spiele- und Multimedia-Programmierung 8
B JAVA Graphics2D Problem das mich in den Wahnsinn treibt Spiele- und Multimedia-Programmierung 3
B Keine Graphics2D Klasse unter J# .Net??? Spiele- und Multimedia-Programmierung 6
S Repaint flackert!!! Spiele- und Multimedia-Programmierung 1
K Flackern bei repaint Methode Spiele- und Multimedia-Programmierung 3
Y Problem mit repaint() in run() Spiele- und Multimedia-Programmierung 2
B Bilder in GUI ändern ohne repaint() Spiele- und Multimedia-Programmierung 6
M Scrolling Repaint Problem Spiele- und Multimedia-Programmierung 2
H Repaint-Problem mit Quaxlis Tutorial Spiele- und Multimedia-Programmierung 2
Steev Eigene Repaint-Logik Spiele- und Multimedia-Programmierung 17
S Animation mit repaint Spiele- und Multimedia-Programmierung 2
F Repaint Problem Spiele- und Multimedia-Programmierung 6
M repaint() ruckelt Spiele- und Multimedia-Programmierung 11
R Update und repaint() im ActionListener Spiele- und Multimedia-Programmierung 3
P repaint verschiebt das Bild Spiele- und Multimedia-Programmierung 2
C repaint und tempo Spiele- und Multimedia-Programmierung 4

Ähnliche Java Themen

Neue Themen


Oben