# JLabel in Vordergrund



## ankmanu (10. Feb 2010)

Hi,

ich habe in einem JFame ein Bild eingefügt, was ständig aktualisiert wird. (mit repaint(); )

Nun will ich ein JLabel vor dem Bild erscheinen lassen, gibt es da eine Möglichkeit, dieses JLabel immer im Vordergrund zu haben?

Vielen Dank im Vorraus

manu


----------



## MQue (11. Feb 2010)

Meiner Meinung nach kommt es drauf an in welcher Reihenfolge du die Komponenten auf das JFrame gibst, Ich würde zuerst das Bild zeichnen und dann immer das Label dann müsste das JLabel immer im Vordergrund sein.
Ansonsten würd ich nicht unbedingt auf dem JFrame zeichnen sondern auf das JFrame ein JPanel geben auf dem du das Bild legst und vielleicht ein weiteres JPanel auf dem dann das JLabel ist.


----------



## ankmanu (11. Feb 2010)

Hi,
danke, aber das Bild wird ständig gerepainted.. 
Wie geht das dann?

Viele Grüße

manu


----------



## Ebenius (12. Feb 2010)

Zeig mal den Code mit dem Du zeichnest! Normaler weise legt man auf ein JFrame ein JPanel als ContentPane und überschreibt dessen [c]paintComponent(Graphics)[/c]-Methode (super-Aufruf nicht vergessen!). Wenn man dann auf das ContentPane andere Komponenten drauf tut, dann wird trotzdem alles richtig gezeichnet.

Ebenius


----------



## ankmanu (12. Feb 2010)

danke,

Hier mal ein Beispiel(ist nicht der Code meines Programmes, aber ich habe es auch so gemacht...)

```
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.util.*;
import javax.media.control.*;
import javax.media.protocol.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import com.sun.image.codec.jpeg.*;
 
public class SwingCapture extends Panel implements ActionListener 
{
  public static Player player = null;
  public CaptureDeviceInfo di = null;
  public MediaLocator ml = null;
  public JButton capture = null;
  public Buffer buf = null;
  public Image img = null;
  public VideoFormat vf = null;
  public BufferToImage btoi = null;
  public ImagePanel imgpanel = null;
  private JLabel lb1;
  
  public SwingCapture() 
  {
    setLayout(new BorderLayout());
    setSize(320,550);
    
    imgpanel = new ImagePanel();
    lb1 = new JLabel("Position X");
    lb1.setSize(lb1.getPreferredSize());
    capture = new JButton("Capture");
    capture.addActionListener(this);
    
    String str1 = "vfw:Logitech USB Video Camera:0";
    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    di = CaptureDeviceManager.getDevice(str2);
    ml = di.getLocator();
    
    try 
    {
      player = Manager.createRealizedPlayer(ml);
      player.start();
      Component comp;
      
      if ((comp = player.getVisualComponent()) != null)
      {
        add(comp,BorderLayout.NORTH);
      }
      add(lb1,BorderLayout.SOUTH);
      add(capture,BorderLayout.CENTER);
      add(imgpanel,BorderLayout.SOUTH);
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
 
 
  
  public static void main(String[] args) 
  {
    Frame f = new Frame("SwingCapture");
    SwingCapture cf = new SwingCapture();
    
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      playerclose();
      System.exit(0);}});
    
    f.add("Center",cf);
    f.pack();
    f.setSize(new Dimension(320,550));
    f.setVisible(true);
  }
  
  
  public static void playerclose() 
  {
    player.close();
    player.deallocate();
  }
  
 
  public void actionPerformed(ActionEvent e) 
  {
    JComponent c = (JComponent) e.getSource();
    
    if (c == capture) 
    {
      // Grab a frame
      FrameGrabbingControl fgc = (FrameGrabbingControl)
      player.getControl("javax.media.control.FrameGrabbingControl");
      buf = fgc.grabFrame();
      
      // Convert it to an image
      btoi = new BufferToImage((VideoFormat)buf.getFormat());
      img = btoi.createImage(buf);
      
      // show the image
      imgpanel.setImage(img);
      
      // save image
      saveJPG(img,"c:\\test.jpg");
    }
  }
  
  class ImagePanel extends Panel 
  {
    public Image myimg = null;
    
    public ImagePanel() 
    {
      setLayout(null);
      setSize(320,240);
    }
    
    public void setImage(Image img) 
    {
      this.myimg = img;
      repaint();
    }
    
    public void paint(Graphics g) 
    {
      if (myimg != null) 
      {
        g.drawImage(myimg, 0, 0, this);
      }
    }
  }
  
 
  public static void saveJPG(Image img, String s)
  {
    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bi.createGraphics();
    g2.drawImage(img, null, null);
 
    FileOutputStream out = null;
    try
    { 
      out = new FileOutputStream(s); 
    }
    catch (java.io.FileNotFoundException io)
    { 
      System.out.println("File Not Found"); 
    }
    
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
    param.setQuality(0.5f,false);
    encoder.setJPEGEncodeParam(param);
    
    try 
    { 
      encoder.encode(bi); 
      out.close(); 
    }
    catch (java.io.IOException io) 
    {
      System.out.println("IOException"); 
    }
}}
```
nun soll JLabel lb1 einfach immer sichtbar sein, wie geht das?

Viele Grüße
manu


----------



## Gast2 (12. Feb 2010)

Ich würde AWT und SWING komponenten nicht mischen...


----------



## ennoente (30. Dez 2012)

Hallo,
bei mir habe ich auch erst mein Bild anzeigen lassen, und dann das JLabel, aber das Bild ist immer über dem JLabel bzw. man kann das JLabel nicht sehen.
Gibt das da einen Befehl, z.B. "JLabel.setInForeground" ?


----------



## Gast2 (30. Dez 2012)

Für die Zukunft: Mach dir für solche Fragen immer nen eigenen Thread auf.

Zu deinem Problem: Nein, so eine Methode gibts nicht. Was zuletzt gezeichnet wird ist oben, so einfach ist das 
Falls dir das noch nicht hilft, dann poste ein KSKB.


----------



## ennoente (31. Dez 2012)

Oh, tut mir leid, ich werd's in Zukunft machen! 

Uhm, also ein KSKB wäre z.B.:

```
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.ImageIcon;


public class JLabelUeberImageProblem extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * @param args
	 */
	
	static JLabel label, Schrift;
	
	public JLabelUeberImageProblem(){
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(null);
		
		Image image = Toolkit.getDefaultToolkit().createImage("C:\\Bild");	// Hier wird ein Bild aufgerufen, bei mir ein Bild von einem Monopoly-Spielbrett
		
		label = new JLabel(new ImageIcon(image));
		JScrollPane pane = new JScrollPane(label);							// Hier pack ich das Bild in ein JScrollPane, wiel es so groß ist (fuer ein Spiel)
		pane.setSize(300, 300);
		
		getContentPane().add(pane);					// Zuerst wird das JScrollPane angeschlossen...
		
		Schrift = new JLabel("AAAAAAA");									// Schriftzug, der ueber das Bild kommen soll (Beispieltest)
		Schrift.setSize(100, 50);
		Schrift.setLocation(50, 50);
		
		getContentPane().add(Schrift);					// und dann erst der Schriftzug
	}
	
	public static void main(String[] args) {
		JLabelUeberImageProblem W = new JLabelUeberImageProblem();
		
		W.setSize(300, 300);
		W.setLocation(300, 300);
		W.setVisible(true);
	}

}
```


----------



## bERt0r (31. Dez 2012)

Mein KSKB in diesem Thread macht genau das was du willst.


----------



## ennoente (31. Dez 2012)

Oh ja, perfekt! Danke


----------



## ennoente (31. Dez 2012)

Nee, bei mir klappt es doch nicht so wie geplant :/
Ich hab die Sachen jetzt schon so angeschlossen wie in deinem KSKB, aber es klappt nicht, er zeigt gar nichts an, irgendwas mache ich falsch...

```
content = new JPanel();
        Spieler1 = new JLabel("TESTTESTTESTTEST");
        Spieler1.setSize(100, 50);
//        Spieler1.setOpaque(true);
        Spieler1.setLocation(800, 100);
        
        content.add(Spieler1);
        glassPanel = new JPanel();
        glassPanel.setOpaque(false);
        glassPanel.add(Spielfeld);
        JLayeredPane p = new JLayeredPane()
            {
                @SuppressWarnings("deprecation")
                @Override
                public void reshape(int x, int y, int width, int height)
                {
                    super.reshape(x, y, width, height);
                    for (Component c : getComponents())
                    {
                        c.reshape(x, y, width, height);
                    }
                }
            };
        p.add(glassPanel, JLayeredPane.FRAME_CONTENT_LAYER);
        p.add(content, JLayeredPane.POPUP_LAYER);
```

Was mache ich hier falsch? Ich habe ein bisschen Code herausgenommen, ich glaube das ist der einzige den man hierfür braucht ("Spielfeld" ist hierbei ein JScrollPane, macht das den Fehler aus? Es beinhaltet ein großes Bild).


----------



## vanny (31. Dez 2012)

Du willst ein Hintergrund und danach dort noch irgendwelche actors drüberzeichnen?
Ich denke mal, wenn du nur den sichtbaren Ausschnitt deines "großen" Bildes zeichnest und dann dein shape, dann kommste mit einem JPanel und ner schicken paintComponent(); gut aus.

PSSuppressWarnings("deprecation") //*hust*


----------



## ennoente (1. Jan 2013)

Ja, ich hab ein Bild, das Spielfeld, und auf das sollen - je nachdem was man würfelt - irgendwo verschiedene Spielsteine hingemalt werden bzw. verschoben werden können. Ist das so kompliziert oder versteh ich da irgendetwas nicht?


----------



## vanny (1. Jan 2013)

Nö, so schwierig ist das nicht.Nur dein Ansatz macht´s nicht grad leichter:noe:

Zeichne deinen sichtbaren Hintergrundbereich in ein BufferedImage der Größe der Component(bzw. deren sichtbare Größe). Danach zeichnest du deine Spielsteine an die jeweilige position.

Dann überschreibst du die paintComponent()- Methode der anzeigenden JComponent (z.Bsp. ein JPanel) in etwa so:

```
public void paintComponent(Graphics g){
		super.paintComponent(g);
		g.drawImage(deinBufferedImage, 0, 0, null);
}
```

wenn dir einiges an meinem Vorschlag unklar ist, benutze doch mit dem neu gewonnenen Wissen die SuFu hier im Forum, gelöste Problemstellungen dieser Art gibt es hier zu Hauf.

Gruß Vanny


----------



## ennoente (3. Jan 2013)

Ist das jetzt die Methode für das Hintergrundbild oder für das daraufzusetzende JLabel?
Und was ist ein SuFu? Ich bin doof


----------



## Timothy Truckle (3. Jan 2013)

ennoente hat gesagt.:


> Und was ist ein SuFu?


Wenn der AKüFi Pause hat ist das die Suchfunktion.



ennoente hat gesagt.:


> Ich bin doof


Die ehrliche oder die höfliche Antwort? 
;o)

bye
TT


----------



## vanny (3. Jan 2013)

ennoente hat gesagt.:


> Ist das jetzt die Methode für das Hintergrundbild oder für das daraufzusetzende JLabel?



Du benötigst weder Glaspanegedönse noch ein JLabel.
Das ist eine paintComponent();-Methode, die man bei jeder JComponent oder bei Klassen, die davon erben findet und somit überschreiben kann.

Guggst du hier


----------



## ennoente (3. Jan 2013)

Diese blöden Docs helfen mir nicht weiter, wie krieg ich denn das Spielfeld in ein BufferedImage rein?
Und funktioniert das mit einem JScrollPane? Google gibt mir da auch keine Antwort...


----------



## Marcinek (3. Jan 2013)

Let me google that for you



ennoente hat gesagt.:


> Und funktioniert das mit einem JScrollPane? Google gibt mir da auch keine Antwort...



Diese blöden Fragen bringen uns auch nicht weiter.


----------



## vanny (3. Jan 2013)

Da stell ich doch auch mal ne blöde frage, wozu ne JScrollPane?
Was hast du denn bis jetzt probiert?

Versuch es doch mal step by step.
1. BufferedImage erstellen(laden/lesen)...vielleicht erstmal nur ein kleines^^
Dann natürlich auf dein Panel zeichnen das Ding
wenn das geht:
2. Teilbild mit getSubImage(); in ein zweites BufferedImage zeichenen mit Graphics2d und all dem Krams. Natürlich wieder erfolgreich auf deinem Panel zeichnen
wenn das dann auch geht:
3. wie in 2. und dann noch deine Spielsteine mit draufpinseln.(is dann übrigens das gleiche wie in 2. nur halt ein Schicht für Schicht Farbauftrag^^)

ergo benötigst du nur n bissl Struktur, Gedult und *ein einziges JPanel*

Gruß Vanny


----------



## ennoente (4. Jan 2013)

Stimmt, sry, ich fang am besten nochmal ganz von vorne an:
Also, ich hab ein Bild "Spielfeld.jpg". Das ist so groß, dass ich es in ein JScrollPane stecke.
Nun möchte ich Spielsteine auf das Bild setzen, per paint-Methode oder wie auch immer. Aber das JScrollPane mit dem Spielfeld ist immer im Vordergrund, ich möchte es aber lieber im Hintergrund haben, damit man die daraufgesetzten Spielsteine sehen kann.
Nun ist meine Frage: Wie kann ich das realisieren? Ich habe noch keine Lösung gefunden, ich habe es schon ganz oft probiert und es hat nie richtig geklappt. Außerdem: Wie kann ich bei dem JScrollPane Steine nach rechts setzen, wenn man nur den linken Ausschnitt sehen kann? Denn dann sind ja der Punkt (600, 0) auf dem Bild und der Punkt (600, 0) auf dem JFrame verschiedene Punkte. Ich hoffe jemand kann mich verstehen


----------



## vanny (4. Jan 2013)

Hier mal die Grafik, damit du mich vielleicht doch noch verstehst:

Der dunkelrote Bereich ist sichtbar und der grüne Spielstein auch, der Rest ist doch völlig redundant aus grafischer Sicht.
Ergo, zeichne nur was du siehst und gut ist.
Was du dazu benötigst steht in den Posts zuvor.

Gruß Vanny


----------

