2016-08-23 2 views
0

Ich versuche, ein JLabel mit einem ovalen Bild, wie folgt zu erstellen.Erstellen Sie einen anklickbaren Bereich rund um JLabel Bild

enter image description here

Mein Code ist folgende:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Image; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.BorderFactory; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingUtilities; 

public final class RoundedButtonDemo { 
    private static Image bi; 

    public static void main(String[] args) { 
     try { 
      loadImage(); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        createAndShowGUI(); 
       } 
      }); 
     } catch (IOException e) { 
      // handle exception 
     } 
    } 

    private static void loadImage() throws IOException { 
     int newWidth = 80; 
     int newHeight = 40; 
     bi = ImageIO.read(RoundedButtonDemo.class.getResource("/resources/login.png")); 
     bi = bi.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT); 

    } 

    private static void createAndShowGUI() { 
     final JFrame frame = new JFrame(); 
     frame.setSize(400, 400); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final JLabel label = new JLabel(); 
     label.setSize(new Dimension(5, 5)); 
     label.setIcon(new ImageIcon(bi)); 
     label.setText("Hello World"); 
     label.setHorizontalTextPosition(JLabel.CENTER); 
     // label.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

     label.addMouseListener(new MouseListener() { 

      private int count = 0; 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       if (e.getSource() == label) { 
        if (count % 2 == 0) { 
         label.setText("Bye"); 
        } else { 
         label.setText("Hello World"); 
        } 

        count++; 
       } 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mousePressed(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 
     }); 

     frame.add(label); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

Dieser Code erstellt ein JLabel das obige Bild enthält. Der Text der JLabel sollte jedes Mal wechseln, wenn auf die Schaltfläche geklickt wird, basierend auf einer MouseListener, die der JLabel hinzugefügt wurde.

Das Problem, das mir gegenübersteht, ist, dass selbst wenn ich außerhalb des Bildes klicke (auch außerhalb der JLabel), die MouseListener ausgelöst wird, und der Text wechselt.

Das große Bild von dem, was ich erreichen möchte, ist: Ein abgerundeter Knopf, der auf eine MouseListener reagiert, wenn es irgendwo auf seiner Oberfläche geklickt wird.

Antwort

3

Ich habe Ihren Code versucht. Sie erhalten dieses Verhalten, weil Ihr JLabel tatsächlich den gesamten Rahmen ausfüllt. Sie müssen ein Layout für Ihren Rahmen festlegen. so etwas wie dieses:

// ... 
frame.setSize(400, 400); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
frame.setLayout(new FlowLayout());    // <-- you need this 

final JLabel label = new JLabel(); 
label.setPreferredSize(new Dimension(80, 40)); // <-- also this 
label.setIcon(new ImageIcon(bi)); 
label.setText("Hello World"); 
// ... 

FlowLayout ist eine der einfachsten Layout-Managern, von denen es viele gibt. Sie können über sie hier lesen: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

Hoffe, dass dies hilft.

PS: Sie hatte eine gute Idee, versuchen, dieses Problem zu debuggen, eine Grenze wie folgt ergänzt:

// label.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

nicht sicher, warum Sie es heraus kommentiert. Vielleicht hast du nicht bemerkt, dass um den gesamten Rahmen herum ein schwarzer Rand war. Versuchen Sie die Einstellung auf Color.RED oder etwas auffälligeres zu färben.

2

Da yoshi darauf hingewiesen wird, füllt der JLabel den gesamten Inhaltsbereich aus, sodass das Klicken auf eine beliebige Stelle im Inhaltsbereich zu Mausereignissen für das Label führt.

Einige Wörter:

1) Sie auch GridBagLayout, statt FlowLayout, falls Sie die JLabel in ihrer Mutterkomponente (sowohl vertikal als auch horizontal) zentriert nutzen könnten. Diese Lösung ist here.

Wie so:

final JPanel singleCenteredComponentJPanel = new JPanel(new GridBagLayout()); 
singleCenteredComponentJPanel.add(label); 
frame.add(singleCenteredComponentJPanel); 

2) Wenn darüber hinaus möchten Sie Mausklicks auf alle transparente Pixel des Etiketts Symbol (falls vorhanden) Sie können Sie wie folgt ignorieren:

Verwenden Sie die BufferedImage.getRGB(int x, int y), BufferedImage.getColorModel() und ColorModel.getAlpha(int pixel) Methoden, um den Alpha-Wert des angeklickten Pixels für jedes Mausereignis zu bestimmen. Wenn der Alpha-Wert gleich 0 ist, ist das Pixel vollständig transparent, ansonsten liegt der Alpha-Wert zwischen 1 und 255 (beide inklusive), was wiederum bedeutet, dass das Pixel nicht vollständig transparent ist. Beispielcode folgt unten.

Und statt Image.getScaledInstance(...) das Bild zu skalieren (die Image zurückkommt, aber wir brauchen BufferedImage), verwenden Sie die Lösung here zur Verfügung gestellt.

Wie so:

private static void loadImage() throws IOException { 
    int newWidth = 80; 
    int newHeight = 40; 
    bi = ImageIO.read(RoundedButtonDemo.class.getResource("/resources/login.png")); 
    bi = getScaledBufferedImage(bi, newWidth, newHeight); 

} 

public static BufferedImage getScaledBufferedImage(final Image img, 
                final int newWidth, 
                final int newHeight) { 
    final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    final GraphicsDevice gdev = genv.getDefaultScreenDevice(); 
    final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration(); 
    final BufferedImage simg = gcnf.createCompatibleImage(newWidth, newHeight, Transparency.TRANSLUCENT); 

    //Painting input image to output image: 
    final Graphics2D g2d = simg.createGraphics(); 
    g2d.drawImage(img, 0, 0, newWidth, newHeight, null); //@Docs "...is scaled if necessary.". 
    g2d.dispose(); 

    return simg; 
} 

Auch die Referenz ändern bi von Image zu BufferedImage.

Und dann die MouseListener des Etiketts:

private int count = 0; 

@Override 
public void mouseClicked(MouseEvent e) { 
    if (e.getSource() == label) { 

     //Get the mouse click position (in pixels), 
     //relative to the top-left corner of label: 
     final Point relativeClickPoint = e.getPoint(); 

     //Obtain alpha value from the TYPE_INT_ARGB pixel: 
     final int pixel = bi.getRGB(relativeClickPoint.x, relativeClickPoint.y); 
     final int alpha = bi.getColorModel().getAlpha(pixel); 

     if (alpha > 0) { //Check if the pixel is not transparent. 
      if (count % 2 == 0) { 
       label.setText("Bye"); 
      } else { 
       label.setText("Hello World"); 
      } 
      count++; 
     } 
    } 
} 

Beachten Sie für die obige Umsetzung: Alle transparente Pixel des Bildes (einschließlich transparente Pixel „innerhalb“ der Form, falls vorhanden) außer Acht gelassen werden . Dies bedeutet, dass der Benutzer in die Mitte des Bildes klicken könnte und nichts passieren würde, wenn das angeklickte Pixel vollständig transparent wäre. Ich habe also angenommen, dass dies bei deinem Bild hier nicht der Fall ist.

3) Für die Skalierung der Image, können Sie die neue Größe der Methode bestimmen collapseInside(...):

/** 
* @param resultDim Output dimension (same aspect ratio as the original dimension, and inside containerDim). 
* @param originalDim Original dimension. 
* @param containerDim Dimension with the maximum width and maximum height. 
*/ 
public static void collapseInside(final Dimension resultDim, 
            final Dimension originalDim, 
            final Dimension containerDim) { 
    resultDim.setSize(originalDim); 
    if (resultDim.width > containerDim.width) { 
     //Adjusting height for max width: 
     resultDim.height = (resultDim.height * containerDim.width)/resultDim.width; 
     resultDim.width = containerDim.width; 
    } 
    if (resultDim.height > containerDim.height) { 
     //Adjusting width for max height: 
     resultDim.width = (resultDim.width * containerDim.height)/resultDim.height; 
     resultDim.height = containerDim.height; 
    } 
} 

Mit dieser Methode:
a) Scaled Image ‚s Breite ist kleiner als oder gleich zur Behältergrößenbreite (resultDim.width <= containerDim.width).
b) Gleiche Höhe (resultDim.height <= containerDim.height).
c) Das Seitenverhältnis der ursprünglichen Image Größe wird in der neuen Image Größe beibehalten (resultDim.width/resultDim.height == originalDim.width/originalDim.height).
Mit Image.getScaledInstance(...) und dem vorherigen getScaledBufferedImage(...) könnte sich das Seitenverhältnis des Image ändern.
So bearbeite ich die getScaledBufferedImage(...)collapseInside(...) zu verwenden:

public static BufferedImage getScaledBufferedImage(final Image img, 
                final int newWidth, 
                final int newHeight) { 
    final Dimension originalDim = new Dimension(img.getWidth(null), img.getHeight(null)), 
        containerDim = new Dimension(newWidth, newHeight), 
        resultDim = new Dimension(); 
    collapseInside(resultDim, originalDim, containerDim); 

    final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    final GraphicsDevice gdev = genv.getDefaultScreenDevice(); 
    final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration(); 
    final BufferedImage simg = gcnf.createCompatibleImage(resultDim.width, resultDim.height, Transparency.TRANSLUCENT); 

    //Painting input image to output image: 
    final Graphics2D g2d = simg.createGraphics(); 
    g2d.drawImage(img, 0, 0, resultDim.width, resultDim.height, null); //@Docs "...is scaled if necessary.". 
    g2d.dispose(); 

    return simg; 
} 

komplette Code für alle drei oben:

import java.awt.Dimension; 
import java.awt.Graphics2D; 
import java.awt.GraphicsConfiguration; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.GridBagLayout; 
import java.awt.Image; 
import java.awt.Point; 
import java.awt.Transparency; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public final class RoundedButtonDemo { 
    private static BufferedImage bi; 

    public static void main(String[] args) { 
     try { 
      loadImage(); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        createAndShowGUI(); 
       } 
      }); 
     } catch (IOException e) { 
      // handle exception 
     } 
    } 

    private static void loadImage() throws IOException { 
     int newWidth = 80; 
     int newHeight = 40; 
     bi = ImageIO.read(RoundedButtonDemo.class.getResource("/resources/login.png")); 
     bi = getScaledBufferedImage(bi, newWidth, newHeight); 

    } 

    public static BufferedImage getScaledBufferedImage(final Image img, 
                 final int newWidth, 
                 final int newHeight) { 
     final Dimension originalDim = new Dimension(img.getWidth(null), img.getHeight(null)), 
         containerDim = new Dimension(newWidth, newHeight), 
         resultDim = new Dimension(); 
     collapseInside(resultDim, originalDim, containerDim); 

     final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     final GraphicsDevice gdev = genv.getDefaultScreenDevice(); 
     final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration(); 
     final BufferedImage simg = gcnf.createCompatibleImage(resultDim.width, resultDim.height, Transparency.TRANSLUCENT); 

     //Painting input image to output image: 
     final Graphics2D g2d = simg.createGraphics(); 
     g2d.drawImage(img, 0, 0, resultDim.width, resultDim.height, null); //@Docs "...is scaled if necessary.". 
     g2d.dispose(); 

     return simg; 
    } 

    /** 
    * @param resultDim Output dimension (same aspect ratio as the original dimension, and inside containerDim). 
    * @param originalDim Original dimension. 
    * @param containerDim Dimension with the maximum width and maximum height. 
    */ 
    public static void collapseInside(final Dimension resultDim, 
             final Dimension originalDim, 
             final Dimension containerDim) { 
     resultDim.setSize(originalDim); 
     if (resultDim.width > containerDim.width) { 
      //Adjusting height for max width: 
      resultDim.height = (resultDim.height * containerDim.width)/resultDim.width; 
      resultDim.width = containerDim.width; 
     } 
     if (resultDim.height > containerDim.height) { 
      //Adjusting width for max height: 
      resultDim.width = (resultDim.width * containerDim.height)/resultDim.height; 
      resultDim.height = containerDim.height; 
     } 
    } 

    private static void createAndShowGUI() { 
     final JFrame frame = new JFrame(); 
     frame.setSize(400, 400); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final JLabel label = new JLabel(); 
     label.setSize(new Dimension(5, 5)); 
     label.setIcon(new ImageIcon(bi)); 
     label.setText("Hello World"); 
     label.setHorizontalTextPosition(JLabel.CENTER); 
     // label.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

     label.addMouseListener(new MouseListener() { 

      private int count = 0; 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       if (e.getSource() == label) { 

        //Get the mouse click position (in pixels), 
        //relative to the top-left corner of label: 
        final Point relativeClickPoint = e.getPoint(); 

        //Obtain alpha value from the TYPE_INT_ARGB pixel: 
        final int pixel = bi.getRGB(relativeClickPoint.x, relativeClickPoint.y); 
        final int alpha = bi.getColorModel().getAlpha(pixel); 

        if (alpha > 0) { //Check if the pixel is not transparent. 
         if (count % 2 == 0) { 
          label.setText("Bye"); 
         } else { 
          label.setText("Hello World"); 
         } 
         count++; 
        } 
       } 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mousePressed(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 
     }); 

     final JPanel singleCenteredComponentJPanel = new JPanel(new GridBagLayout()); 
     singleCenteredComponentJPanel.add(label); 
     frame.add(singleCenteredComponentJPanel); 

     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

Alternativ können Sie auch die paintComponent(...) von JPanel und Graphics.drawImage(...) verwenden außer Kraft setzen kann die Imagebi zu malen an die JPanel wie folgt:

@Override 
protected void paintComponent(final Graphics g) { 
    super.paintComponent(g); 

    //Drawing the image: 
    g.drawImage(img, 0, 0, null); 

    //Drawing the text: 
    //For centering the text, I used code from: 
    //https://stackoverflow.com/questions/27706197/how-can-i-center-graphics-drawstring-in-java 
    final FontMetrics metrics = g.getFontMetrics(g.getFont()); 
    final int x = (img.getWidth(null) - metrics.stringWidth(text))/2; 
    final int y = (img.getHeight(null) - metrics.getHeight())/2 + metrics.getAscent(); 
    g.drawString(text, x, y); 
} 

Wo img ist bi und text ist der Text der Schaltfläche (d. H. "Hallo Welt" und "Tschüss").
Dann fügen Sie die MouseListener zu der JPanel wie sie ist.

komplette Code für diese (als „RoundedButtonDemo1“ Klasse, in der gleichen Paket):

import java.awt.Dimension; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GraphicsConfiguration; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.GridBagLayout; 
import java.awt.Image; 
import java.awt.Point; 
import java.awt.Transparency; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public final class RoundedButtonDemo1 { 
    private static BufferedImage bi; 

    public static void main(String[] args) { 
     try { 
      loadImage(); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        createAndShowGUI(); 
       } 
      }); 
     } catch (IOException e) { 
      // handle exception 
     } 
    } 

    private static void loadImage() throws IOException { 
     int newWidth = 80; 
     int newHeight = 40; 
     bi = ImageIO.read(RoundedButtonDemo1.class.getResource("/resources/login.png")); 
     bi = getScaledBufferedImage(bi, newWidth, newHeight); 

    } 

    public static BufferedImage getScaledBufferedImage(final Image img, 
                 final int newWidth, 
                 final int newHeight) { 
     final Dimension originalDim = new Dimension(img.getWidth(null), img.getHeight(null)), 
         containerDim = new Dimension(newWidth, newHeight), 
         resultDim = new Dimension(); 
     collapseInside(resultDim, originalDim, containerDim); 

     final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     final GraphicsDevice gdev = genv.getDefaultScreenDevice(); 
     final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration(); 
     final BufferedImage simg = gcnf.createCompatibleImage(resultDim.width, resultDim.height, Transparency.TRANSLUCENT); 

     //Painting input image to output image: 
     final Graphics2D g2d = simg.createGraphics(); 
     g2d.drawImage(img, 0, 0, resultDim.width, resultDim.height, null); //@Docs "...is scaled if necessary.". 
     g2d.dispose(); 

     return simg; 
    } 

    /** 
    * @param resultDim Output dimension (same aspect ratio as the original dimension, and inside containerDim). 
    * @param originalDim Original dimension. 
    * @param containerDim Dimension with the maximum width and maximum height. 
    */ 
    public static void collapseInside(final Dimension resultDim, 
             final Dimension originalDim, 
             final Dimension containerDim) { 
     resultDim.setSize(originalDim); 
     if (resultDim.width > containerDim.width) { 
      //Adjusting height for max width: 
      resultDim.height = (resultDim.height * containerDim.width)/resultDim.width; 
      resultDim.width = containerDim.width; 
     } 
     if (resultDim.height > containerDim.height) { 
      //Adjusting width for max height: 
      resultDim.width = (resultDim.width * containerDim.height)/resultDim.height; 
      resultDim.height = containerDim.height; 
     } 
    } 

    private static class CustomButton extends JPanel { 
     private Image img; 
     private String text; 

     public void setImage(final Image img) { 
      this.img = img; 
      final Dimension imgDim = new Dimension(img.getWidth(null), img.getHeight(null)); 
      setMinimumSize(imgDim); 
      setPreferredSize(imgDim); 
      repaint(); 
     } 

     public Image getImage() { 
      return img; 
     } 

     public void setText(final String text) { 
      this.text = text; 
      repaint(); 
     } 

     public String getText() { 
      return text; 
     } 

     @Override 
     protected void paintComponent(final Graphics g) { 
      super.paintComponent(g); 

      //Drawing the image: 
      g.drawImage(img, 0, 0, null); 

      //Drawing the text: 
      //For centering the text, I used code from: 
      //https://stackoverflow.com/questions/27706197/how-can-i-center-graphics-drawstring-in-java 
      final FontMetrics metrics = g.getFontMetrics(g.getFont()); 
      final int x = (img.getWidth(null) - metrics.stringWidth(text))/2; 
      final int y = (img.getHeight(null) - metrics.getHeight())/2 + metrics.getAscent(); 
      g.drawString(text, x, y); 
     } 
    } 

    private static void createAndShowGUI() { 
     final JFrame frame = new JFrame(); 
     frame.setSize(400, 400); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final CustomButton button = new CustomButton(); 
     button.setSize(new Dimension(5, 5)); 
     button.setImage(bi); 
     button.setText("Hello World"); 
     //button.setHorizontalTextPosition(SwingConstants.CENTER); 
     //button.setOpaque(false); 
     //button.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

     button.addMouseListener(new MouseListener() { 

      private int count = 0; 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       if (e.getSource() == button) { 

        //Get the mouse click position (in pixels), 
        //relative to the top-left corner of label: 
        final Point relativeClickPoint = e.getPoint(); 

        //Obtain alpha value from the TYPE_INT_ARGB pixel: 
        final int pixel = bi.getRGB(relativeClickPoint.x, relativeClickPoint.y); 
        final int alpha = bi.getColorModel().getAlpha(pixel); 

        if (alpha > 0) { //Check if the pixel is not transparent. 
         if (count % 2 == 0) { 
          button.setText("Bye"); 
         } else { 
          button.setText("Hello World"); 
         } 
         count++; 
        } 
       } 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mousePressed(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       // TODO Auto-generated method stub 

      } 
     }); 


     final JPanel singleCenteredComponentJPanel = new JPanel(new GridBagLayout()); 
     singleCenteredComponentJPanel.add(button); 
     frame.add(singleCenteredComponentJPanel); 

     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

Alternativ, wenn Sie normale Tasten wollen, istead von Etiketten, wie es scheint here Sie Tasten neu gestalten können auch!

Ansonsten habe ich auch folgendes versucht:
1) Unter Verwendung JLayeredPane s. Es gibt eine tutorial, die sie erklärt, und ich vermute, dass sie wahrscheinlich eine Methode haben könnten, um die Reihenfolge des sichtbaren Bereichs für eine gegebene Point oder etwas ähnliches zu erhalten, aber sie nicht.
2) Unter Verwendung von Container.getComponentAt(Point) und Container.findComponentAt(Point) in der MouseListener, aber (wie ich nach dem Testen herausgefunden) diese Methoden nicht durchsichtig undurchsichtig (+ transparente) Pixel "durchschauen".
3) Suche nach Umformung oder Transluzenz in JPanel s (inspiriert von How to Create Translucent and Shaped Windows), aber nichts gefunden.
4) How to Decorate Components with the JLayer Class mit erster Linie sagen:

... können Sie auf Komponenten und reagieren auf die Komponente Ereignisse ziehen, ohne direkt die zugrunde liegende Komponente zu modifizieren.

scheint vielversprechend, aber ich bin hier fertig.

Das ist es für mich für jetzt. Auf Wiedersehen.