Hintergrundbild in eine GUI einfügen (Java): Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
(Die Seite wurde neu angelegt: „Kategorie:Java-Codeschnipsel Standard-GUIs sind langweilig? Zur Illustration kann man Swing-GUIs in Java relativ einfach mit einem Hintergrundbild versehen…“)
 
K
 
(7 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 +
[[Kategorie:Swing]]
 
[[Kategorie:Java-Codeschnipsel]]
 
[[Kategorie:Java-Codeschnipsel]]
Standard-GUIs sind langweilig? Zur Illustration kann man Swing-GUIs in Java relativ einfach mit einem Hintergrundbild versehen.
+
[[Datei:BackgroundImage-Test.png|mini|Hintergrundbild in einem Fenster]]
 +
'''Standard-GUIs sind langweilig?''' Zur Illustration kann man nur Teile oder auch die komplette Swing-[[GUI]] in Java relativ einfach mit einem Hintergrundbild versehen.
  
Folgende [[Klasse]] erbt von {{JAPI|JPanel}} und kann daher relativ flexibel in einer [[GUI]] eingesetzt werden.
+
Folgende [[Klasse]] erbt von {{JAPI|JPanel}} und kann daher relativ flexibel in einer [[GUI]] eingesetzt werden. Sie ist in der Lage, neben der Aufnahme weiterer GUI-Komponenten außerdem auch ein Hintergrundbild zu empfangen und dieses nach bestimmten Kriterien zu zeichnen.
 +
 
 +
Man kann bspw. bestimmen, ob das Hintergrundbild immer an die aktuellen Dimensionen des einbettenden Panels angepasst werden soll. Damit wäre sichergestellt, dass das gesamte Bild jederzeit sichtbar ist. Allerdings hat das auch einen Nebeneffekt. Es kann passieren, dass das Bild verzerrt dargestellt wird, was insbesondere bei Fotos störend sein kann.
 +
 
 +
Man kann auch festlegen, dass das Bild nicht verzerrt werden darf. Dann wird je nach Dimension des JPanels ggf. nur ein Teil des gesamten Bildes dargestellt.
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
  class BackgroundImagePanel extends JPanel {
+
import java.awt.*;
      private Image image;
+
import javax.swing.*;
       private boolean fitImage;
+
 
 +
/*
 +
* BackgroundImagePanel ist in der Lage ein Hintergrundbild zu empfangen und dieses zu zeichnen.
 +
*
 +
* @author Gernot Segieth
 +
*/
 +
class BackgroundImagePanel extends JPanel {
 +
  private Image image;
 +
  private boolean fitImage;
 +
 
 +
  /**
 +
    * Erzeugt ein BackgroundImagePanel, das sich zunächst wie ein "normales" JPanel verhält.
 +
    */
 +
  BackgroundImagePanel() {
 +
      super();
 +
  }
 +
 
 +
  /**
 +
    * Erzeugt ein BackgroundImagePanel, das sich zunächst wie ein "normales" JPanel verhält.
 +
    *
 +
    * @param layout ein LayoutManager zur Anordnung von GUI-Komponenten für das Panel.
 +
    */
 +
  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
 +
    * <b>oder in Format und Dimension des Panels ausgeben werden.</b>
 +
    *
 +
    * @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();
 +
  }
  
      /**
+
  /**
      * Erzeugt ein BackgroundImagePanel, das sich zunächst wie ein "normales" JPanel verhält.
+
    * @see javax.swing.JComponent#getPreferredSize()
      */
+
    */
       BackgroundImagePanel() {
+
  @Override
         super();
+
  public Dimension getPreferredSize() {
 +
       if(image != null) {
 +
         return new Dimension(image.getWidth(this), image.getHeight(this));
 
       }
 
       }
 +
      return super.getPreferredSize();
 +
  }
  
      /**
+
  /**
      * Erzeugt ein BackgroundImagePanel, das sich zunächst wie ein "normales" JPanel verhält.
+
    * @see javax.swing.JComponent#paintComponent(Graphics g)
      *
+
    */
      * @param layout ein LayoutManager zur Anordnung von GUI-Komponenten für das Panel.
+
  @Override
      */
+
  protected void paintComponent(Graphics g) {
      BackgroundImagePanel(LayoutManager layout) {
+
      super.paintComponent(g);
         super(layout);
+
      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);
 +
        }
 
       }
 
       }
 +
  }
 +
}
 +
</syntaxhighlight>
 +
 +
==GUI mit Hintergrundbild zusammenbauen==
 +
Mit dieser eben vorgestellten Spezialkomponente zum Zeichen von Hintergrundbildern können wir nun eine GUI so programmieren, dass wir ein {{JAPI|JFrame}} erhalten, der ein Hintergrundbild enthalten wird. Das erreichen wir, indem wir unser '''BackgroundImagePanel''' direkt in den CENTER-Bereich des [[BorderLayout|BorderLayouts]] unseres JFrames einbauen.
 +
<syntaxhighlight lang="java">
 +
import java.awt.*;
 +
import javax.swing.*;
 +
import javax.imageio.*;
 +
import java.io.*;
 +
import java.net.*;
  
       /**
+
public class BackgroundImageTest {
      * Nimmt das zu zeichnende Bild entgegen und nimmt Einstellungen vor, die das Hintergrundbild im Originalformat
+
  public BackgroundImageTest() {
      * und in den Original-Dimensionen ausgeben werden.
+
       Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
      *
+
      JFrame frame = new JFrame("BackgroundImage-Test");
      * @param image das zu zeichnende Bild
+
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      */
+
      frame.add(createMainPanel());
       void setImage(Image image) {
+
      frame.setSize(size.width * 70 / 100, size.height * 70 / 100);
         this.setImage(image, false);
+
      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());
      * Nimmt das zu zeichnende Bild entgegen und nimmt Einstellungen vor, die das Hintergrundbild im Originalformat
+
      mainPanel.setImage(image); //hier kann man einstellen, ob das Bild im Original oder eingepasst ausgegeben werden soll (true/false)
      * und und in den Original-Dimensionen oder in Format und Dimension des Panels ausgeben werden.
+
 
      *
+
       JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
      * @param image das zu zeichnende Bild
+
      southPanel.setOpaque(false); //entscheidet, ob das Button-Panel durchsichtig sein soll
      * @param fitImage bei Übergabe von true wird das Bild immer an die Größe des Panel angepasst (kann zu Verzerrung führen),
+
      southPanel.add(createButtonPanel(southPanel.isOpaque()));
      * ansonsten wird immer das Original gezeichnet.
+
 
      */
+
      mainPanel.add(southPanel, BorderLayout.SOUTH);
       void setImage(Image image, boolean fitImage) {
+
       return mainPanel;
        this.image = image;
+
  }
        this.fitImage = fitImage;
 
        validate();
 
        repaint();
 
       }
 
  
      /**
+
  //erzeugt ein Panel mit Buttons, bei Übergabe von true wird das Panel undurchsichtig
      * @see javax.swing.JComponent#getPreferredSize()
+
  private JPanel createButtonPanel(boolean opaque) {
      */
+
       JPanel panel = new JPanel(new GridLayout(1, 0, 5, 5));
       @Override
+
      panel.setOpaque(opaque);
      public Dimension getPreferredSize() {
+
      panel.add(new JButton("Abbrechen"));
        if(image != null) {
+
      panel.add(new JButton("OK"));
            System.out.println(this.getSize());
+
      //Ereignisverarbeitung fehlt!
            return new Dimension(image.getWidth(this), image.getHeight(this));
+
      return panel;
        }
+
  }
  
         return super.getPreferredSize();
+
  public static void main(String[] args) {
 +
      try {
 +
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
 +
      } catch(Exception e) {
 +
         System.err.println(e);
 
       }
 
       }
  
       /**
+
       SwingUtilities.invokeLater(new Runnable() {
      * @see javax.swing.JComponent#paintComponent(Graphics g)
+
         public void run() {
      */
+
             new BackgroundImageTest();
      @Override
 
      protected void paintComponent(Graphics g) {
 
         super.paintComponent(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);
 
            }
 
 
         }
 
         }
       }
+
       });
 
   }
 
   }
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
==Siehe auch==
 +
*[[LayoutManager]]
 +
*[[Grafikdateien laden und anzeigen (Java)]]

Aktuelle Version vom 22. Oktober 2018, 12:52 Uhr

Hintergrundbild in einem Fenster

Standard-GUIs sind langweilig? Zur Illustration kann man nur Teile oder auch die komplette Swing-GUI in Java relativ einfach mit einem Hintergrundbild versehen.

Folgende Klasse erbt von JPanel und kann daher relativ flexibel in einer GUI eingesetzt werden. Sie ist in der Lage, neben der Aufnahme weiterer GUI-Komponenten außerdem auch ein Hintergrundbild zu empfangen und dieses nach bestimmten Kriterien zu zeichnen.

Man kann bspw. bestimmen, ob das Hintergrundbild immer an die aktuellen Dimensionen des einbettenden Panels angepasst werden soll. Damit wäre sichergestellt, dass das gesamte Bild jederzeit sichtbar ist. Allerdings hat das auch einen Nebeneffekt. Es kann passieren, dass das Bild verzerrt dargestellt wird, was insbesondere bei Fotos störend sein kann.

Man kann auch festlegen, dass das Bild nicht verzerrt werden darf. Dann wird je nach Dimension des JPanels ggf. nur ein Teil des gesamten Bildes dargestellt.

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

/*
 * BackgroundImagePanel ist in der Lage ein Hintergrundbild zu empfangen und dieses zu zeichnen.
 *
 * @author Gernot Segieth
 */
class BackgroundImagePanel extends JPanel {
   private Image image;
   private boolean fitImage;

   /**
    * Erzeugt ein BackgroundImagePanel, das sich zunächst wie ein "normales" JPanel verhält.
    */
   BackgroundImagePanel() {
      super();
   }

   /**
    * Erzeugt ein BackgroundImagePanel, das sich zunächst wie ein "normales" JPanel verhält.
    *
    * @param layout ein LayoutManager zur Anordnung von GUI-Komponenten für das Panel.
    */
   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
    * <b>oder in Format und Dimension des Panels ausgeben werden.</b>
    *
    * @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) {
         return new Dimension(image.getWidth(this), image.getHeight(this));
      }
      return super.getPreferredSize();
   }

   /**
    * @see javax.swing.JComponent#paintComponent(Graphics g)
    */
   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(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);
         }
      }
   }
}

GUI mit Hintergrundbild zusammenbauen

Mit dieser eben vorgestellten Spezialkomponente zum Zeichen von Hintergrundbildern können wir nun eine GUI so programmieren, dass wir ein JFrame erhalten, der ein Hintergrundbild enthalten wird. Das erreichen wir, indem wir unser BackgroundImagePanel direkt in den CENTER-Bereich des BorderLayouts unseres JFrames einbauen.

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;
   }

   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();
         }
      });
   }
}

Siehe auch