{"id":469,"date":"2018-11-15T14:01:28","date_gmt":"2018-11-15T13:01:28","guid":{"rendered":"https:\/\/freizone.net\/java-einfach-lernen\/?p=469"},"modified":"2020-05-11T19:29:40","modified_gmt":"2020-05-11T17:29:40","slug":"virtueller-bildschirm","status":"publish","type":"post","link":"https:\/\/freizone.net\/java-einfach-lernen\/2018\/11\/15\/virtueller-bildschirm\/","title":{"rendered":"virtueller Bildschirm"},"content":{"rendered":"<p>Da mit <code>super.paint(g);<\/code> auch das Elternelement neu gezeichnet wird, w\u00fcrden alle alten Punkte die wir gemalt haben gel\u00f6scht werden. Das ist praktisch bei Animationen, nicht jedoch beim Zeichnen. Um daher korrekt malen zu k\u00f6nnen, m\u00fcssen wir unserem Programm beibringen es sich zu merken was schon gezeichnet wurde. Dies bewerkstelligen wir mit einer einzigen Variablen. Zum einen k\u00f6nnten wir es mit einem Array machen:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">package miniMalen;\r\n\r\nimport java.awt.Color;\r\nimport java.awt.Graphics;\r\nimport java.awt.event.MouseAdapter;\r\nimport java.awt.event.MouseEvent;\r\nimport javax.swing.JFrame;\r\nimport javax.swing.JPanel;\r\n\r\npublic class Tafel extends JFrame {\r\n\r\n  public static void main(String[] s) {\r\n    new Tafel();\r\n  }\r\n\r\n  private int[][] liste = new int[100][2];\r\n  private int zaehler = 0;\r\n  private JPanel panel;\r\n  private int x = -10;\r\n  private int y = -10;\r\n\r\n  public Tafel() {\r\n    initialisiereTafel();\r\n  }\r\n\r\n  private void initialisiereTafel() {\r\n    this.setDefaultCloseOperation(EXIT_ON_CLOSE);\r\n    this.setBounds(0, 0, 500, 500);\r\n    this.setLocationRelativeTo(null);\r\n    this.setAlwaysOnTop(true);\r\n    this.setBackground(Color.white);\r\n    this.setTitle(\"Tafel\");\r\n    this.setLayout(null);\r\n    sichtbar();\r\n\r\n    panel = new JPanel() {\r\n\r\n      public void paintComponent(Graphics g) {\r\n        super.paintComponent(g);\r\n\r\n        for (int z = 0; z &lt; liste.length; z++) {\r\n          x = liste[z][0];\r\n          y = liste[z][1];\r\n\r\n          g.fillOval(x, y, 10, 10);\r\n        }\r\n      }\r\n\r\n    };\r\n\r\n    panel.setBackground(Color.WHITE);\r\n\r\n    panel.setBounds(0, 0, 500, 500);\r\n    this.add(panel);\r\n\r\n    panel.addMouseMotionListener(new MouseAdapter() {\r\n      public void mouseDragged(MouseEvent arg0) {\r\n        System.out.println(\"Dragged\");\r\n        x = arg0.getX();\r\n        y = arg0.getY();\r\n\r\n        liste[zaehler][0] = x;\r\n        liste[zaehler][1] = y;\r\n        zaehler++;\r\n\r\n        panel.repaint();\r\n      }\r\n    });\r\n\r\n    panel.addMouseListener(new MouseAdapter() {\r\n      public void mousePressed(MouseEvent arg0) {\r\n        System.out.println(\"Test\");\r\n        x = arg0.getX();\r\n        y = arg0.getY();\r\n\r\n        liste[zaehler][0] = x;\r\n        liste[zaehler][1] = y;\r\n        zaehler++;\r\n\r\n        panel.repaint();\r\n      }\r\n    });\r\n\r\n  }\r\n\r\n  private void sichtbar() {\r\n    this.setVisible(true);\r\n  }\r\n\r\n}<\/pre>\n<p>Wir definieren in Zeile 16 ein Array mit zwei Dimensionen. Also f\u00fcr die X- und Y-Koordinaten. Das hei\u00dft in diesem Fall, es gibt 100 Felder die jeweils 2 Speicherzellen f\u00fcr Zahlen, also int, enthalten. Ausserdem brauchen wir noch eine Z\u00e4hlvariable (Zeile 17) damit das Programm wei\u00df in welchem Feld wir gerade sind.<\/p>\n<p>In den MouseListener <em>MouseDragged<\/em> und <em>MousePressed<\/em> wird dann ab Zeile 66 bzw. 80 unter Benutzung der Z\u00e4hlvariable <em>zaehler<\/em> in die erste Zelle die x-Koordinate geschrieben und in die zweite y und anschlie\u00dfend <em>zaehler<\/em> mit <code>zaehler++<\/code> um 1 erh\u00f6ht. Dann wird mit <code>panel.repaint()<\/code>, panel, also unsere Zeichenfl\u00e4che, neu gezeichnet.<\/p>\n<p>Schlie\u00dflich wird in der paint-Methode, die ja durch repaint() aufgerufen wird, in einer For-Schleife die komplette Liste ausgelesen und auf dem Bildsschirm ausgegeben. Das alles geschieht im Bruchteil einer Sekunde, jedesmal wenn die Maus gedr\u00fcckt oder gedr\u00fcckt und gezogen wird.<\/p>\n<p>Allerdings hat die L\u00f6sung mit dem Array mehrere Nachteile. Wir m\u00fcssen im Vorfeld festlegen wie viele Felder das Array hat, es kann sich nicht automatisch erweitern. Auch gibt es fr\u00fcher oder sp\u00e4ter eine OutOfBounds-Exception, sobald das Ende des Arrays erreicht ist, was ebenfalls behandelt werden m\u00fcsste.<br \/>\nEinfacher ist es daher eine sogenannte ArrayList zu verwenden. Die Klasse ArrayList hat den Vorteil das es Methoden bereith\u00e4lt um bequem einen neuen Datensatz hinzuzuf\u00fcgen. Generell ist das arbeiten mit einer ArrayList sehr komfortabel wie wir noch sehen werden. Die L\u00f6sung mit der ArrayList w\u00fcrde so aussehen:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">package miniMalprogramm;\r\n\r\nimport java.awt.Color;\r\nimport java.awt.Graphics;\r\nimport java.awt.event.MouseAdapter;\r\nimport java.awt.event.MouseEvent;\r\nimport javax.swing.JFrame;\r\nimport javax.swing.JPanel;\r\n\r\npublic class Tafel extends JFrame {\r\n\r\n  public static void main(String[] s) {\r\n    new Tafel();\r\n  }\r\n\r\n  private int[][] liste = new int[100][2];\r\n  private int zaehler = 0;\r\n  private JPanel panel;\r\n  private int x = -10;\r\n  private int y = -10;\r\n\r\n  public Tafel() {\r\n    initialisiereTafel();\r\n  }\r\n\r\n  private void initialisiereTafel() {\r\n    this.setDefaultCloseOperation(EXIT_ON_CLOSE);\r\n    this.setBounds(0, 0, 500, 500);\r\n    this.setLocationRelativeTo(null);\r\n    this.setAlwaysOnTop(true);\r\n    this.setBackground(Color.white);\r\n    this.setTitle(\"Tafel\");\r\n    this.setLayout(null);\r\n    sichtbar();\r\n\r\n    panel = new JPanel() {\r\n\r\n      public void paintComponent(Graphics g) {\r\n        super.paintComponent(g);\r\n\r\n        for (int z = 0; z &lt; liste.length; z++) {\r\n          x = liste[z][0];\r\n          y = liste[z][1];\r\n\r\n          g.fillOval(x, y, 10, 10);\r\n        }\r\n      }\r\n\r\n    };\r\n\r\n    panel.setBackground(Color.WHITE);\r\n\r\n    panel.setBounds(0, 0, 500, 500);\r\n    this.add(panel);\r\n\r\n    panel.addMouseMotionListener(new MouseAdapter() {\r\n      public void mouseDragged(MouseEvent arg0) {\r\n        System.out.println(\"Dragged\");\r\n        x = arg0.getX();\r\n        y = arg0.getY();\r\n\r\n        liste[zaehler][0] = x;\r\n        liste[zaehler][1] = y;\r\n        zaehler++;\r\n\r\n        panel.repaint();\r\n      }\r\n    });\r\n\r\n    panel.addMouseListener(new MouseAdapter() {\r\n      public void mousePressed(MouseEvent arg0) {\r\n        System.out.println(\"Test\");\r\n        x = arg0.getX();\r\n        y = arg0.getY();\r\n\r\n        liste[zaehler][0] = x;\r\n        liste[zaehler][1] = y;\r\n        zaehler++;\r\n\r\n        panel.repaint();\r\n      }\r\n    });\r\n\r\n  }\r\n\r\n  private void sichtbar() {\r\n    this.setVisible(true);\r\n  }\r\n\r\n}<\/pre>\n<p>Die ArrayList die wir definieren ist vom Typ Point. Ein Point ist ein einfaches Objekt das zwei Koordinaten, x und y enth\u00e4lt. In den MouseListeners wird einfach ein Point hinzugef\u00fcgt (Zeile 65 und 77). Schlie\u00dflich wird nach dem Aufruf von <code>panel.repaint()<\/code> der virtuelle Bildschirm mit einer for-Schleife ausgelesen und dargestellt.<\/p>\n<p>Eine ArrayList kann nat\u00fcrlich auch mit einem Objekt gef\u00fcllt werden das wir selbst definiert haben. Zum Beispiel wollen wir nicht nur eine Point-Liste haben, sondern die Liste soll auch noch die Dicke des Pinsels speichern. Wir brauchen also ein Objekt das diese Daten speichert. Z.B. ArrayList&lt;Grafikobjekt&gt; welches dann zwei int Variablen f\u00fcr die Koordinaten sowie eine int-Variable f\u00fcr die Dicke enth\u00e4lt.<br \/>\nIm n\u00e4chsten Kapitel wollen wir solch eine Klasse erstellen.<br \/>\nHattet ihr heute schon einen Kaffee?<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Da mit super.paint(g); auch das Elternelement neu gezeichnet wird, w\u00fcrden alle alten Punkte die wir gemalt haben gel\u00f6scht werden. Das ist praktisch bei Animationen, nicht jedoch beim Zeichnen. Um daher korrekt malen zu k\u00f6nnen, m\u00fcssen wir unserem Programm beibringen es sich zu merken was schon gezeichnet wurde. Dies bewerkstelligen wir mit einer einzigen Variablen. Zum [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/posts\/469"}],"collection":[{"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/comments?post=469"}],"version-history":[{"count":13,"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":883,"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/posts\/469\/revisions\/883"}],"wp:attachment":[{"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/media?parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/categories?post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/freizone.net\/java-einfach-lernen\/wp-json\/wp\/v2\/tags?post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}