Swing ImageIcon hover

  • Themenstarter Themenstarter ack3799
  • Beginndatum Beginndatum
A

ack3799

Gast
Ich würde gerne wenn man mit der Maus über ein ImageIcon fährt eine kleine Hover-Box mit einer kurzen Beschreibung öffnen lassen. Da die Icons nicht quadratisch sind (transparente Bereiche) sollte die Hoverbox nur beim direkten über dem Icon sein erscheinen. Kann ich irgendwie die Form eines Jbuttons so verändern, dass das funktioniert, oder wie macht man das am Besten?
 
Ja. Gibt es da auch die Möglichkeiten nur bei nicht-transparenten Flächen eines Bildes den tooltip anzuzeigen?
 
Meines erachtens: nope

JButtons sind immer Rechteckig. Du kannst zwar alles sichtbare ausblenden aber programmatisch ist er immernoch rechteckig.

Der Tooltio ist mit dem Button oder dem ImageIcon verknüpft. Da dieses auch immer Rechteckig ist wüsste ich nicht wie.

Solltest du das herausfinden interessierts mich aber auch.
 
Java:
		for(int xValue=0;xValue<image.getWidth();xValue++){
			for (int yValue=0; yValue < image.getHeight(); yValue++) {
			    int rgb = image.getRGB(xValue, yValue);	
			    int alpha = ((rgb >> 24) & 0xff); 		

			    if (alpha != 0) {
			    	makeButton();
			    }

			}
		}

Werden dann aber ganz schön viele Buttons.... Sehr sehr unschöne Lösung.

(Evtl. Non-Transparent Pixel in Rechtecke groupen, dann immerhin etwas besser. Wie mache ich sowas am besten?)
 
Jop, über so etwas habe ich auch schon nachgedacht. Läuft nur letzten Endes auch auf Pixel für Pixel durchgeste hinaus :/
Dann hast du da was grundlegend falsch verstanden. Die Funktion wird automatisch aufgerufen, wenn der Mauszeiger eine gewisse zeit still über deinem Komponenten stehen bleibt. Die Funktion bekommt ein MouseEvent übergeben, in dem steht die Position des Zeigers (EIN x und y Wert) und von diesem einen Punkt kannst du dann z.B die Pixeldaten überprüfen.
 
Dann hast du da was grundlegend falsch verstanden. Die Funktion wird automatisch aufgerufen, wenn der Mauszeiger eine gewisse zeit still über deinem Komponenten stehen bleibt. Die Funktion bekommt ein MouseEvent übergeben, in dem steht die Position des Zeigers (EIN x und y Wert) und von diesem einen Punkt kannst du dann z.B die Pixeldaten überprüfen.

Genau. Da der Hintergrund und Vordergrund des Icons übereinander gelegt werden (nur der Vordergrund soll tooltipped werden), müssen die Pixel bereits beim Erstellen des Icons geprüft und in ein Array (o.ä.) geschrieben werden. Oder jedesmal die Vordergrundsgrafik neu Eingelesen werden, was warscheinlich noch weniger performant ist.
 
Ist dieses Thema Hintergrund für den anderen Thread mit dem Array bzw. ArrayList?

Zu diesem Thema:
Grundsätzlich kannst Du Dir das Bild im Vordergrund doch merken und in der getToolTip auswerten.

Hier mal ein Beispiel. Ich erstelle hier ein BufferedImage als Maske, um beliebige Objekte vom Typ Image verwenden zu können. Wenn man ausschließlich mit BufferedImages arbeitet, kann man sich das sparen. Wenn man mag, kann man auch ein Hintergrundbild hinterlegen, der Konstruktor und die Klasse sieht das vor.
In der getToolTip des ImageHoverPanel wird diese Maske ausgewertet und dem entsprechend der ToolTip angepasst.

Java:
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;
import javax.swing.JFrame;
public class ImageToolTipDemo extends JFrame {
	
	class ImageHoverPanel extends JComponent {
		private Image image, bgImg;
		BufferedImage mask;
		private int imgX, imgY;
		
		public ImageHoverPanel(Image hoverImg, Image bgImg) {
			this.image = hoverImg;
			this.bgImg = bgImg;
			this.createAlphaMask();
			this.setPreferredSize(new Dimension(imgX + hoverImg.getWidth(null), imgY + hoverImg.getHeight(null)));
			this.setToolTipText("");
		}
		
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			if (bgImg!=null)
				g.drawImage(bgImg, imgX, imgY, null);
			g.drawImage(image, imgX, imgY, null);
		}
		
		public String getToolTipText(MouseEvent evt) {
			int x = evt.getX()- imgX;
			int y = evt.getY() -imgY;
			if (x>=0 && x<mask.getWidth() && y>=0 && y<mask.getHeight()) {
				if (mask.getRGB(x, y)==0)
					return "Transparent Area. Here the tootip can be set to null!";
				else
					return "Image Area";
			}
			return null;
		}
		
		private void createAlphaMask() {
			int w = image.getWidth(null);
			int h = image.getHeight(null);
			mask = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
			Graphics2D g = (Graphics2D)mask.getGraphics();
			g.drawImage(image, 0, 0, null);
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP));
			g.setColor(Color.BLACK);
			g.fillRect(0, 0, w, h);
			g.dispose();
		}
	}
	
	public ImageToolTipDemo() {
		add(new ImageHoverPanel(createAlphaImage(200, 200), null));
	}
	
	private BufferedImage createAlphaImage(int w, int h) {
		BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2 = image.createGraphics();
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setColor(Color.RED);
		g2.fillOval(10, 10, w-50, h-50);
		g2.setColor(Color.BLUE);
		g2.fillRect(15, 5, 20, h-10);
		Stroke stroke = new BasicStroke(5);
		g2.setStroke(stroke);
		g2.setColor(Color.GREEN);
		g2.drawPolygon(new int[] {5, w/2-5, w-10, w/2+15, w-2, w/2+15}, new int[] {h/2, h/2-5, 2, h/2, h/2, h-20}, 6);
		g2.dispose();
		return image;
	}
	
	public static void main(String[] args) {
		JFrame frame = new ImageToolTipDemo();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 

Zurück
Oben