# Würfel zeichnen ?



## Hertz (27. Feb 2012)

Hallo,

Habe ein Frage zum unteren Code.

Es wird die Anzahl Würfel gewählt, unde auf einem Label das Resultat der einzelnen Würfel, nebeneinander dargestellt.
Zusätzlich wollte ich Grafikwürfel, auf dem Panel erscheinen lassen. 
Hier bin ich mir nicht sicher, ob das mit den if-bedingungen ok ist. 
Habe in actionPerformed, etwas mit validate(), repaint(), und JPanel probiert, wobei das panel leer bleibt?


```
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class WürfelSpiel1 {
 public static void main(String[] args) {
  WürfelSpiel1 wu = new WürfelSpiel1();
  wu.getGuiPanel();
 }
 int z;
 JLabel label;
 JComboBox anzahlWürfel;
 JFrame frame;
 JPanel panel;

 public void getGuiPanel() {
  frame = new JFrame();
  frame.setSize(300,300);
  frame.setVisible(true);
  panel = new JPanel();
  JButton button = new JButton("Wirf!");
  String[] wahl = {"1", "2", "3", "4", "5"};
  anzahlWürfel = new JComboBox(wahl);
  label = new JLabel("hier erscheinen gleich die Augenzahlen");
  button.addActionListener(new WurfListener());
  panel.add(anzahlWürfel);
  panel.add(button);
  panel.add(label);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.getContentPane().add(panel);
 }

 public class WurfListener implements ActionListener {
  public void actionPerformed(ActionEvent ev) {
   //würfeln
   String augenZahl = "";
   String auswahl = (String) anzahlWürfel.getSelectedItem();
   int anzahlZuWerfende = Integer.parseInt(auswahl);
   for (int i = 0; i < anzahlZuWerfende; i++) {
    z = (int) ((Math.random() * 6) +1);
    augenZahl += (" " + z);
    Grafikwürfel w = new Grafikwürfel();
    frame.repaint();
   }
   label.setText(augenZahl);
  }
 }

 class Grafikwürfel extends JPanel {
  public void paintComponent(Graphics g) {
   if(z == 1) {
    g.setColor(Color.black);
    g.fillRect(350,350,90,90);
    g.setColor(Color.white);
    g.fillOval(385,385,20,20);
   }

   if(z == 2) {
    g.setColor(Color.blue);
    g.fillRect(750,350,90,90);
    g.setColor(Color.green);
    g.fillOval(750,350,20,20);
    g.fillOval(820,420,20,20);
   }

   if(z == 3) {
    g.setColor(Color.yellow);
    g.fillRect(850,350,90,90);
    g.setColor(Color.red);
    g.fillOval(850,350,20,20);
    g.fillOval(885,385,20,20);
    g.fillOval(920,420,20,20);
   }

   if(z == 4) {
    g.setColor(Color.green);
    g.fillRect(650,350,90,90);
    g.setColor(Color.cyan);
    g.fillOval(650,350,20,20);
    g.fillOval(650,420,20,20);
    g.fillOval(720,350,20,20);
    g.fillOval(720,420,20,20);
   }

   if(z == 5) {
    g.setColor(Color.pink);
    g.fillRect(450,350,90,90);
    g.setColor(Color.black);
    g.fillOval(450,350,20,20);
    g.fillOval(520,350,20,20);
    g.fillOval(485,385,20,20);
    g.fillOval(450,420,20,20);
    g.fillOval(520,420,20,20);
   }

   if(z == 6) {
    g.setColor(Color.darkGray);
    g.fillRect(550,350,90,90);
    g.setColor(Color.magenta);
    g.fillOval(560,350,20,20);
    g.fillOval(560,385,20,20);
    g.fillOval(560,420,20,20);
    g.fillOval(610,350,20,20);
    g.fillOval(610,385,20,20);
    g.fillOval(610,420,20,20);
   }
  }
 }
}
```

Vielen Dank für die Hilfe
H.


----------



## SlaterB (27. Feb 2012)

ohne add() geht gar nix

stelle aber lieber am Anfang die GUI komplett zusammen, ändere später nur die Werte fürs (erneute) paintComponent,
ohne super-Aufruf oder Löschen dürfte dort übrigens alles übereinandergemalt werden,
kein Grundlagen-Beispiel vorher angeschaut?


----------



## Hertz (27. Feb 2012)

Danke für die Antwort, leider hab ich nichts konkretes gefunden als Grundlagenbeispiel, müsste wohl mehr surfen.

Das mit dem add(), meinst du so was [c]panel.add(BorderLayout.SOUTH, w);[/c] ?

Mit dem übermalen wirds ein Problem sein. Wie meinst du das mit dem super-Aufruf und dem löschen?


----------



## SlaterB (27. Feb 2012)

> Das mit dem add(), meinst du so was panel.add(BorderLayout.SOUTH, w); ?

etwas abwegig, wo du doch vorher drei andere Komponenten einfach nur mit add() hinzugefügt hast?:

```
panel.add(anzahlWürfel);
  panel.add(button);
  panel.add(label);
```
ein BorderLayout ist in panel ja auch gar nicht vorhanden

du solltest schon ungefähr eine Vorstellung von Layout usw. haben,
jedenfalls mindestens die Komponente erfolgreich am Anfang einfügen,
nicht gleichzeitig mit komplizierten Button/ späteren Einfügen auch noch grundsätzliche add()-Probleme angehen

> Wie meinst du das mit dem super-Aufruf und dem löschen? 

etwa
Galileo Computing :: Java ist auch eine Insel - 14 Einführung in grafische Oberflächen
14.9.3 Zeichnen von Inhalten auf ein JFrame
das erste Beispiel lautet

```
package com.tutego.insel.ui.graphics;

import java.awt.Graphics;
import javax.swing.*;

class DrawPanel extends JPanel
{
  @Override
  protected void paintComponent( Graphics g )
  {
    super.paintComponent( g );
    g.drawLine( 10, 10, 100, 50 );
  }
}
```

zudem steht da noch der Satz


> Der Aufruf von super.paintComponent() ist immer dann angebracht, wenn die Oberklasse ihre Inhalte zeichnen soll. Bei vollständig eigenem Inhalt ist das nicht notwendig.


ok, spricht etwas gegen mich,
erst bei mehrfachen Zeichnen wird man schon merken ob jedes Zeichnen über den anderen stattfindet
oder zwischendurch  das vorher gezeichnete entfernt wird,
das ist so früh noch nicht besprochen in dem Link


----------



## Hertz (27. Feb 2012)

Das mit dem Layout war ein Fehler. Der BorderLayout ist der standard Layout für frames, und FlowLayout für panels. 

Hab den Link gelesen Danke. Jedoch frage ich mich, wie das im Zitat gemeint ist, bezogen auf diesen code. Ob das ein vollständiger eigener Inhalt ist.
Wobei welche Oberklasse zeichnet ihre Inhalte, seh nicht ganz in der Hirarchie durch?


Habe diesen Code in ActionPerformed gesetzt?

```
Grafikwürfel w = new Grafikwürfel();
    panel.add(w);
    panel.validate();
```

Vielen Dank
H.


----------



## SlaterB (27. Feb 2012)

> Wobei welche Oberklasse zeichnet ihre Inhalte, seh nicht ganz in der Hirarchie durch?

nenn es einfach Swing, Swing macht schon was, z.B. eingefügte Buttons auch noch malen,
wobei ich persönlich nie empfehle, in einem Panel mit überschriebener paintComponent noch Komponenten reinzusetzen,

worauf ich mich die ganze Zeit bezog war ein einfaches Löschen der Anzeige des Panels vor jedem paintComponent, etwa bei repaint(), 
kann man durch eigene Zeichenbefehle, z.B. drawRect() in Hintergrundfarbe, natürlich genauso hinbekommen


----------



## Hertz (27. Feb 2012)

Hi,

Leider funktioniert noch nicht so wie es sollte, also die Combobox und das Label werden angezeigt.
Aber es wird nichts gezeichnet.

Die actionPerformed Klasse sieht momentan so aus.


```
public class WurfListener implements ActionListener {
  public void actionPerformed(ActionEvent ev) {
   //würfeln
   String augenZahl = "";
   String auswahl = (String) anzahlWürfel.getSelectedItem();
   int anzahlZuWerfende = Integer.parseInt(auswahl);
   for (int i = 0; i < anzahlZuWerfende; i++) {
    z = (int) ((Math.random() * 6) +1);
    augenZahl += (" " + z);
    Grafikwürfel w = new Grafikwürfel();
    panel.add(w);
    panel.repaint();
    panel.validate();
   }
   label.setText(augenZahl);
  }
 }
```

Was müsste man ändern?


----------



## SlaterB (27. Feb 2012)

noch einmal: funktioniert es ohne ActionListener, wenn du einfach nur am Anfang ein Panel einfügst (zum Rest)?
versuche doch erst die einfachen Varianten..

was du dagegen kaum wissen kannst, durchaus viele Gemeinheiten bei Swing:
ich vermute hier das Problem, dass dein Panel die Größe 1x1 Pixel hat, setze setPreferredSize(),
wenn du ein derartiges Panel in ein BorderLayout (wie das JFrame/ ContentPane es hat) einfügst, wird es maximiert,
beim FlowLayout eines anderen Panel nicht


----------



## Hertz (27. Feb 2012)

Ja stimmt, habe jetzt den panel auf BorderLayout.NORTH gesetzt und Borderlayout.CENTER für das zeichnen. 
Vielleicht nicht so optimal, da im Lehrbuch drauf hingewiesen wurde JPanel über JFrame zusetzen.

Ok, jetzt müsste man nur noch die Würfel dazu bringen, mehrmals zu erscheinen, meld mich sonst wieder.

Vielen Dank für die Hilfe.

Good Night
H.


----------

