kleines Zeichenprogramm

Status
Nicht offen für weitere Antworten.

jobu0101

Bekanntes Mitglied
Ich habe versucht mal selbst ei kleines Zeichenprogramm zu programmieren. Das kann jetzt noch nichts außer in einer Farbe was malen. Auch wenn man das Fenster minimiert und dann wieder maximiert, ist alles weg!
Doch das soll mich erstmal nicht stören, habe nämlich ein ganz anderes Problem: Wenn ich die Maus zu schnell bewege, dann zeichnet er nicht durchgänige Linien, sondern nur Punkte, weil es für ihn eben halt zu schnell ist! In Programmen wie Paint, ist das nicht der Fall, ist zwar auch in einer schnelleren Programmiersprache geschrieben, doch meine Frage ist nun, ob sowas auch in Java möglich ist.

Hier mal mein Programmcode:

Code:
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;

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

public class test03 extends JPanel {
	static int x, y;

	static boolean zeichne = false;

	static test03 gpanel = new test03();;

	protected void paintComponent(Graphics g) {
		int breite = gpanel.getWidth();
		int hoch = gpanel.getHeight();
		Shape wrechteck = new Rectangle2D.Double(0, 0, breite, hoch);
		Shape pinsel = new Arc2D.Double(x - 5, y - 5, 10, 10, 0, 360, Arc2D.PIE);

		if (zeichne == false) {
			g.setColor(Color.WHITE);
			((Graphics2D) g).fill(wrechteck);
		} else {
			zeichne = false;
			g.setColor(Color.BLACK);
			((Graphics2D) g).fill(pinsel);
		}
	}

	public static void main(String args[]) {

		JFrame f = new JFrame("Malprogramm");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(300, 300);
		Container con = f.getContentPane();
		con.setLayout(new GridLayout(0, 1, 0, 0));
		con.add(gpanel);
		f.setVisible(true);
		gpanel.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent arg0) {
				zeichne = true;
				x = arg0.getX();
				y = arg0.getY();
				gpanel.repaint();
			}
		});
		gpanel.addMouseMotionListener(new MouseMotionListener() {
			public void mouseDragged(MouseEvent arg0) {
				zeichne = true;
				x = arg0.getX();
				y = arg0.getY();
				gpanel.repaint();
			}

			public void mouseMoved(MouseEvent arg0) {
			}
		});
	}
}
 
R

Roar

Gast
jobu0101 hat gesagt.:
In Programmen wie Paint, ist das nicht der Fall, ist zwar auch in einer schnelleren Programmiersprache geschrieben, doch meine Frage ist nun, ob sowas auch in Java möglich ist.
lol der is gut :) das hat nix damit zu tun dass manche glauben ein c++ programm sei schneller als ein java programm, sondern damit, dass die programmierer es richtig programmiert haben ;)
:gaen: :)
 

jobu0101

Bekanntes Mitglied
Roar hat gesagt.:
jobu0101 hat gesagt.:
In Programmen wie Paint, ist das nicht der Fall, ist zwar auch in einer schnelleren Programmiersprache geschrieben, doch meine Frage ist nun, ob sowas auch in Java möglich ist.
lol der is gut :) das hat nix damit zu tun dass manche glauben ein c++ programm sei schneller als ein java programm, sondern damit, dass die programmierer es richtig programmiert haben ;)
:gaen: :)

Genau das ist ja meine Hoffnung!

Deshalb habe ich das ja hier gepostet! Wieprogrammeirt man sowas denn richtig?
 

Bleiglanz

Gesperrter Benutzer
das hast du in der Form auch Paint und z.B. in jedem schnellen Programm in C++ und der Win32 API, die Ereignisse werden halt vom OS nicht schnell genug weiterverarbeitet

Lösung: du merkst dir den "letzen" Punkt und ziehst dann eine Linie zum "aktuellen" Punkt
 
S

SlaterB

Gast
was Andre_Uhres sagen wollte:
du malst bisher direkt auf der Komponente, aber nur einmalig,
irgendwann wird das Bild ja mal völlig gelöscht und wurde vorher nicht gespeichert,
also solltest du auf einem Image-Objekt malen
und in paint einfach immer das Image-Objekt zeigen,

problematisch ist auch dass du irgendwie ständig die Zeichenfläche weiß übermalst (wenn zeichnen = false),

das ist natürlich ziemlich tötlich selbt beim Zeichnen auf ein Image ;)
bei jedem repaint der nicht durch ein MosueEvent ausgelöst wird (z.B. ein repaint nach Größenänderung)
wird die Zeichenfäche weiß neu gestrichen

----------

zu den Sprüngen:
merke dir den vorherigen x,y Punkt und male jedesmal eine Linie zwischen den letzten und den neuen Punkt,

bei deiner dicken Linie wird das natürlich ein Problem, da musst du dir was angepasstes überlegen,
eventuell berechnest du die Entfernung und malst genügend Zwischenpunkte

----------

mit kleinen Erweiterungen und bisschen aufgeräumter als Anregung:

Code:
import java.awt.*;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;

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



public class ZeichenPanel extends JPanel {

	private int oldx, oldy;
	private int x, y;
	private boolean dragged = false;
	private boolean lastPointPainted = true;
	private Image image = null;

	public ZeichenPanel() {
		addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent arg0) {
				x = arg0.getX();
				y = arg0.getY();
				oldx = x;
				oldy = y;
				repaint();
			}
			public void mouseReleased(MouseEvent e) {
				dragged = false;
			}

		});
		
		addMouseMotionListener(new MouseMotionListener() {
			public void mouseDragged(MouseEvent arg0) {
				if (!lastPointPainted) {
              // MouseEvent ignorieren wenn vorheriger Punkt noch nicht gemalt wurde
					return;
				}
				lastPointPainted = false;
				oldx = x;
				oldy = y;
				x = arg0.getX();
				y = arg0.getY();
				
				if (!dragged) {
					oldx = x;
					oldy = y;
					dragged = true;
				}

				repaint();
			}

			public void mouseMoved(MouseEvent arg0) {
			}
		});
	}

	protected void paintComponent(Graphics g) {
		if (image == null) {
			int breite = getWidth();
			int hoch = getHeight();

			image = createImage(breite, hoch);

			Shape wrechteck = new Rectangle2D.Double(0, 0, breite, hoch);
			image.getGraphics().setColor(Color.WHITE);
			//((Graphics2D) image.getGraphics()).fill(wrechteck);
		}
		zeichne(image.getGraphics());
		
		g.drawImage(image,0,0,this);
	}

	private void zeichne(Graphics g) {
		Shape pinsel = new Arc2D.Double(x - 5, y - 5, 10, 10, 0, 360, Arc2D.PIE);
		g.setColor(Color.BLACK);
	//	((Graphics2D) g).fill(pinsel);
		g.drawLine(oldx,oldy,x,y);
	
		lastPointPainted = true;
	}

	public static void main(String args[]) {

		JFrame f = new JFrame("Malprogramm");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(600, 600);
		Container con = f.getContentPane();
		con.setLayout(new GridLayout(0, 1, 0, 0));
		con.add(new ZeichenPanel());
		f.setVisible(true);
	}
}

ein Problem am Rande:
die repaint-Operation kommt teilweise nicht so schnell hinterher wie die Maus neue Events liefert,
das heißt dass manchmal mehrere neue Punkte durch das Mouseevent definiert werden bevor die letzten
überhaupt gezeichnet wurden -> Lücken selbst wenn man einen Punkt merkt,

Lösung: mehrere Punkte merken oder mit dem Aufzeichnen eines neuern Punktes warten bis der vorherige gezeichnet wurde (siehe lastPointPainted-Variable im Programm, am besten auch mal rausnehmen um die Lücken zu sehen)
 

André Uhres

Top Contributor
Ich weiss nicht ob es bemerkt wurde dass DrawOnImage ein Link ist zu einem Post vom Autor camickr.
Er ist im Sun Java Forum der Swing Spezialist. Seine Lösung ist auch net schlecht.
 

jobu0101

Bekanntes Mitglied
Danke an euch alle, ihr habt mir geholfen!

@SlaterB: Man müsste beim Vergrößern des Fensters auch das Bild vergrößern. Aber das ist natürlich nur eine Kleinigkeit, um die es hier garnicht ging!


Edit:

Aber habe doch noch eine Frage:

in dem

Code:
if (image == null) {

Teil wird die Grafik angelegt und er soll ein weißes Rechteck zeichnen. Der Befehl für das weiße Rechteck ist also Kommentar geschrieben. Macht man die Kommentarstriche weg, wird das Rechteck aber schwarz. Woran liegt das?
 
S

SlaterB

Gast
oja, das wollte ich noch testen und hatte es vergessen,
ich denke es liegt daran dass bei jedem image.getGraphics()-Aufruf das immergleiche Objekt auf die Standardfarbe Schwarz zurückgesetz wird,

folgendes tuts:
Graphics2D g2 = image.getGraphics();
g2.setColor(Color.GREEN);
g2.fill(wrechteck);

----------

die Variante aus dem anderen Forum ist natürlich viel schicker,
ich dachte erst da stände nur erwas zum BufferedImage ;)
 

jobu0101

Bekanntes Mitglied
André Uhres hat gesagt.:

Zu dem Beispiel habe ich noch eine Frage:

Da gibt es folgende Funktion:

Code:
    private JButton addButton(Color color)
    {
        JButton button = new JButton();
        button.setBackground(new Color(230,240,250));
        button.setBorder(BorderFactory.createEtchedBorder());
 
        if (color != null)
        {
            button.setForeground(Color.white);
            button.setBackground(color);
        }
 
        button.setText("Paint");
        buttonPanel.add(button);
        button.addActionListener(this);
 
        return(button);
    }

Worauf bezieht sich denn da das this in dieser Zeile:

Code:
        button.addActionListener(this);
 

André Uhres

Top Contributor
jobu0101 hat gesagt.:
Worauf bezieht sich denn da das this in dieser Zeile:
Code:
        button.addActionListener(this);
Auf den Frame. Der ist ja der ActionListener:
Code:
public class DrawOnImage extends JFrame implements ActionListener
 

jobu0101

Bekanntes Mitglied
André Uhres hat gesagt.:
jobu0101 hat gesagt.:
Worauf bezieht sich denn da das this in dieser Zeile:
Code:
        button.addActionListener(this);
Auf den Frame. Der ist ja der ActionListener:
Code:
public class DrawOnImage extends JFrame implements ActionListener

stimmt, klar! Den hatte ich übersehen und dieganze Zeit mich gewundert, warum das funktioniert :D
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Java Swing - kleines Rechteck unter dem cursor AWT, Swing, JavaFX & SWT 5
J Kleines Helikopterspiel programmieren AWT, Swing, JavaFX & SWT 2
J Verbesserungsvorschläge?! Kleines AWT Programm AWT, Swing, JavaFX & SWT 4
T Kleines Infofenster einblenen lassen AWT, Swing, JavaFX & SWT 3
J Kleines Anzeige Problem(nur blanker Frame) AWT, Swing, JavaFX & SWT 22
F Kleines Fenster am Bildschirmrand AWT, Swing, JavaFX & SWT 3
C Swing Kleines Programm mit SWING unter Verwendung von MVC AWT, Swing, JavaFX & SWT 5
L Kleines Lückenprogrämmchen AWT, Swing, JavaFX & SWT 3
C kleines Chatprogramm, probleme mit JTextArea AWT, Swing, JavaFX & SWT 9
R JTable Header - will links kleines icon hinzufuegen..? AWT, Swing, JavaFX & SWT 6
D Swing Ein kleines Formatierungsproblem AWT, Swing, JavaFX & SWT 9
F kleines problem beim suchen in einem String AWT, Swing, JavaFX & SWT 15
T Ein kleines buntes Farbproblem AWT, Swing, JavaFX & SWT 7
V Thread als kleines splash AWT, Swing, JavaFX & SWT 13
C Mein erstes kleines Swing-Projekt - Probleme AWT, Swing, JavaFX & SWT 8
H Kleines SwingProgramm Frage AWT, Swing, JavaFX & SWT 14
H Kleines Malprogramm AWT, Swing, JavaFX & SWT 36
J Kleines Layout Problem AWT, Swing, JavaFX & SWT 5
B Kleines JFrame Problem (oder doch größer?) AWT, Swing, JavaFX & SWT 2
P Warum braucht mein kleines Programm 20 MB Speicher? AWT, Swing, JavaFX & SWT 13
D Kleines aber dummes Problem mit Turtle. AWT, Swing, JavaFX & SWT 4
J JavaFX JavaFX Canvas einfaches Zeichenprogramm AWT, Swing, JavaFX & SWT 7
U JavaFX Zeichenprogramm mit JavaFX FXML AWT, Swing, JavaFX & SWT 7
T 2D-Grafik Tutorial für ein einfaches Zeichenprogramm! AWT, Swing, JavaFX & SWT 2
B Swing Noch ein Zeichenprogramm... AWT, Swing, JavaFX & SWT 19
Q Swing Zeichenprogramm, grundlegende Fragen AWT, Swing, JavaFX & SWT 8
K Probleme mit Zeichenprogramm AWT, Swing, JavaFX & SWT 14

Ähnliche Java Themen

Neue Themen


Oben