<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.byte-welt.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Marco13</id>
	<title>Byte-Welt Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.byte-welt.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Marco13"/>
	<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php/Spezial:Beitr%C3%A4ge/Marco13"/>
	<updated>2026-07-08T09:48:31Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Java-Applet_zu_Java-Applikation_umschreiben&amp;diff=8435</id>
		<title>Java-Applet zu Java-Applikation umschreiben</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Java-Applet_zu_Java-Applikation_umschreiben&amp;diff=8435"/>
		<updated>2018-08-26T17:55:35Z</updated>

		<summary type="html">&lt;p&gt;Marco13: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Java-Applets sind spätestens mit der Veröffentlichung von Java 7 Update 51 auf Webseiten im Internet praktisch bedeutungslos geworden. Zu viele Sicherheitslücken, die bis dahin aktiv ausgenutzt wurden, steckten im Java Plugin für Webbrowser.&lt;br /&gt;
Mit dem Release von Java 7 Update 51 wurden Applets sämtliche Rechte entzogen. Nur die Anpassung der Einstellungen in der Java Runtime, in der einbettenden Jar-Datei und in der einbettenden Ẃebseite versetzten Benutzer noch in die Lage, Java-Applets auszuführen.&lt;br /&gt;
&lt;br /&gt;
Mit Veröffentlichung von Java 9 hat Oracle das Java Plugin als &#039;&#039;deprecated&#039;&#039; (veraltet) eingestuft. In einer späteren Java-Versionen wird das Java Plugin also aus dem JDK und der JRE entfernt werden.&lt;br /&gt;
&lt;br /&gt;
Auch die Browser-Hersteller unterstützen bereits in ihren aktuellen Versionen ihrer Programme keine Java-Applets mehr. Zeit also, nützliche Java-Applets zu ausführbare Java-Anwendungen umzubauen.&lt;br /&gt;
&lt;br /&gt;
In diesem Tutorial werden wir eine häufig gestellte Frage behandeln und ausführlich beantworten:&lt;br /&gt;
&lt;br /&gt;
==Wie verwandelt man ein Java-Applet in eine Java-Anwendung?==&lt;br /&gt;
&lt;br /&gt;
Ein Applet in eine Anwendung umzuschreiben kann sehr einfach sein: Es gibt viele Applets, die nur wenig Funktionalität haben, und zum Beispiel nur etwas auf den Bildschirm zeichnen. In diesen Fällen kann man das Applet manchmal unverändert in eine Anwendung einfügen. Wenn das Applet mehr Funktionalität enthält (also Bedienkomponenten wie z.B. Buttons, Animationen oder Maus-Interaktion) kann es notwendig sein, diese Funktionalitäten einzeln in eine Anwendung zu übertragen. Je nachdem, wie das Applet aufgebaut ist, kann es dabei empfehlenswert sein, die Funktionen durch modernere Gegenstücke zu ersetzen - zum Beispiel, wenn ein Applet, das mit AWT entwickelt wurde, in eine Swing-Anwendung umgeschrieben werden soll. &lt;br /&gt;
&lt;br /&gt;
In Folgenden werden einige Beispiele für einfache Applets gezeigt, und wie man ihre Funktionen in eine Anwendung übertragen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== In Arbeit! Dieser Artikel wird gerade noch bearbeitet ==&lt;br /&gt;
&lt;br /&gt;
* Wie auf den Unterschied von &amp;lt;code&amp;gt;Applet&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;JApplet&amp;lt;/code&amp;gt; eingehen? (Letztere sind recht selten...)&lt;br /&gt;
* Kurzer Hinweis auf die Applet Lifecycle Methods (init/start/stop/destroy) hier? Die werden unten an verschiedenen Punkten benötigt...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ein einfaches Applet mit minimalem Aufwand in eine Anwendung verwandeln ==&lt;br /&gt;
&lt;br /&gt;
* Ein &amp;lt;code&amp;gt;Applet&amp;lt;/code&amp;gt; ist eine &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt;. Zeigen, wie man die einfach in einem &amp;lt;code&amp;gt;Frame&amp;lt;/code&amp;gt; darstellen kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zeichenfunktionen ==&lt;br /&gt;
&lt;br /&gt;
* Zeigen, wie man die &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;paint&amp;lt;/code&amp;gt;-Methoden (inklusive händischem double-buffering) nach Swing überträgt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Animationen ==&lt;br /&gt;
&lt;br /&gt;
* Das Negativbeispiel von &amp;quot;sleep in paint&amp;quot; verdammen, und einen einfachen repaint-Thread zeigen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Bedienkomponenten ==&lt;br /&gt;
&lt;br /&gt;
* Ggf. schwierig zu trennen. Es gibt Applets, die da richtigen Mist machen. Applets enthalten machmal Buttons UND Zeichenfunktionalität...&lt;br /&gt;
* Händisches &amp;quot;button.setBounds&amp;quot; war OK, weil sich die Applet-Größe nie geändert hat. Kurzer Hinweis (KEINE Anleitung!) zu LayoutManagern&lt;br /&gt;
* Erwähnen, das Button/Slider/CheckBox leicht zu JButton/JSlider/JCheckBox gemacht werden können&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[Einbinden von Java-Applets in HTML-Dateien]]&lt;br /&gt;
* [[Java-Applets und Java WebStart-Anwendungen signieren]]&lt;br /&gt;
* [[Java Applets und Java Web Start-Anwendungen starten - ab Java 7 Update 51]]&lt;br /&gt;
* [[JAR-Datei]]&lt;br /&gt;
&lt;br /&gt;
{{Fragen stellen}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;br /&gt;
[[Kategorie:Java Applets]]&lt;br /&gt;
[[Kategorie:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Marco13</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Limit_(SQL)&amp;diff=6960</id>
		<title>Limit (SQL)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Limit_(SQL)&amp;diff=6960"/>
		<updated>2017-01-03T13:27:39Z</updated>

		<summary type="html">&lt;p&gt;Marco13: Fix entsprechend https://forum.byte-welt.net/byte-welt-projekte-projects/wiki/22974-wiki-beitrag-limit.html&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Um Abfragen zu beschleunigen kann man eine maximale Anzahl an Ergebnissen festlegen, somit hört das [[DBMS]] nach X Werten auf nach weiteren zu suchen.&lt;br /&gt;
&lt;br /&gt;
==MySQL==&lt;br /&gt;
Unter [[MySQL]] gibt es für diesen Fall die Anweisung &#039;&#039;LIMIT&#039;&#039;, diese hat zwei Parameter, wobei der letzte optional ist. &lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT * from testtable WHERE id = 1 LIMIT 1&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
Diese Abfrage wählt nur ein Element aus, auch wenn es mehrere Elemente mit der ID 1 geben würde, außerdem wird direkt nach der 1. Abfrage aufgehört nach weiteren zu suchen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT * FROM testtable WHERE id &amp;gt;1 ORDER BY id LIMIT 10,30&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
Diese Abfrage wählt 30 Elemente aus, jedoch werden diese nicht vom Anfang genommen, sondern erst ab dem 10. Element: Der erste Parameter von &#039;&#039;LIMIT&#039;&#039; beschreibt dabei den offset der Zeilen, und der zweite Parameter die maximale Anzahl der Zeilen. Dies bedeutet wenn die id von 1-100 eindeutig durchnummeriert ist, werden die Elemente 11-40 ausgegeben.&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL==&lt;br /&gt;
Unter [[PostgreSQL]] gibt es ähnlich wie bei [[MySQL]] die Anweisung &#039;&#039;LIMIT&#039;&#039;, auch mit den beiden Parametern, jedoch wird der zweite Parameter mit dem [[Schlüsselwort]] &#039;&#039;OFFSET&#039;&#039; eingetragen.&lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT * from testtable WHERE id = 1 LIMIT 1&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
Diese Abfrage wählt nur ein Element aus, auch wenn es mehrere Elemente mit der ID 1 geben würde, außerdem wird direkt nach der 1. Abfrage aufgehört nach weiteren zu suchen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT * FROM testtable WHERE id &amp;gt;1 ORDER BY id LIMIT 10 OFFSET 30&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
Diese Abfrage wählt 10 Elemente aus, jedoch werden diese nicht vom Anfang genommen, sondern erst ab dem 30.Element. Dies bedeutet wenn die id von 1-100 eindeutig durchnummeriert ist, werden die Elemente 30-40 ausgegeben.&lt;br /&gt;
&lt;br /&gt;
==Oracle==&lt;br /&gt;
Unter [[Oracle]] gibt es für diese Art der Anweisungen eine weitere Spalte, diese heißt &#039;&#039;ROWNUM&#039;&#039;. Sie enthält die Zeilennummer, so dass man mit dieser wie mit jeder anderen Spalte arbeiten kann.&lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT * from testtable WHERE id = 1 AND rownum = 1&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
Diese Abfrage wählt nur ein Element aus, auch wenn es mehrere Elemente mit der ID 1 geben würde, außerdem wird direkt nach der 1. Abfrage aufgehört nach weiteren zu suchen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine Abfrage auf &#039;&#039;rownum &amp;gt; 1&#039;&#039; ist nicht möglich, da die rownum erzeugt wird nachdem der Query Optimizer die WHERE Klausel ausgwertet hat. Siehe http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html&lt;br /&gt;
&lt;br /&gt;
==MSSQL==&lt;br /&gt;
[[MSSQL]] besitzt die Anweisung &#039;&#039;TOP&#039;&#039; für die Begrenzung der Ergebnise. Unter SQL CE existiert die Funktion nicht, es gibt auch keine Alternative.&lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT TOP 10 * FROM testtable WHERE id = 1&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einen Offset oder ähnliches wird von MSSQL nicht unterstützt oder angeboten.&lt;br /&gt;
&lt;br /&gt;
==DB2==&lt;br /&gt;
[[DB2]] hat für die die Begrenzung der Ergebnisse die Anweisung &#039;&#039;FETCH FIRST X ROWS ONLY&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=sql&amp;gt;SELECT * FROM testtable FETCH FIRST 10 ROWS ONLY;&amp;lt;/code=sql&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SQL]]&lt;br /&gt;
[[Kategorie:MySQL]]&lt;br /&gt;
[[Kategorie:PostgreSQL]]&lt;br /&gt;
[[Kategorie:Oracle]]&lt;br /&gt;
[[Kategorie:MSSQL]]&lt;/div&gt;</summary>
		<author><name>Marco13</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Bilder_skalieren&amp;diff=5438</id>
		<title>Bilder skalieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Bilder_skalieren&amp;diff=5438"/>
		<updated>2013-08-17T20:21:05Z</updated>

		<summary type="html">&lt;p&gt;Marco13: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Bilder skalieren=&lt;br /&gt;
&lt;br /&gt;
Einen ausführlichen Artikel zum Thema &#039;Bilder skalieren&#039; gibt es unter [https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html The Perils of getScaledInstance]. Die wichtigsten Punkte sind hier kurz zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
Bim Skalieren von Bildern gibt es im wesentlichen zwei mögliche Ziele: Man will das Bild entweder &#039;&#039;skaliert zeichnen&#039;&#039;, oder man will eine &#039;&#039;skalierte Instanz&#039;&#039; eines Bildes erstellen. In beiden Fällen kann man noch unterschiedliche Schwerpunkte setzen. So kann im einen Fall die Performance (also die Zeichengeschwindigkeit) besonders wichtig sein, und im anderen Fall die Bildqualität. &lt;br /&gt;
&lt;br /&gt;
== Bilder skaliert zeichnen ==&lt;br /&gt;
&lt;br /&gt;
Wenn man ein Bild skaliert zeichnen will, kann man das am einfachsten direkt mit der geeigneten Methode &amp;lt;code&amp;gt;drawImage&amp;lt;/code&amp;gt; aus der Klasse &amp;lt;code&amp;gt;Graphics&amp;lt;/code&amp;gt;. Von dieser Methode gibt es verschiedene Varianten, und unter anderem eine, mit der man direkt sagen kann, wie groß das Bild gezeichnet werden soll:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
public boolean drawImage(Image image, int x, int y, int width, int height, ImageObserver observer)&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Um ein Bild in einer Größe von 400x300 Bildpunkten zu zeichnen, verwendet man also&lt;br /&gt;
&amp;lt;code=java&amp;gt; &lt;br /&gt;
graphics.drawImage(image, 0, 0, 400, 300, null);&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Skalierte Instanzen erstellen ==&lt;br /&gt;
&lt;br /&gt;
Um eine skalierte Instanz eines Bildes zu erstellen, kann man einfach das vorhandene Bild in ein Bild der gewünschten Größe hineinzeichnen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
BufferedImage originalImage = ImageIO.read(new File(&amp;quot;image.png&amp;quot;));&lt;br /&gt;
BufferedImage scaledImage = new BufferedImage(400, 300, BufferedImage.TYPE_INT_ARGB);&lt;br /&gt;
Graphics g = scaledImage.createGraphics();&lt;br /&gt;
g.drawImage(originalImage, 0, 0, 400, 300, null);&lt;br /&gt;
g.dispose();&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Wie man sieht wird hierbei die gleiche Methode &amp;lt;code&amp;gt;drawImage&amp;lt;/code&amp;gt; aus der Klasse &amp;lt;code&amp;gt;Graphics&amp;lt;/code&amp;gt; verwendet, wie beim skalierten Zeichnen. Allerdings wird das Bild hier nicht auf den Bildschirm, sondern in ein anderes Bild hinein gezeichnet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RenderingHints: Qualität oder Geschwindigkeit? ==&lt;br /&gt;
&lt;br /&gt;
Sowohl beim skalierten Zeichnen als auch beim erstellen skalierter Instanzen kann man durch das Setzen von &#039;&#039;Rendering Hints&#039;&#039; noch festlegen, ob eher in höherer Qualität oder eher in höherer Geschwindigkeit gezeichnet werden soll. Diese &#039;&#039;Rendering Hints&#039;&#039; setzt man in dem &amp;lt;code&amp;gt;Graphics2D&amp;lt;/code&amp;gt;-Objekt, das man zum Zeichnen verwendet. Dabei ist egal, ob man direkt auf den Bildschirm oder in ein anderes Bild hinein zeichnet. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird hier gesagt, dass &#039;&#039;bilineare Interpolation&#039;&#039; verwendet werden soll, was zwar etwas langsamer ist, aber für höhere Bildqualität sorgt:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
Graphics2D g = (Graphics2D)graphics;&lt;br /&gt;
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,&lt;br /&gt;
                   RenderingHints.VALUE_INTERPOLATION_BILINEAR);&lt;br /&gt;
g.drawImage(image, 0, 0, 400, 300, null);&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Hätte man statt &amp;lt;code&amp;gt;VALUE_INTERPOLATION_BILINEAR&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;VALUE_INTERPOLATION_NEAREST_NEIGHBOR&amp;lt;/code&amp;gt; angegeben, wäre die Bildqualität geringer, aber das Zeichnen etwas schneller. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Warum nicht getScaledInstance? ==&lt;br /&gt;
&lt;br /&gt;
Oft werden mit der Methode [http://docs.oracle.com/javase/6/docs/api/java/awt/Image.html#getScaledInstance%28int,%20int,%20int%29 Image#getScaledInstance] skalierte Instanzen von Bildern erstellt und gezeichnet - im schlimmsten Fall sogar bei jedem Zeichenvorgang erneut. Diese Methode ist oft weder in bezug auf Bildqualität noch in Bezug auf die Performance die geeignetste Lösung. Die Methoden aus der Klasse &amp;lt;code&amp;gt;Graphics2D&amp;lt;/code&amp;gt; und die &amp;lt;code&amp;gt;RenderingHints&amp;lt;/code&amp;gt; bieten mehr Möglichkeiten, die für das jeweilige Ziel beste Skalierungs-Art zu wählen. Zusätzlich können die skalierten Instanzen, die manuell erstellt werden, Hardwarebeschleunigt sein, wodurch sie später schneller gezeichnet werden können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das war nicht alles! ==&lt;br /&gt;
&lt;br /&gt;
Es gibt noch viele Details, die man beim Skalieren von Bildern berücksichtigen kann. Im oben verlinkten Artikel wird genauer auf diese Details eingegangen und verschiedene mögliche Strategien beim Skalieren besprochen, und die Ergebnisse mit Benchmarks und Testbildern verglichen. Aber schon die Frage, ob man Bilder in einem bestimmten Anwendungsfall eher &#039;&#039;skaliert zeichnen&#039;&#039; sollte, oder ob es besser wäre, eine &#039;&#039;skalierte Instanz&#039;&#039; eines Bildes zu erstellen, kann schwierig zu beantworten sein. Dieser Artikel soll nur die grundsätzlichen Unterschiede und Vorgehensweisen beschreiben, und hilft hoffentlich, zu verhindern, dass jemand vor jedem Zeichnen eines Bildes eine skalierte Instanz mit &amp;lt;code&amp;gt;getScaledInstance&amp;lt;/code&amp;gt; erstellt....&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Tutorials (Java)]]|[[Kategorie:Java]]&lt;/div&gt;</summary>
		<author><name>Marco13</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Malen_in_Swing_Teil_2:_ein_einfaches_Malprogramm&amp;diff=5196</id>
		<title>Malen in Swing Teil 2: ein einfaches Malprogramm</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Malen_in_Swing_Teil_2:_ein_einfaches_Malprogramm&amp;diff=5196"/>
		<updated>2012-12-26T15:46:16Z</updated>

		<summary type="html">&lt;p&gt;Marco13: ActionListener muss initialisiert werden, bevor er in &amp;#039;addButton&amp;#039; verwendet wird&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
Der erste Teil dieses Tutorials erklärt den grundlegenden Malmechanismus: [[Malen in Swing Teil 1: der grundlegende Mechanismus]].&lt;br /&gt;
&lt;br /&gt;
Das folgende weiterführende Beispielprogramm erlaubt das Malen von farbigen Linien verschiedener Stärke. Das Malen geschieht freihändig durch Ziehen mit der Maus. &lt;br /&gt;
Durch dieses Beispiel lernen wir: &lt;br /&gt;
* wie mehrfache repaint Anträge zusammengefasst werden&lt;br /&gt;
* wie wir den Bereich, der dargestellt wird, einschränken können&lt;br /&gt;
[[Datei:DrawOnImage.jpg]]&lt;br /&gt;
==Mehrfache repaint Anträge zusammenfassen==&lt;br /&gt;
&lt;br /&gt;
Jede gemalte Linie setzt sich zusammen aus einer Folge von vielen Kreisen (Graphics#fillOval), die jeweils durch Interpolation zwischen zwei Mauspunkten festgelegt werden. &lt;br /&gt;
Dabei wird repaint(x,y,brushSize,brushSize) mehrfach in einer Schleife aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;    @Override&lt;br /&gt;
    public void mouseDragged(final MouseEvent e) {&lt;br /&gt;
        double xDelta = e.getX() - lastPoint.getX();&lt;br /&gt;
        double yDelta = e.getY() - lastPoint.getY();&lt;br /&gt;
        double delta = Math.max(Math.abs(xDelta), Math.abs(yDelta));&lt;br /&gt;
        double xIncrement = xDelta / delta;&lt;br /&gt;
        double yIncrement = yDelta / delta;&lt;br /&gt;
        double xStart = lastPoint.getX();&lt;br /&gt;
        double yStart = lastPoint.getY();&lt;br /&gt;
        for (int i = 0; i &amp;lt; delta; i++) {&lt;br /&gt;
            Point interpolated = new Point((int) xStart, (int) yStart);&lt;br /&gt;
            draw(interpolated);&lt;br /&gt;
            xStart += xIncrement;&lt;br /&gt;
            yStart += yIncrement;&lt;br /&gt;
        }&lt;br /&gt;
        draw(e.getPoint());&lt;br /&gt;
        lastPoint = e.getPoint();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private void draw(final Point start) {&lt;br /&gt;
        int brushSize = drawingPanel.getBrushSize();&lt;br /&gt;
        int x = start.x - (brushSize / 2) + 1;&lt;br /&gt;
        int y = start.y - (brushSize / 2) + 1;&lt;br /&gt;
        drawingPanel.getG2d().fillOval(x, y,brushSize, brushSize);&lt;br /&gt;
        drawingPanel.repaint(x, y,brushSize, brushSize); //&amp;lt;&amp;lt;---------------------&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Erfolgen mehrfache repaint() Aufrufe auf einer Komponente bevor der erste Antrag verarbeitet wird, kann der Swing Repaintmanager die mehrfachen Anträge zu einem einzigen Aufruf zusammenfassen. Genauer gesagt: der RepaintManager wird eine Serie von Malanträgen dann zusammenfassen, wenn der &amp;quot;Anführer&amp;quot; der Serie schon mit invokeLater verschickt wurde, aber noch nicht auf dem EDT verarbeitet wurde (der Vorgang bleibt also &amp;quot;threadsafe&amp;quot;). Wenn mehrfache Anträge zusammengefasst werden, ist das resultierende Cliprechteck gleich der Vereinigung der Rechtecke, die in den zusammengefassten Anträgen enthalten sind. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BEMERKUNG:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Diese Zeile:&lt;br /&gt;
&amp;lt;code=java&amp;gt;drawingPanel.getG2d().fillOval(x, y,brushSize, brushSize);&amp;lt;/code=java&amp;gt;&lt;br /&gt;
holt mit &#039;&#039;&#039;getG2d()&#039;&#039;&#039; nicht das Graphics Objekt der Komponente, sondern das Graphics Objekt des &#039;&#039;&#039;Bildes&#039;&#039;&#039;. In paintComponent wird dann mit &amp;quot;drawImage&amp;quot; das Bild auf das Graphics Objekt der Komponente übertragen, wie der folgende Abschnitt zeigt. Daher auch der Name des Hauptprogramms &amp;quot;DrawOnImage&amp;quot;. Man spricht in diesem Fall auch von der &amp;quot;passiven Maltechnik&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Den Bereich, der dargestellt wird, einschränken==&lt;br /&gt;
Während Swing versucht, den Prozess der Darstellung der Komponenten so leistungsfähig wie möglich zu machen, kann die paintComponent() Implementierung einer Komponente selbst eine bedeutende Auswirkung auf die gesamte Leistung haben. Wir können diesen Prozess beeinflussen, indem wir die Clipinformationen verwenden, um den Bereich, der dargestellt wird, einzuschränken.&lt;br /&gt;
&lt;br /&gt;
Wenn deine Komponente einfach ist -- zum Beispiel, wenn es eine Drucktaste ist -- dann ist sie die Mühe nicht wert, die Darstellung zu bearbeiten, um nur den Teil zu malen, der das Cliprechteck überschneidet; es ist vorzuziehend, die gesamte Komponente zu malen und die Graphics passend einschränken zu lassen. Wenn du jedoch eine Komponente mit komplizierter Ausgabe erzeugt hast, wie eine Textkomponente, dann ist es notwendig, dass dein Code die Clipinformationen gebraucht, um den Umfang der Darstellung einzuschränken. Die Methode Graphics#getClipBounds gibt uns Zugriff auf das Cliprechteck:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;    @Override&lt;br /&gt;
    public void paintComponent(final Graphics g) {&lt;br /&gt;
        super.paintComponent(g);&lt;br /&gt;
        // initialises the image with the first paint&lt;br /&gt;
        // or checks the image size with the current panelsize&lt;br /&gt;
        if (image == null || image.getWidth(this) &amp;lt; getSize().width || image.getHeight(this) &amp;lt; getSize().height) {&lt;br /&gt;
            resetImage();&lt;br /&gt;
        }&lt;br /&gt;
        Rectangle r = g.getClipBounds(); //&amp;lt;&amp;lt;----------------------&lt;br /&gt;
        g.drawImage(image, r.x, r.y, r.width + r.x, r.height + r.y, r.x, r.y, r.width + r.x, r.height + r.y, null);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der drawImage(..)-Aufruf, mit den angegebenen Parametern, zeichnet nur den Teil des Bildes neu, der sich mit dem Cliprechteck überschneidet. Man spricht in diesem Zusammenhang auch von der &amp;quot;intelligenten Maltechnik&amp;quot; (smart painting).&lt;br /&gt;
&lt;br /&gt;
==Gesamter Quellcode==&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
import java.awt.*;&lt;br /&gt;
import java.awt.event.*;&lt;br /&gt;
&lt;br /&gt;
public class DrawOnImage {&lt;br /&gt;
&lt;br /&gt;
    final private DrawingPanel drawingPanel;&lt;br /&gt;
    final private JPanel buttonPanel;&lt;br /&gt;
    final private JButton clearButton, upSize, downSize;&lt;br /&gt;
    private final ActionListener actionHandler;&lt;br /&gt;
&lt;br /&gt;
    public DrawOnImage() {&lt;br /&gt;
        JFrame frame = new JFrame(&amp;quot;DrawOnImage&amp;quot;);&lt;br /&gt;
        drawingPanel = new DrawingPanel();&lt;br /&gt;
        actionHandler = new ActionListener() {&lt;br /&gt;
&lt;br /&gt;
            @Override&lt;br /&gt;
            public void actionPerformed(final ActionEvent e) {&lt;br /&gt;
                String s = e.getActionCommand();&lt;br /&gt;
                if (s.equals(&amp;quot;Paint&amp;quot;)) {&lt;br /&gt;
                    JButton button = (JButton) e.getSource();&lt;br /&gt;
                    drawingPanel.setPaintColor(button.getBackground());&lt;br /&gt;
                } else if (s.equals(&amp;quot;Clear&amp;quot;)) {&lt;br /&gt;
                    drawingPanel.clearPaint();&lt;br /&gt;
                } else if (s.equals(&amp;quot;+&amp;quot;)) {&lt;br /&gt;
                    drawingPanel.increaseBrushSize();&lt;br /&gt;
                } else {&lt;br /&gt;
                    drawingPanel.decreaseBrushSize();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        buttonPanel = new JPanel();&lt;br /&gt;
        buttonPanel.setLayout(new GridLayout(2, 0, 2, 2));&lt;br /&gt;
        addButton(Color.BLACK);&lt;br /&gt;
        addButton(Color.BLUE);&lt;br /&gt;
        addButton(Color.GREEN);&lt;br /&gt;
        upSize = addButton(null);&lt;br /&gt;
        upSize.setText(&amp;quot;+&amp;quot;);&lt;br /&gt;
        addButton(Color.RED);&lt;br /&gt;
        addButton(Color.ORANGE);&lt;br /&gt;
        clearButton = addButton(null);&lt;br /&gt;
        clearButton.setText(&amp;quot;Clear&amp;quot;);&lt;br /&gt;
        downSize = addButton(null);&lt;br /&gt;
        downSize.setText(&amp;quot;-&amp;quot;);&lt;br /&gt;
        frame.getContentPane().add(new JScrollPane(drawingPanel));&lt;br /&gt;
        frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);&lt;br /&gt;
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);&lt;br /&gt;
        frame.pack();&lt;br /&gt;
        frame.setLocationRelativeTo(null);&lt;br /&gt;
        frame.setVisible(true);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private JButton addButton(final Color color) {&lt;br /&gt;
        JButton button = new JButton();&lt;br /&gt;
        button.setBackground(new Color(230, 240, 250));&lt;br /&gt;
        button.setBorder(BorderFactory.createEtchedBorder());&lt;br /&gt;
        if (color != null) {&lt;br /&gt;
            button.setForeground(Color.WHITE);&lt;br /&gt;
            button.setBackground(color);&lt;br /&gt;
        }&lt;br /&gt;
        button.setText(&amp;quot;Paint&amp;quot;);&lt;br /&gt;
        buttonPanel.add(button);&lt;br /&gt;
        button.addActionListener(actionHandler);&lt;br /&gt;
        return (button);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void main(final String[] args) {&lt;br /&gt;
        Runnable gui = new Runnable() {&lt;br /&gt;
&lt;br /&gt;
            @Override&lt;br /&gt;
            public void run() {&lt;br /&gt;
                DrawOnImage drawOnImage = new DrawOnImage();&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        //GUI must start on EventDispatchThread:&lt;br /&gt;
        SwingUtilities.invokeLater(gui);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.awt.Point;&lt;br /&gt;
import java.awt.event.MouseEvent;&lt;br /&gt;
import javax.swing.event.MouseInputAdapter;&lt;br /&gt;
&lt;br /&gt;
class MouseHandler extends MouseInputAdapter {&lt;br /&gt;
&lt;br /&gt;
    private final DrawingPanel drawingPanel;&lt;br /&gt;
    private Point lastPoint;&lt;br /&gt;
&lt;br /&gt;
    MouseHandler(final DrawingPanel drawingPanel) {&lt;br /&gt;
        this.drawingPanel = drawingPanel;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void mousePressed(final MouseEvent e) {&lt;br /&gt;
        lastPoint = e.getPoint();&lt;br /&gt;
        draw(lastPoint);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void mouseDragged(final MouseEvent e) {&lt;br /&gt;
        double xDelta = e.getX() - lastPoint.getX();&lt;br /&gt;
        double yDelta = e.getY() - lastPoint.getY();&lt;br /&gt;
        double delta = Math.max(Math.abs(xDelta), Math.abs(yDelta));&lt;br /&gt;
        double xIncrement = xDelta / delta;&lt;br /&gt;
        double yIncrement = yDelta / delta;&lt;br /&gt;
        double xStart = lastPoint.getX();&lt;br /&gt;
        double yStart = lastPoint.getY();&lt;br /&gt;
        for (int i = 0; i &amp;lt; delta; i++) {&lt;br /&gt;
            Point interpolated = new Point((int) xStart, (int) yStart);&lt;br /&gt;
            draw(interpolated);&lt;br /&gt;
            xStart += xIncrement;&lt;br /&gt;
            yStart += yIncrement;&lt;br /&gt;
        }&lt;br /&gt;
        draw(e.getPoint());&lt;br /&gt;
        lastPoint = e.getPoint();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private void draw(final Point start) {&lt;br /&gt;
        int brushSize = drawingPanel.getBrushSize();&lt;br /&gt;
        int x = start.x - (brushSize / 2) + 1;&lt;br /&gt;
        int y = start.y - (brushSize / 2) + 1;&lt;br /&gt;
        drawingPanel.getG2d().fillOval(x, y, brushSize, brushSize);&lt;br /&gt;
        drawingPanel.repaint(x, y, brushSize, brushSize);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.awt.*;&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
&lt;br /&gt;
public class DrawingPanel extends JComponent {&lt;br /&gt;
&lt;br /&gt;
    private Image image;&lt;br /&gt;
    private Graphics2D g2d;&lt;br /&gt;
    private int brushSize = 5;&lt;br /&gt;
&lt;br /&gt;
    public DrawingPanel() {&lt;br /&gt;
        super();&lt;br /&gt;
        setPreferredSize(new Dimension(300, 300));&lt;br /&gt;
        MouseHandler mh = new MouseHandler(this);&lt;br /&gt;
        addMouseListener(mh);&lt;br /&gt;
        addMouseMotionListener(mh);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public Dimension getPreferredSize() {&lt;br /&gt;
        Dimension size = super.getPreferredSize();&lt;br /&gt;
        if (image != null) {&lt;br /&gt;
            size.width = image.getWidth(this);&lt;br /&gt;
            size.height = image.getHeight(this);&lt;br /&gt;
        }&lt;br /&gt;
        return size;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void setPaintColor(final Color color) {&lt;br /&gt;
        g2d.setColor(color);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void clearPaint() {&lt;br /&gt;
        g2d.setBackground(Color.WHITE);&lt;br /&gt;
        g2d.clearRect(0, 0, getWidth(), getHeight());&lt;br /&gt;
        repaint();&lt;br /&gt;
        g2d.setColor(Color.BLACK);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void increaseBrushSize() {&lt;br /&gt;
        brushSize += 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void decreaseBrushSize() {&lt;br /&gt;
        brushSize -= 2;&lt;br /&gt;
        if (brushSize &amp;lt;= 0) {&lt;br /&gt;
            brushSize = 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void paintComponent(final Graphics g) {&lt;br /&gt;
        super.paintComponent(g);&lt;br /&gt;
        // initialises the image with the first paint&lt;br /&gt;
        // or checks the image size with the current panelsize&lt;br /&gt;
        if (image == null || image.getWidth(this) &amp;lt; getSize().width&lt;br /&gt;
                || image.getHeight(this) &amp;lt; getSize().height) {&lt;br /&gt;
            resetImage();&lt;br /&gt;
        }&lt;br /&gt;
        Graphics2D g2 = (Graphics2D) g;&lt;br /&gt;
        Rectangle r = g.getClipBounds();&lt;br /&gt;
        g2.drawImage(image, r.x, r.y, r.width + r.x, r.height + r.y,&lt;br /&gt;
                r.x, r.y, r.width + r.x, r.height + r.y, this);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private void resetImage() {&lt;br /&gt;
        Image saveImage = image;&lt;br /&gt;
        Graphics2D saveG2d = g2d;&lt;br /&gt;
        image = createImage(getWidth(), getHeight());&lt;br /&gt;
        g2d = (Graphics2D) image.getGraphics();&lt;br /&gt;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,&lt;br /&gt;
                RenderingHints.VALUE_ANTIALIAS_ON);&lt;br /&gt;
        g2d.setBackground(Color.WHITE);&lt;br /&gt;
        g2d.clearRect(0, 0, getWidth(), getHeight());&lt;br /&gt;
        g2d.setColor(Color.BLACK);&lt;br /&gt;
        if (saveG2d != null) {&lt;br /&gt;
            g2d.setColor(saveG2d.getColor());&lt;br /&gt;
            g2d.drawImage(saveImage, 0, 0, this);&lt;br /&gt;
            saveG2d.dispose();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public Graphics2D getG2d() {&lt;br /&gt;
        return g2d;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int getBrushSize() {&lt;br /&gt;
        return brushSize;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;br /&gt;
[[Kategorie:Tutorials (Java)]]&lt;br /&gt;
[[Kategorie:Swing]]&lt;/div&gt;</summary>
		<author><name>Marco13</name></author>
	</entry>
</feed>