Habe mich jetzt durch viele Threads gelesen. Ich habe bisher immer mit getGraphics gearbeitet, so, wie mans gelernt hat. es gab immer fehler (nullpointer), aber irgendwann hats irgendwie doch funktioniert. aber ich möchte, dass es in zukunft immer geht, ohne probleme.
wenn ich mache
Graphics g=l.getGraphics() ( jetzt werde ich nämlich wahrscheinlich schon gelüncht)
dann krieg ich bei zb g.drawXY(a,b,c,d) eine nullpointerexception.
Code:
JLayeredPane f=new JLayeredPane()
{
private static final long serialVersionUID = 1L;
protected void paintComponent(final Graphics g)
{
super.paintComponent(g);
zeichneBrett(); // oder zeichneBrett(g); ?? <<<<
}
};
///
public void zeichneBrett()
{
Graphics g=f.getGraphics();
g.drawString("TEST", 50, 50);
}
wie mache ich das richtig? habe die paintComponent Methode von f überschrieben, so, wie ich das machen sollte, aber es geht immer nocht nicht ??
an welche "einzelnen objekte" ? ja, so wie du das erklärt hast gerade, hatte ich das auch schon, aber da passiert einfach gar nichts. und was, wenn ich erst im laufe der zeit das "TEST" zeichnen will? dann würde ich jetzt die methode zeichneBrett übergeben, aber wo krieg ich das graphics objekt her zum übergeben, wenn nicht mit der methode getGraphics ?
sorry für doppelpost, bin gerade nicht angemeldet (muss mir gleich mal mein passwort neu schicken lassen ;-) )
also, dass nichts passiert, stimmt nicht, hatte nur was vergessen. soweit geht das jetzt, danke. aber was mach ich, wenn ich die methode zeichneBrett erst später aufrufen will ?
an alle Objekte, die anzeigt werden sollen,
JPanel, JButton usw.,
etwas unglückliche Formulierung, stimmt, da du ja gar kein Unterobjekt hast
> was, wenn ich erst im laufe der zeit das "TEST" zeichnen will?
überall, wo du deine Zeichenoperation + getGraphics() aufrufen würdest,
schreibe repaint() hin
macht nur richtig Sinn bei einer Top-Komponente wie JFrame,
dort musst du auch das JLayeredPane einfügen
überhaupt gibts da zig Dinge zu beachten, bis das Zeichnen ordentlich funktioniert,
poste ein vollständiges Programm was nicht geht, dann kann man es evtl. korrigieren
Du speicherst dir die Informationen, die du brauchst, um das zu zeichnen, was du zeichnen willst. In der paintComponent holst du dir dann diese Informationen und zeichnest.
- traurig, aber wahr! in diversen tutorials !! hab auch von vielen anderen gelesen, dass die das irgendwo gelernt und gelesen haben - und die haben die selben probleme gehabt ^^
hm hat folgendes geschrieben::
aber was mach ich, wenn ich die methode zeichneBrett erst später aufrufen will ?
Du speicherst dir die Informationen, die du brauchst, um das zu zeichnen, was du zeichnen willst. In der paintComponent holst du dir dann diese Informationen und zeichnest.[\quote]
ja, so habe ich das bis jetzt auch gemacht. aber dumm nur, wenn ich zb einen apfel oder eine schachfigur bewegen will, muss ich dann tausend mal alles neu zeichnen, wenn man eine bewegung sehen will. ansonsten gehts immer nur ganz ruckartig und auch da sieht man bei vielen objekten dann, wie es einmal kurz flackert :-(
- also probleme hab ich noch mit der schachfigur, die wird übermalt und ist dann weg. falls jemand schneller eine lösung dafür hat als ich, bin ich dankbar ;-) ansonsten hätte ich nur noch das problem, wie ich jetzt eine schachfigur versetzten soll. ich würde jetzt eine methode machen, die die gesamte brettkonstellation neu zeichnet und die in protected void paintComponent(final Graphics g) mit reinnehmen und dann repaint aufrufen.
falls es besser geht, bescheid sagen ;-)
also hier mal mein code (ist ja noch nicht soviel zum glück )
Code:
package gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
public class feldGUI extends Frame{
JLayeredPane f=new JLayeredPane()
{
private static final long serialVersionUID = 1L;
protected void paintComponent(final Graphics g)
{
super.paintComponent(g);
zeichneBrett(g);
//maleFigur("bauerS.png", 3,4); << dann flackerts wie doof
}
};
JLayeredPane control=new JLayeredPane();
JLabel koord=new JLabel("koords");
feldGUI()
{
setLayout(new BorderLayout());
control.setLayout(new FlowLayout(1,10,10));
add(f, BorderLayout.CENTER);
add(control, BorderLayout.SOUTH);
control.add(koord);
setVisible(true);
setSize(600,600);
setLocation(100,100);
setTitle("Schach-KI 1.0");
validate();
f.addMouseListener(new fmauslis());
f.addMouseMotionListener(new fmausbewlis());
}
class fmausbewlis implements MouseMotionListener
{
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseMoved(MouseEvent e) {
int x=e.getX()/(f.getWidth()/8);
int y=e.getY()/(f.getHeight()/8);
if(x>7||y>7)
{
koord.setText("aus");
}
else
{
koord.setText("x,y: "+(x+1)+";"+(y+1));
}
}
}
class fmauslis implements MouseListener
{
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
public void zeichneBrett(Graphics g)
{
//Graphics g=f.getGraphics();
int h=f.getHeight();
int b=f.getWidth();
int hx=0;
int bx=0;
//g.drawString("TEST", 50, 50);
Color grau=new Color(115,129,176);
Color weiß=new Color(231,231,239);
for(int x=0;x<8;x++)
{
for(int y=0;y<8;y++)
{
if((x%2==0&&y%2==0) || (x%2==1&&y%2==1) )
{
g.setColor(grau);
g.fillRect(bx, hx, b/8, h/8);
}
else
{
g.setColor(weiß);
g.fillRect(bx, hx, b/8, h/8);
}
hx+=h/8;
//System.out.println("bin bei: "+x+";"+y+" koord: bx:"+bx+" hx: "+hx);
}
bx+=b/8;
hx=0;
}
}
public void maleFigur(String pfad, int xpos, int ypos)
{
Image img=f.getToolkit().getImage(pfad);
Image scaliert=img.getScaledInstance(f.getWidth()/8, f.getHeight()/8, 1);
Graphics g=f.getGraphics();
int x= xpos*(f.getWidth()/8);
int y= ypos*(f.getHeight()/8);
g.drawImage(scaliert, x, y, Color.WHITE, f);
//System.out.println("Male nach: "+x+";"+y);
}
public static void main(String[]s)
{
feldGUI fg=new feldGUI();
fg.maleFigur("bauerS.png", 4, 5); // das geht noch nicht ?? :-( wird übermalt!!
//fg.zeichneBrett();
}
}
Nun. Wenn sich etwas bewegt, muss man neu zeichnen. Und wenn dann etwas flackert, hat man etwas falsch gemacht. Zu dem Code:
Klassennamen schreibt man GROSS, Variablennamen klein. Die Namen sollten aber sprechend sein: Bei einer Variable 'f' in der Klasse weiß niemand, was das ist. ("F" wie "JLayeredPane" - sehr originell :wink: ). Ansonsten ist die Klassenstruktur nicht so toll. Im Moment bist du wohl noch am expermimentieren, aber wenn das mit dem Zeichnen erstmal grundsätzlich klappt, solltest du dir erst ein Konzept überlegen, becor du weitermachst. (Vielleicht eine Klasse "Spielfeld", und eine Klasse "Figur" - beide mit Methoden "zeichneMichAuf(Graphics g)"...)
Hier mal der Code, mit einigen geänderten Stellen und Kommentaren - die sind mit "XXX" markiert.
Code:
import java.awt.*;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
import javax.swing.JLayeredPane;
public class feldGUI extends Frame{
JLayeredPane f=new JLayeredPane()
{
private static final long serialVersionUID = 1L;
protected void paintComponent(final Graphics g)
{
super.paintComponent(g);
zeichneBrett(g);
//maleFigur("bildA.gif", 3,4); // << dann flackerts wie doof
}
};
JLayeredPane control=new JLayeredPane();
JLabel koord=new JLabel("koords");
// XXX Nicht bei jedem neuzeichnen neu skalieren!
Image bauerSscaliert=null;
feldGUI()
{
setLayout(new BorderLayout());
control.setLayout(new FlowLayout(1,10,10));
add(f, BorderLayout.CENTER);
add(control, BorderLayout.SOUTH);
control.add(koord);
setSize(600,600);
setLocation(100,100);
setTitle("Schach-KI 1.0");
validate();
// XXX setVisible zuletzt machen
setVisible(true);
// XXX Bild EINMAL laden und skalieren (später nurnoch malen)
Image img= Toolkit.getDefaultToolkit().getImage("bauerS.png");
bauerSscaliert = img.getScaledInstance(f.getWidth()/8, f.getHeight()/8, 1);
f.addMouseListener(new fmauslis());
f.addMouseMotionListener(new fmausbewlis());
}
class fmausbewlis implements MouseMotionListener
{
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseMoved(MouseEvent e) {
int x=e.getX()/(f.getWidth()/8);
int y=e.getY()/(f.getHeight()/8);
if(x>7||y>7)
{
koord.setText("aus");
}
else
{
koord.setText("x,y: "+(x+1)+";"+(y+1));
}
}
}
class fmauslis implements MouseListener
{
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
public void zeichneBrett(Graphics g)
{
//Graphics g=f.getGraphics();
int h=f.getHeight();
int b=f.getWidth();
int hx=0;
int bx=0;
//g.drawString("TEST", 50, 50);
Color grau=new Color(115,129,176);
Color weiß=new Color(231,231,239);
for(int x=0;x<8;x++)
{
for(int y=0;y<8;y++)
{
if((x%2==0&&y%2==0) || (x%2==1&&y%2==1) )
{
g.setColor(grau);
g.fillRect(bx, hx, b/8, h/8);
}
else
{
g.setColor(weiß);
g.fillRect(bx, hx, b/8, h/8);
}
hx+=h/8;
//System.out.println("bin bei: "+x+";"+y+" koord: bx:"+bx+" hx: "+hx);
}
bx+=b/8;
hx=0;
}
// XXX Hier wird die Figur gemalt
maleFigur(g, 3,3);
}
// XXX hier wird nurnoch gemalt!!!
public void maleFigur(Graphics g, int xpos, int ypos)
{
int x= xpos*(f.getWidth()/8);
int y= ypos*(f.getHeight()/8);
g.drawImage(bauerSscaliert, x, y, Color.WHITE, f);
//System.out.println("Male nach: "+x+";"+y);
}
public static void main(String[]s)
{
feldGUI fg=new feldGUI();
//fg.maleFigur("bildA.gif", 4, 5); // das geht noch nicht ?? :-( wird übermalt!!
//fg.zeichneBrett();
}
}
Nochmal: Das ist nicht schön. Du solltest dir wirklich eine geeignete Struktur für das ganze überlegen.
<edit>
Das sollte eins höher stellen. Marco 13 war mit seiner Antwort etwas schneller.
</edit>
Hmpf. Da weiß man ja gar nicht wo man anfangen soll. :bahnhof:
Ich fange mal mit 'ner Liste an, was mir so auf Anhieb auffällt
- Mischung von light- und heavyweight Komponenten (Frame/JLayeredPane) kann Ärger geben
- ich weiß nicht was diese JLayeredPane hier soll (JPanel ist besser und doppel gepuffert)
- die folgende Methode ist auch übel:
Code:
public void maleFigur(String pfad, int xpos, int ypos) {
Image img = f.getToolkit().getImage(pfad);
Image scaliert = img.getScaledInstance(f.getWidth() / 8, f.getHeight() / 8,
1);
Graphics g = f.getGraphics();
int x = xpos * (f.getWidth() / 8);
int y = ypos * (f.getHeight() / 8);
g.drawImage(scaliert, x, y, Color.WHITE, f);
//System.out.println("Male nach: "+x+";"+y);
}
Da wird bei jedem Malen das Bild noch geladen. Außerdem funzt das nicht, wenn Du's mal in eine jar packen willst
- man kann das Programm nicht beenden. Ich durfte es über den TaskManager abschießen.
Den "Kollegen" hier fällt bestimmt auch noch einiges auf. Wenn das aus einem Tutorial ist, dann aus einem, wie man's nicht machen sollte.
Mein Rat: Lies Dich noch mal ein, wie man's richtig macht. :### Stichworte: Grafiken laden und animieren, etc.. Zu kurzen Codestrecken, sagt Dir jeder hier, ob das so gut ist oder ob man es besser machen könnte. Das Programm, daß Du gepostet hast, sollte man meiner Ansicht nach komplett neu schreiben. Das ist einfacher, als da wild drin rum zu korrigieren.
Mit dem Teil wirst Du auf Dauer nicht glücklich. Und wenn Du ständig dran rumverbessern mußt, bzw. ständig nachfragen mußt geht auch der ganze Spaß an der Programmierung verloren.