In vielen Beiträgen findet man die Möglichkeit auf JPanels mittels der Methode paintComponent zu zeichnen. Als Nachteil könnte sich hier herausstellen, dass ALLES in dieser Methode gezeichnet werden muss. Als eine Alternative, dies zu umgehen, wird die Verwendung eines BufferedImage genannt, welches dann zu gegebener Zeit (in PaintComponent) aufkopiert wird. Diesen Ansatz habe ich mal probiert umzusetzen, allerdings funktioniert es nicht richtig. Erst mal mein Ansatz:
... und ...
Nun meine Fragen:
Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.*;
public class PaintSWING extends JFrame {
// Anfang Attribute
private byte[][] myColorField = new byte[20][20];
private BufferedImage zeichenImage;
private MyCanvasPanel zeichenflaeche = new MyCanvasPanel(zeichenImage);
private JButton btnDraw = new JButton();
// Ende Attribute
public PaintSWING(String title) {
// Frame-Initialisierung
super(title);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 510;
int frameHeight = 572;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
zeichenflaeche.setBounds(7, 2, 500, 500);
zeichenflaeche.setBackground(Color.WHITE);
cp.add(zeichenflaeche);
// Initialisieren / Angleichen der Zeichenflächen
zeichenflaeche.init();
btnDraw.setBounds(424, 512, 75, 25);
btnDraw.setText("Draw");
btnDraw.setMargin(new Insets(2, 2, 2, 2));
btnDraw.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnDraw_ActionPerformed(evt);
}
});
cp.add(btnDraw);
// Ende Komponenten
setResizable(false);
setVisible(true);
zeichenflaeche.repaint();
}
// Anfang Methoden
public void btnDraw_ActionPerformed(ActionEvent evt) {
Graphics g = zeichenImage.getGraphics();
for (int x = 0; x < 19; x++) {
for (int y = 0; y < 19; y++) {
int ro = (int) Math.random()*255;
int ge = (int) Math.random()*255;
int bl = (int) Math.random()*255;
g.setColor(new Color(ro, ge, bl));
g.fillRect(x * 10, y * 10, 9, 9);
}
}
zeichenflaeche.repaint();
}
// Ende Methoden
public static void main(String[] args) {
new PaintSWING("Zeichnen in SWING");
}
}
... und ...
Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.*;
public class MyCanvasPanel extends JPanel {
private BufferedImage zeichenImage;
public MyCanvasPanel(BufferedImage zeichenImage) {
this.zeichenImage = zeichenImage;
}
public void init() {
zeichenImage = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration()
.createCompatibleImage(this.getWidth(),
this.getHeight());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(zeichenImage, 0, 0, this);
}
}
Nun meine Fragen:
- Der Zugriff scheint eigentlich zu funktionieren - nach dem Start erhalte ich ein schwarzes Bild. Dies müsste nach Durchlesen anderer Beiträge zu erwarten sein. Drücke ich jedoch auf den Button sehe ich keine Änderung
. Liegt es am Zeichnen oder am Zugriff auf das Image beim Kopieren?
- Muss ich eigentlich die beiden Images (in den jeweiligen Methoden) angleichen, aslo die Methode init() verwenden? Sieht für mich ein bisschen komisch aus, ohne wirklich zu erkennen warum.
- Weshalb benötige ich hier eigentlich das @Override? Zum Überschreiben brauiche ich das sonst eigentlich nie ...