Das letzte Mal, dass ich JFrame / Canvas verwendet habe, war mein Universitätsabschluss. Nach langer Zeit mit Java ist es schwer zu hören, was ich sage ...: Schweißtropfen:
Ich vergesse also, wie man Java benutzt
Ich möchte über JFrame / Canvas als Memorandum anstatt über Rehabilitation schreiben: writing_hand:
Ich möchte eine einfache Zeichen-App mit der Jframe / Canvas-Klasse erstellen.
Das fertige Produkt sieht aus wie auf dem Bild. : Kunst:
Zuerst erstellen wir ein Fenster, in dem die App angezeigt wird. Hier wird JFrame verwendet. Wie man es benutzt ist so.
Step1.java
package paintApp;
import javax.swing.JFrame;
public class Step1 {
static int w = 800, h = 600;
public static void main(String[] args) {
run();
}
public static void run() {
//Erstellen Sie eine Instanz von JFrame
JFrame frame = new JFrame("Zeichen App");
//Beenden Sie das Programm, wenn das Fenster geschlossen ist
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Fenstergröße / Ausgangsposition
frame.setSize(w, h);
frame.setLocationRelativeTo(null);
// setBounds(x, y, w, h);
//Schaufenster
frame.setVisible(true);
}
}
Ich könnte leicht einen Rahmen machen: v:
Bereiten Sie als Nächstes eine Leinwand vor, um tatsächlich ein Bild zu zeichnen. Java bietet eine praktische Klasse namens Canvas. Fügen wir es dem Rahmen hinzu.
Step2.java
package paintApp;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Step2 {
static int w = 800, h = 600;
public static void main(String[] args) {
run();
}
public static void run() {
//Erstellen Sie eine Instanz von JFrame
JFrame frame = new JFrame("Zeichen App");
//Beenden Sie das Programm, wenn das Fenster geschlossen ist
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Fenstergröße / Ausgangsposition
frame.setSize(w, h);
frame.setLocationRelativeTo(null);
// setBounds(x, y, w, h);
//Erstellen Sie eine Instanz von PaintCanvas
PaintCanvas canvas = new PaintCanvas();
//Zum Rahmen hinzufügen
JPanel pane = new JPanel();
frame.getContentPane().add(pane);
canvas.setPreferredSize(new Dimension(w, h));
pane.add(canvas);
//Schaufenster
frame.setVisible(true);
}
//Canvas-Klasse
static class PaintCanvas extends Canvas {
public PaintCanvas() {
//Stellen Sie den Leinwandhintergrund auf Weiß ein
setBackground(Color.white);
}
public void paint(Graphics g) {
}
}
}
Eine rein weiße Leinwand ist erschienen.
Lassen Sie uns hier ein Bild zeichnen.
Ereignisse wie "Mausklick" oder "Ziehen" werden als "Ereignisse" bezeichnet.
Es gibt eine praktische Klasse, mit der Sie dieses Ereignis erhalten können.
MouseListener und MouseMotionListener /jp/8/docs/api/java/awt/event/MouseMotionListener.html).
Der Unterschied zwischen MouseListener und MouseMotionListener besteht in der Art der Ereignisse, die Sie erhalten können.
Verwenden wir es entsprechend der Art des Ereignisses, das Sie verwenden möchten.
Dieses Mal möchte ich klicken, ziehen und verschieben, also werde ich beide verwenden.
** Events die du bekommen kannst **
MouseListener | MouseMotionListener |
---|---|
mouseClicked | mouseDragged |
mouseEntered | mouseDragged |
mouseExited | |
mousePressed | |
mouseReleased |
Fügen wir diese der Leinwand hinzu.
Step3.java
package paintApp;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Step3 {
static int w = 800, h = 600;
public static void main(String[] args) {
run();
}
public static void run() {
//Erstellen Sie eine Instanz von JFrame
JFrame frame = new JFrame("Zeichen App");
//Beenden Sie das Programm, wenn das Fenster geschlossen ist
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Fenstergröße / Ausgangsposition
frame.setSize(w, h);
frame.setLocationRelativeTo(null);
// setBounds(x, y, w, h);
//Erstellen Sie eine Instanz von PaintCanvas
PaintCanvas canvas = new PaintCanvas();
//Zum Rahmen hinzufügen
JPanel pane = new JPanel();
frame.getContentPane().add(pane);
canvas.setPreferredSize(new Dimension(w, h));
pane.add(canvas);
//Schaufenster
frame.setVisible(true);
}
//Canvas-Klasse
static class PaintCanvas extends Canvas implements MouseListener,
MouseMotionListener {
public PaintCanvas() {
//Stellen Sie MouseListener / MouseMotionListener ein
addMouseListener(this);
addMouseMotionListener(this);
//Stellen Sie den Leinwandhintergrund auf Weiß ein
setBackground(Color.white);
}
public void paint(Graphics g) {
}
@Override
public void mouseDragged(MouseEvent e) {
System.out.println(e);
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
}
Auf diese Weise können Sie sehen, dass es auf Mausoperationen reagiert. : mouse_three_button:
… Die Bühne ist jetzt bereit. Von hier aus erstellen wir einen Prozess zum Zeichnen eines Bildes mit dem erfassten Mausereignis.
Der Inhalt erhält beim Ziehen mit der Maus die Koordinaten des Start- und Endpunkts und verbindet sie mit einer Linie ... Das war's: ok_hand:
Speichern Sie die Mauskoordinaten zu diesem Zeitpunkt in einer Variablen, um das Ereignis MouseDragged etwas detaillierter zu erläutern. Wenn dasselbe Ereignis erneut auftritt, werden die im vorherigen Prozess gespeicherten Koordinaten in einer anderen Variablen als Ausgangspunkt gespeichert, wobei die aktuellen Koordinaten überschrieben werden. Auf diese Weise zeichne ich eine Linie, während ich den Start- und Endpunkt aktualisiere.
Jedes Mal, wenn die Maus gezogen wird, wächst die Linie nach und nach und es sieht so aus, als würde die Flugbahn der Maus so angezeigt, wie sie ist.
Übrigens wird beim Zeichnen dieser Linie der Stil jeder Linie an beiden Enden auf "rund" gesetzt. Wenn Sie dies nicht tun, sind beide Enden quadratische Linien, und die Fugen zwischen den Linien sind gezackt, was zu einem unattraktiven Bild führt.
Step4.java
package paintApp;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Step4 {
static int w = 800, h = 600;
public static void main(String[] args) {
run();
}
public static void run() {
//Erstellen Sie eine Instanz von JFrame
JFrame frame = new JFrame("Zeichen App");
//Beenden Sie das Programm, wenn das Fenster geschlossen ist
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Fenstergröße / Ausgangsposition
frame.setSize(w, h);
frame.setLocationRelativeTo(null);
// setBounds(x, y, w, h);
//Erstellen Sie eine Instanz von PaintCanvas
PaintCanvas canvas = new PaintCanvas();
//Zum Rahmen hinzufügen
JPanel pane = new JPanel();
frame.getContentPane().add(pane);
canvas.setPreferredSize(new Dimension(w, h));
pane.add(canvas);
//Schaufenster
frame.setVisible(true);
}
//Canvas-Klasse
static class PaintCanvas extends Canvas implements MouseListener,
MouseMotionListener {
//BufferedImage, das den Zeichnungsinhalt enthält
private BufferedImage cImage = null;
//Instanz zum Zeichnen auf cImage
private Graphics2D g2d;
//Linienstart- und Endkoordinaten
private int x, y, xx, yy;
//Zeichenmodus ODER Radiergummimodus
private int type;
//Dicke der Linie
public int width = 1;
//Linienfarbe
public Color c = Color.black;
public PaintCanvas() {
//Koordinaten initialisieren
x = -1;
y = -1;
xx = -1;
yy = -1;
type = 0;
//Stellen Sie MouseListener / MouseMotionListener ein
addMouseListener(this);
addMouseMotionListener(this);
//Stellen Sie den Leinwandhintergrund auf Weiß ein
setBackground(Color.white);
//Generieren Sie ein BufferedImage, das den Zeichnungsinhalt enthält
cImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) cImage.getGraphics();
//Machen Sie den Hintergrund von BufferedImage weiß
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
//Zeichnung
repaint();
}
public void paint(Graphics g) {
//Zeichenmodus (Zeichnen einer Linie)
if (type == 1) {
if (x >= 0 && y >= 0 && xx >= 0 && yy >= 0) {
BasicStroke stroke = new BasicStroke(width,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2d.setStroke(stroke);
g2d.setColor(c);
g2d.drawLine(xx, yy, x, y);
}
//Radiergummi-Modus
} else if (type == 2) {
if (x >= 0 && y >= 0 && xx >= 0 && yy >= 0) {
//Stellen Sie eine Linie mit abgerundeten Enden ein
BasicStroke stroke = new BasicStroke(50.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2d.setStroke(stroke);
g2d.setColor(Color.white);
g2d.drawLine(xx, yy, x, y);
}
}
//Reflektieren Sie den Zeichnungsinhalt auf der Leinwand
g.drawImage(cImage, 0, 0, null);
}
@Override
public void mouseDragged(MouseEvent e) {
//Erkennt, dass die Taste gedrückt wird
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
//Klicken mit der linken Maustaste (Zeichenmodus)
type = 1;
}
if ((e.getModifiers() & MouseEvent.BUTTON2_MASK) != 0) {
//Klicken Sie auf die mittlere Schaltfläche
}
if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0) {
//Rechtsklick (Löschmodus)
type = 2;
}
//Legen Sie vergangene Koordinaten als Startkoordinaten fest
xx = x;
yy = y;
//Legen Sie neue Koordinaten als Endkoordinaten fest
Point point = e.getPoint();
x = point.x;
y = point.y;
//neu zeichnen
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
//Initialisieren Sie die Koordinaten, wenn das Ziehen abgeschlossen ist
x = -1;
y = -1;
xx = -1;
yy = -1;
type = 0;
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
Point point = e.getPoint();
x = point.x;
y = point.y;
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
}
Ziehen Sie mit der Maus, um dort eine Linie zu zeichnen.
Es wurde sofort so!
Die Zeichen-App wurde fertiggestellt!
Im Bild wurden drei Funktionen hinzugefügt: Leinwand löschen, Linienstärke ändern und Linienfarbe ändern. Das allein reicht zum Zeichnen.
Dies ist eine vereinfachte Version. Wenn Sie hier Funktionen hinzufügen, können Sie sie zu einer authentischeren Zeichen-App machen: smiley: Der endgültige Code ist hier.
PaintApp.java
package paintApp;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class PaintApp {
static int w = 800, h = 600;
public static void main(String[] args) {
run();
}
public static void run() {
//Erstellen Sie eine Instanz von JFrame
JFrame frame = new JFrame("Zeichen App");
//Beenden Sie das Programm, wenn das Fenster geschlossen ist
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Fenstergröße / Ausgangsposition
frame.setSize(w, h);
frame.setLocationRelativeTo(null);
// setBounds(x, y, w, h);
//Erstellen Sie eine Instanz von PaintCanvas
PaintCanvas canvas = new PaintCanvas();
//Zum Rahmen hinzufügen
JPanel pane = new JPanel();
frame.getContentPane().add(pane, BorderLayout.CENTER);
JPanel paneB = new JPanel();
frame.getContentPane().add(paneB, BorderLayout.NORTH);
canvas.setPreferredSize(new Dimension(w, h));
pane.add(canvas);
/*Zusatzfunktionen*/
//Alles löschen
JButton clear = new JButton("CLEAR");
clear.addActionListener(new ClearListener(canvas));
paneB.add(clear);
//Anpassen der Linienstärke
JSlider slider = new JSlider(1, 50, 1); //Minimalwert, Maximalwert, Anfangswert
slider.addChangeListener(new SliderListener(canvas)); //Zur Interrupt-Verarbeitung
paneB.add(slider);
//Änderung der Linienfarbe
String[] combodata = { "BLACK", "RED", "BLUE", "GREEN" };
JComboBox combo = new JComboBox(combodata);
combo.addActionListener(new ComboListener(canvas));
paneB.add(combo);
//Schaufenster
frame.setVisible(true);
}
//Canvas-Klasse
static class PaintCanvas extends Canvas implements MouseListener,
MouseMotionListener {
//BufferedImage, das den Zeichnungsinhalt enthält
private BufferedImage cImage = null;
//Instanz zum Zeichnen auf cImage
private Graphics2D g2d;
//Linienstart- und Endkoordinaten
private int x, y, xx, yy;
//Zeichenmodus ODER Radiergummimodus
private int type;
//Dicke der Linie
public int width = 1;
//Linienfarbe
public Color c = Color.black;
public PaintCanvas() {
//Koordinaten initialisieren
x = -1;
y = -1;
xx = -1;
yy = -1;
type = 0;
//Stellen Sie MouseListener / MouseMotionListener ein
addMouseListener(this);
addMouseMotionListener(this);
//Stellen Sie den Leinwandhintergrund auf Weiß ein
setBackground(Color.white);
//Generieren Sie ein BufferedImage, das den Zeichnungsinhalt enthält
cImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) cImage.getGraphics();
//Machen Sie den Hintergrund von BufferedImage weiß
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
//Zeichnung
repaint();
}
//Löschen Sie die Leinwand
public void clear() {
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
repaint();
}
//Liniendicke ändern
public void setStroke(int n) {
width = n;
}
//Änderung der Linienfarbe
public void setColorCombo(String color) {
if (color.equals("BLACK")) {
c = Color.black;
} else if (color.equals("RED")) {
c = Color.red;
} else if (color.equals("BLUE")) {
c = Color.blue;
} else if (color.equals("GREEN")) {
c = Color.green;
}
}
public void paint(Graphics g) {
//Zeichenmodus (Zeichnen einer Linie)
if (type == 1) {
if (x >= 0 && y >= 0 && xx >= 0 && yy >= 0) {
BasicStroke stroke = new BasicStroke(width,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2d.setStroke(stroke);
g2d.setColor(c);
g2d.drawLine(xx, yy, x, y);
}
//Radiergummi-Modus
} else if (type == 2) {
if (x >= 0 && y >= 0 && xx >= 0 && yy >= 0) {
//Stellen Sie eine Linie mit abgerundeten Enden ein
BasicStroke stroke = new BasicStroke(50.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2d.setStroke(stroke);
g2d.setColor(Color.white);
g2d.drawLine(xx, yy, x, y);
}
}
//Reflektieren Sie den Zeichnungsinhalt auf der Leinwand
g.drawImage(cImage, 0, 0, null);
}
@Override
public void mouseDragged(MouseEvent e) {
//Erkennt, dass die Taste gedrückt wird
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
//Klicken mit der linken Maustaste (Zeichenmodus)
type = 1;
}
if ((e.getModifiers() & MouseEvent.BUTTON2_MASK) != 0) {
//Klicken Sie auf die mittlere Schaltfläche
}
if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0) {
//Rechtsklick (Löschmodus)
type = 2;
}
//Legen Sie vergangene Koordinaten als Startkoordinaten fest
xx = x;
yy = y;
//Legen Sie neue Koordinaten als Endkoordinaten fest
Point point = e.getPoint();
x = point.x;
y = point.y;
//neu zeichnen
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
//Initialisieren Sie die Koordinaten, wenn das Ziehen abgeschlossen ist
x = -1;
y = -1;
xx = -1;
yy = -1;
type = 0;
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
Point point = e.getPoint();
x = point.x;
y = point.y;
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
//Zum Löschen der Taste
static class ClearListener implements ActionListener {
PaintCanvas canvas;
public ClearListener(PaintCanvas canvas) {
super();
this.canvas = canvas;
}
@Override
public void actionPerformed(ActionEvent e) {
canvas.clear();
}
}
//Für Schieberegler
static class SliderListener implements ChangeListener {
PaintCanvas canvas;
public SliderListener(PaintCanvas canvas) {
super();
this.canvas = canvas;
}
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
int fps = (int) source.getValue();
canvas.setStroke(fps);
}
}
//Für Kombinationsfeld
static class ComboListener implements ActionListener {
PaintCanvas canvas;
public ComboListener(PaintCanvas canvas) {
super();
this.canvas = canvas;
}
@Override
public void actionPerformed(ActionEvent e) {
JComboBox source = (JComboBox) e.getSource();
String color = (String) source.getSelectedItem();
canvas.setColorCombo(color);
}
}
}
Vielen Dank für das Lesen bis zum Ende!
Recommended Posts