JLayeredPane auf JPanel?

Hallo Leute,

ich habe eine Frage an euch.

Ich habe ein JFrame mit einem BorderLayout.
Am Ende des JFrames habe ich ein JPanel platziert auf diesem befinden sich ein paar buttons.
Nun möchte ich ein Hintergrundbild auf dem Jpanel setzen, was aber nicht so einfach funktioniert.
Daher dachte ich mir, ich setze auf das JPanel ein JLayeredPane mit zwei ebenen (new Integer(0) & new integer(1)). Auf 0 habe ich ein JLabel das mit einem Bild bestückt wird und auf 1 werden die Buttons dargestellt.

Nun werden die Buttons angezeigt nur das JLabel zeigt kein Bild an.
Pfad zum Bild passen und die programmierung auch.

Nun Frage ich mich, ob das prinzipiel überhaupt so funktionieren kann?

JFrame mit JLayeredPane und JPanel funktioniert, habe ich schon gemacht, nur JFrame mit JPanel & JLayeredPane??

Mal abgesehen von meinem obligatorischen Rat auf JavaFX und dem SceneBuilder zu setzen:

  • hast du mal versucht das JLabel einzeln anzuzeigen?

  • ist die Größe des JLabels richtig eingestellt das es den Hintergrund auch ausfüllt?

Ja, auch ohne Button wird das Label nicht angezeigt.
Ich habe auch mal das Bild durch einen eingefärbten Hintergrund ersetzt, funktioniert auch nicht.

Ohne Code wirds schwierig.

https://docs.oracle.com/javase/tutorial/uiswing/components/panel.html : “In many types of look and feel, panels are opaque by default.”

Schau mal ob’s geht, wenn du

aufDemVorderenPanel.setOpaque(false);

aufrufst. Ansonsten, ja: Mehr code…

Hier mal ein vollständiges Beispiel eines JFrames mit einem JPanel, das ein Hintergrundbild zeichnen kann. In einem weiteren JPanel werden ein paar Dummy-Buttons angezeigt.

Lies dir die Anmerkungen durch, spiele etwas mit dem Code an den beschriebenen Stellen und sieh, wie sich das Programm verhält.

import java.awt.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;
import java.net.*;

public class BackgroundImageTest {
   public BackgroundImageTest() {
      Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
      JFrame frame = new JFrame("BackgroundImage-Test");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.add(createMainPanel());
      frame.setSize(size.width * 70 / 100, size.height * 70 / 100);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   private JPanel createMainPanel() {
      Image image = null;
      String url = "http://hintergrundbild.org/wallpaper/full/b/d/7/43686-beautiful-hintergrundbilder-fuer-samsung-tablet-1920x1080-fuer-android-40.jpg";
      try {
         image = ImageIO.read(new URL(url));
      } catch(IOException ioe) {
         JOptionPane.showMessageDialog(null,
            "Das Hintergrundbild konnte nicht geladen werden!\n" + ioe.getLocalizedMessage(),
            ioe.getClass().getName(),
            JOptionPane.WARNING_MESSAGE);
      }

      BackgroundImagePanel mainPanel = new BackgroundImagePanel(new BorderLayout());
      mainPanel.setImage(image); //hier kann man einstellen, ob das Bild im Original oder eingepasst ausgegeben werden soll (true/false)

      JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
      southPanel.setOpaque(false); //entscheidet, ob das Button-Panel durchsichtig sein soll
      southPanel.add(createButtonPanel(southPanel.isOpaque()));

      mainPanel.add(southPanel, BorderLayout.SOUTH);
      return mainPanel;
   }

   //erzeugt ein Panel mit Buttons, bei Übergabe von true wird das Panel undurchsichtig
   private JPanel createButtonPanel(boolean opaque) {
      JPanel panel = new JPanel(new GridLayout(1, 0, 5, 5));
      panel.setOpaque(opaque);
      panel.add(new JButton("Abbrechen"));
      panel.add(new JButton("OK"));
      //Ereignisverarbeitung fehlt!
      return panel;
   }

   class BackgroundImagePanel extends JPanel {
      private Image image;
      private boolean fitImage;

      BackgroundImagePanel() {
         super();
      }

      BackgroundImagePanel(LayoutManager layout) {
         super(layout);
      }

      /**
       * Nimmt das zu zeichnende Bild entgegen und nimmt Einstellungen vor, die das Hintergrundbild im Originalformat
       * und in den Original-Dimensionen ausgeben werden.
       *
       * @param image das zu zeichnende Bild
       */
      void setImage(Image image) {
         this.setImage(image, false);
      }

      /**
       * Nimmt das zu zeichnende Bild entgegen und nimmt Einstellungen vor, die das Hintergrundbild im Originalformat
       * und und in den Original-Dimensionen oder in Format und Dimension des Panels ausgeben werden.
       *
       * @param image das zu zeichnende Bild
       * @param fitImage bei Übergabe von true wird das Bild immer an die Größe des Panel angepasst (kann zu Verzerrung führen),
       * ansonsten wird immer das Original gezeichnet.
       */
      void setImage(Image image, boolean fitImage) {
         this.image = image;
         this.fitImage = fitImage;
         validate();
         repaint();
      }

      /**
       * @see javax.swing.JComponent#getPreferredSize()
       */
      @Override
      public Dimension getPreferredSize() {
         if(image != null) {
            System.out.println(this.getSize());
            return new Dimension(image.getWidth(this), image.getHeight(this));
         }

         return super.getPreferredSize();
      }

      @Override
      protected void paintComponent(Graphics g) {
         if(image != null) {
            if(fitImage) {
               Dimension size = this.getSize();
               g.drawImage(image, 0, 0, size.width, size.height, this);
            } else {
               g.drawImage(image, 0, 0, this);
            }
         }
      }
   }

   public static void main(String[] args) {
      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch(Exception e) {
         System.err.println(e);
      }

      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            new BackgroundImageTest();
         }
      });
   }
}

BackgroundImage-Test

Leider tut das Programm bei mir gar nichts. Es öffnet sich kein Fenster, es kommt auch keine Meldung, nur das rote Quadrat von Eclipse zeigt an, dass es läuft.

Das kann ich nicht nachvollziehen…

Schreib mal in die Zeile vor
return super.getPreferredSize();
eine Konsolenausgabe. Bekommst du die dann nach Kompilieren und Ausführen zu sehen?

Bei mir geht’s auch. Kann es sein, dass er bei einer seeeehr langsamen Netzverbindung (oder wenn er hinter irgendeiner Firmenproxywall hängt) ein Problem mit dem Bild hat? Ggf. mal ein lokales JPG versuchen - ist aber nur wild geraten, eigentlich sieht sonst im Code alles OK aus…

1 Like

Ja daran wird es liegen, während ich gestern nichts bekam, war da heute immerhin ein Kasten mit “Das Hintergrundbild kann nicht geladen werden! Can’t get input stram from URL!” und dem Titel “javax.imageio.IIOE.exception”.

Ist bestimmt die Firmen-Proxy-Geschichte.

Danke für eure Hilfe!

Es funktioniert nun.

SG