Icons automatisch und "korrekt" skalieren

Ahoi

Gibt es eine elegante Möglichkeit Icons zu skalieren, so dass die Anzeige immer richtig ist, auch wenn das Parent Objekt (JLabel) seine Größe verändert?
Hintergrund ist der das ich zwei Panels hab, mit einem SplitPane als Container. Wenn ich nun die Größe ändere sollen sich auch die Icons verschieben, aber immer im 4:3 Verhältnis bleiben.

Die Lösung bisher, ein eignes Icon Objekt, tut iwie nicht was sie soll

@Override
	public void paintIcon(Component c, Graphics g, int x, int y) {
		// TODO Auto-generated method stub
		this.width = c.getWidth();
		this.height = GUITools.calculate4To3Height(width);
		
		g.drawImage(super.getImage(), x, y, width, height, c);
	}
}```

Hinzu kommt, das das Image u.U. über die Labelgrenze hinaus geht. Zum Beispiel wenn man nur die MainWindow Höhe ändert, wird es zu breit und damit größer als das Label, auf dem es liegt

Layouts und Images sind echt manchmal eine verzwickte Sache

Warscheinlich vergisst du, dass “height” auch mal der “dominante” Wert sein kann, z.B. wenn sich nur diese ändert (was ja der Fall ist). Dann müsstest du aus “height” die neue “width” berechnen. Geht dann recht simpel über den Kehrwert.

:stumm:

Nun ist aber das Problem, das das Label auf dem das Icon liegt zu klein ist. Wenn ich den Divider des SplitPanes bis an den Rand schiebe wird das Bild dennoch nicht größer gezogen, sondern bleibt irgendwann stehen.
Die Struktur ist dabei folgende JXPanel -> JLabel -> Icon. Ds Panel hat dabei nen BorderLayout und im CENTER dann das Label.
Diese Einheit steckt dann wieder in einem JXPanel, nur diesmal NORTH des Layouts

€: Auch wird die Größe erst angepasst, nachdem man den Slider bewegt hat. Währenddessen sieht man aber quasi im “Hintergrund” wie das neue Bild aussieht, weil es schon gezeichnet wird. Aber noch nicht aktualisiert. Oder sowas in die Richtung

Gibt’s dafür evtl. ein KSKB (kleines selbstkompilierbares Beispiel)?

[QUOTE=Spacerat]Gibt’s dafür evtl. ein KSKB (kleines selbstkompilierbares Beispiel)?[/QUOTE]nicht direkt. ich kann aber mal schauen ob ich eins gebaut kriegt

Das wäre toll.

Das ist im Grunde die AUsgangssitiuation. Nun sollen aber zwei Dinge passieren

a) wird der Slider nach links geschoben, sollen sich die Bilder anpassen, so das das Forat immer gleich bleibt. Außerdem soll dabei der horizonzale Abstand nicht größer werden. Das liegt aber vermutlich am Layout, welches sollte man da nehmen? FlowLayout?

b) wenn der Slider nach links geht, sollen sich auch hier die Bilder anpassen. Aber auch hier nur soweit das beide Bilder nicht abgeschnitten werden oder sich überlagern

Einen Teil davon hab ich schon hinbekommen, der macht aber komische Sachen, und den hab ich nocch nicht darein bekommne weil da ne Menge drumherum noch dranhängt.

  • Bilder passen sich beim kleiner machen an
  • Bildergröße aktualisiert sich erst beim ziehen des Sliders, vorher sind sie kleiner
  • Bilder sind 720x288 und nicht wie in dem Beispiel

Bringt das Bsp. überhaupt was? ^^

€: Ok, das mit der Größe liegt wohl daran das das Bild sofort in der Größe angepasst wird, und damit die original Größe verloren geht. Überschreib ich die getWidth/getHeight Methoden dagegen nicht, ist das angezeigte Bild in dem Panel kleiner als das original Bild :confused:

€²: Gibt es denn unabhängig davon Vorschläge wie man in nem SPlitPane Bilder autom. skaliert

Deine größenberechnung ist Fehlerhaft und die ganzen fixen Größenangaben machen es dir auch nur schwerer. Entschlackt und angepasst mit einer eigenen Bildkomponente:


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
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.JSplitPane;

public class MainFrame {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame f = new JFrame();
		f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		
		JPanel leftPanel = new JPanel(new BorderLayout());

		JPanel imgPanel = new JPanel(new GridLayout(0,1));

		ImageIcon icon= new ImageIcon(MainFrame.class.getResource("logo.jpg"));
		
		for(int i=0;i<5;i++)
		{
			imgPanel.add(new BildPanel(icon.getImage()));
		}
		
		leftPanel.add(imgPanel);
		
		JPanel rightPanel = new JPanel(new BorderLayout());
		JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
		
		f.add(splitPane, BorderLayout.CENTER);
		f.pack();
		f.setVisible( true );
	}

}

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;

import javax.swing.JPanel;

public class BildPanel extends JPanel
{
	private Image image;
	private int iWidth,iHeight;
	private double imageVerhaeltnis;
	
	BildPanel(Image img)
	{
		image=img;
		iWidth=img.getWidth(null);
		iHeight=img.getHeight(null);
		imageVerhaeltnis=image.getWidth(null)/image.getHeight(null);
	}
	
	@Override
	public void paintComponent(Graphics g)
	{
		if(image!=null)
		{
			Rectangle bounds=g.getClipBounds();
			double boundsVerhaeltnis=bounds.getWidth()/bounds.getHeight();						
			int width,height;
			
			if(boundsVerhaeltnis>imageVerhaeltnis)
			{
				width=(int) ((int) bounds.getHeight()*imageVerhaeltnis);
				height=(int) (bounds.getHeight());
			}
			else
			{
				width=(int) bounds.getWidth();
				height=(int) (bounds.getWidth()*imageVerhaeltnis);
			}
			
			g.drawImage(image, 0,0,width,height,null);	
		}
	}
}

Das nicht direkt über das Icon zu machen sondern über das parentObjekt, also das Panel hab ich auch schon überlegt. Werd mir das ganze mal anschauen.

Danke schonmal

Yay. Es tut wie es soll, danke. Paar Kleinigkeiten sind noch, aber die sind an andrer Stelle wo die Layoutgrößen nicht passen.