# Kreis in Jlabel darstellen.



## trndtap (3. Jan 2013)

Hallo. 

Ich möchte Kreise auf einem JLabel darstellen. Von 1 bis zu 5 Kreisen.
Als Test habe ich gerade mal in Paint einen einfachen Kreis gemalt mit
transparentem Hintergrund und das ganze dann in mein JLabel mit 
GridLayout(0, 5) geadded (geadded habe ich in Wahrheit ein weiteres
JLabel mit setIcon(Mein Bild). Das Ergebniss war Katastrophal 

Man sieht, dass sich in dem 1/5 Bereich des JLabels etwas drüber 
gelegt hat, aber was ist nicht zu erkennen. Auch die Transparenz 
scheint ignoriert zu werden.

Wie macht man sowas am besten? Kann man das ganze mit Java
vielleicht direkt auf das Label drauf zeichnen wenn es so was 
banales wie ein Kreis ist?

Wichtig ist, dass der Hintergrund wirklich transparent ist.


----------



## Marco13 (3. Jan 2013)

Warum ein JLabel? Zum Zeichnen nimmt man üblicherweise ein eigenes JPanel...Malen in Swing Teil 1: der grundlegende Mechanismus ? Byte-Welt Wiki


----------



## trndtap (4. Jan 2013)

Ok, danke für den Hinweis 

Ich hab dann mal folgende Klasse implementiert:


```
public class CellCoin extends JComponent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 
	 */
	public CellCoin() {
		this.repaint();
	}
	
	/**
	 * 
	 */
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		Ellipse2D ellipse = new Ellipse2D.Float(10f,10f,10f,10f);
		
		Graphics2D g2d = (Graphics2D) getGraphics();
		g2d.clearRect(0, 0, getWidth(), getHeight());
		g2d.setColor(new Color(255, 0, 0));
		g2d.fill(ellipse);
		g2d.draw(ellipse);
	}
}
```

Und füge diese Klasse meinem JLabel mit dem GridLayout(0, 5) hinzu.
Das mache ich in meiner Klasse Cell durch einen Methodenaufruf
im Konstruktor:


```
private void updateCoins(int coins) {
	coinsOutput.removeAll();
		
	for(int i = 0; i < coins; i++) {
		coinsOutput.add(new CellCoin());
	}
		
	this.validate();
	this.repaint();
}
```

coinsOutput ist hierbei das JLabel().

Allerdings passiert hierbei garnichts ^^. Also die Methoden werden aufgerufen, 
dass habe ich durch ein System.out geprüft, allerdings wird nichts angezeigt


----------



## bERt0r (4. Jan 2013)

Du musst deinem JComponent eine preferredSize verpassen, sonst ist der 0x0 Pixel groß.


----------



## trndtap (4. Jan 2013)

Ehrlich?

Ich war der Meinung das ein GridLayout für die Größe der Componente sorgt.
Wenn ich z.B. einen JButton hinzufüge ist er sofort genau so groß wie die 
vom Layout zur Verfügung gestellte Fläche.

(also 1/5 vom JLabel).


----------



## trndtap (4. Jan 2013)

Und wie ichs mir gedacht habe bringt ein setPreferredSize() nichts 

Ich habe übrigens noch was geändert was meiner Meinung nach falsch war:


```
private void updateCoins(int coins) {
    coinsOutput.removeAll();
        
    for(int i = 0; i < coins; i++) {
        coinsOutput.add(new CellCoin());
    }
        
    coinsOutput.validate();
    coinsOutput.repaint();
}
```

Das validate() und repaint() muss aufs Jlabel, nicht auf die übergeordnete Komponente, oder?

Jedenfalls gehts so auch nicht


----------



## Marco13 (4. Jan 2013)

Poste am besten mal ein KSKB


----------



## trndtap (4. Jan 2013)

As you wish 


```
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Cell extends JPanel {
	private static final long serialVersionUID = 1L;
	private JLabel coinsOutput = null;
	private int cellID = 0;
	private int coins = 0;
	private boolean choosed = false;

	public Cell(int cellID, int coins) {
		this.cellID = cellID;
		this.coins = coins;
		
		this.setLayout(new GridLayout(0, 1));
		this.setPreferredSize(new Dimension(120, 40));
		this.setBorder(BorderFactory.createLineBorder(Color.black));
		this.setBackground(new Color(220, 220, 220));
		
		this.coinsOutput = new JLabel();
		this.coinsOutput.setLayout(new GridLayout(0, 5));
		this.coinsOutput.setFont(new Font("Monospaced", Font.PLAIN, 20));
		this.coinsOutput.setHorizontalAlignment(JLabel.CENTER);
		this.coinsOutput.setVerticalAlignment(JLabel.CENTER);
		
		this.add(this.coinsOutput);
		this.updateCoins(this.coins);
	}
	
	public int getCellID() {
		return cellID;
	}
	public void setCellID(int cellID) {
		this.cellID = cellID;
	}
	private void updateCoins(int coins) {
		coinsOutput.removeAll();
		
		for(int i = 0; i < coins; i++) {
			coinsOutput.add(new CellCoin());
		}
		
		coinsOutput.validate();
		coinsOutput.repaint();
	}
	public boolean isChoosed() {
		return choosed;
	}
	public void setChoosed(boolean choosed) {
		this.choosed = choosed;
		
		if(choosed) {
			this.setBackground(new Color(220, 220, 220));
		} else {
			this.setBackground(new Color(220, 100, 0));
		}
	}
	public String getCoinsOutput() {
		return coinsOutput.getText();
	}
	public void setCoinsOutput(String coinsOutput) {
		this.coinsOutput.setText(coinsOutput);
	}
}
```


```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

import javax.swing.JComponent;

public class CellCoin extends JComponent {
	private static final long serialVersionUID = 1L;

	public CellCoin() {}
	
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		Ellipse2D ellipse = new Ellipse2D.Float(10f,10f,10f,10f);
		
		Graphics2D g2d = (Graphics2D) getGraphics();
		g2d.clearRect(0, 0, getWidth(), getHeight());
		g2d.setColor(new Color(255, 0, 0));
		g2d.fill(ellipse);
		g2d.draw(ellipse);
	}
}
```


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

public class Field extends JFrame {
	private static final long serialVersionUID = 1L;
	private JPanel mainPanel = new JPanel();
	private int amountCells = 0;
	
	public Field(int amountCells) {
		this.amountCells = amountCells;
		
		this.setTitle("BLA");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setResizable(false);
		
		for(int i = 0; i < this.amountCells; i++) {
			mainPanel.add(new Cell(i, 5));
		}
		
		this.add(mainPanel);
		this.pack();
		this.setLocationRelativeTo(null);
		this.setVisible(true);
	}

	public static void main(String[] args) {
		new Field(4);
	}
}
```


----------



## trndtap (4. Jan 2013)

Hallo,

habe den Fehler gefunden.
War mal wieder ganz einfach.


```
protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        Ellipse2D ellipse = new Ellipse2D.Float(10f,10f,10f,10f);
        
        Graphics2D g2d = (Graphics2D) getGraphics(); // hier ist der Fehler. statt gegGraphics() einfach g
        g2d.clearRect(0, 0, getWidth(), getHeight());
        g2d.setColor(new Color(255, 0, 0));
        g2d.fill(ellipse);
        g2d.draw(ellipse);
    }
```


----------



## trndtap (4. Jan 2013)

Dennoch eine Frage:

Der Kreis wird gezeichnet und ein Weißer Hintergrund wird dahinter
erzeugt. Gibt es eine Möglichkeit diesen Transparent zu machen?


----------



## Marco13 (4. Jan 2013)

Notiz an mich: Die übliche Vorgehensweise, bei ALLEN Fragen, die hier zum Zeichnen gestellt werden, erstmal mit der Browsersuche nach "getGraphics" zu suchen, und ggf. darauf hinzuweisen, dass man das nicht verwenden darf, in Zukunft selbst dann anwenden, wenn jemand schon paintComponent überschreibt. 

Graphics2D g2d = (Graphics2D) g;

(Zu 'Cell.java': Einem Label (coinsOutput) ein neues Layout zu verpassen könnte (!) zu Problemen führen. Die meisten Swing-Components, die NICHT reine Zeichen/Container-Components sind (d.h. praktisch alle außer JPanel) haben schon ein bestimmtes Layout, das evtl. schon verwendet wird und nicht geändert werden sollte. OB das hier bei einem JLabel wirklich problematisch ist, weiß ich nicht auswendig, aber es KÖNNTE eben sein...)


EDIT: Weitere Notiz an mich: Nachdem jemand ein KSKB gepostet hast, vor dem Ausprobieren erstmal noch ein bißchen warten, weil der Ersteller damit seinen Fehler vielleicht schon selbst findet :autsch:

Und noch eine: Vor dem Antworten nochmal "Reload" machen, weil vielleicht ein Gast noch was geschrieben hat.


----------



## trndtap (4. Jan 2013)

Das sind so einige Notitzen 

Wie siehts aus mit der Transparenz? Oder muss ich das mit Images machen.
Das wär bisl doof


----------



## Marco13 (4. Jan 2013)

Reicht's nicht einfach das clearRect rauszuwerfen (das ohnehin nicht verwendet werden sollte)? Ggf. noch im Konstruktor der Component
setOpaque(false);
aufrufen


----------



## trndtap (4. Jan 2013)

Tatsache, es reicht  thx


----------

