JLabel mit Icon & JFrame Resize

TiME-SPLiNTER

Aktives Mitglied
Hallo Zusammen,

Ich bin auf ein Problem gestossen, bei dem ich einfach nicht zu einem Ansatz komme. Ich habe ein JFrame mit einem BorderLayout. FIRST ist ein JPanel, dann CENTER ist mein JLabel (das Problemkind) und LAST ist wieder ein JPanel.

Im JLabel ist ein Icon das dem JFrame bei einem Resize (ComponentListener) von der Grösse her angeglichen wird. Das geht super solange das JLabel immer grösser und grösser wird. Wird es aber kleiner (das Fenster wird kleiner gezogen), dann bleibt das Icon auf der letzten Grösse da ich anhand der aktuellen Width und Height des JLabels die Grösse des Icons berechne.

Meine Frage ist jetzt, wie kann ich nun das Icon wieder verkleinern... oder was gäbe es für einen anderen Ansatz? Ich habe ein vereinfachtes Beispiel geschrieben was meine Problematik verdeutlichen soll.

Java:
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import ch.timesplinter.mediaguru.common.Utils;

public class TestJLabelIcon extends JFrame {
	private static final long serialVersionUID = -5427008595933142844L;
	private static final String PICTURE_PATH = "D:/bilder/beispiel.jpg";
	
	public TestJLabelIcon() {
		initComponents();
		initComponets2();
		
		initLoad();
	}
	
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
        );

        pack();
        
        setSize(800,600);
    }// </editor-fold>
	
    private void initComponets2() {
    	jLabel1.addComponentListener(new ComponentListener() {	
			@Override
			public void componentShown(ComponentEvent e) {
				initLoad();
			}
			
			@Override
			public void componentResized(ComponentEvent e) {
				initLoad();
			}
			
			@Override
			public void componentMoved(ComponentEvent e) {
				initLoad();
			}
			
			@Override
			public void componentHidden(ComponentEvent e) {
				initLoad();
			}
		});
    }
    
    private void initLoad() {
    	refreshJLabel();
    	jLabel1.setIcon(getResizedImage(new ImageIcon(PICTURE_PATH), jLabel1.getWidth(), jLabel1.getHeight()));
    }
    
    private void refreshJLabel() {
    	if(jLabel1 != null && jLabel1.getWidth() < this.getWidth() && jLabel1.getHeight() < this.getHeight())
    		return;
    	
    	System.out.println("NEU INIT");
    	
    }
    
	public static void main(String[] args) {
		TestJLabelIcon test = new TestJLabelIcon();
		test.setVisible(true);
	}

public static ImageIcon getResizedImage(ImageIcon imageIn, int maxWidth, int maxHeight) {
		if(imageIn == null)
			return imageIn;
		
		if(imageIn.getIconHeight() < maxHeight && imageIn.getIconWidth() < maxWidth)
			return imageIn;
		
		if(maxHeight <= 0 || maxWidth <= 0)
			return imageIn;
		
		CloneableImageIcon image = new CloneableImageIcon(imageIn.getImage());
		
		int newHeight;
		int newWidth;
		
		if((image.getIconHeight() > image.getIconWidth())) {
			newHeight = maxHeight;
			newWidth = (int)(image.getIconWidth()*((float)maxHeight/(float)image.getIconHeight()));
		} else if((image.getIconHeight() <= image.getIconWidth())) {
			newWidth = maxWidth;
			newHeight = (int)(image.getIconHeight()*((float)maxWidth/(float)image.getIconWidth()));
		
			if(newHeight > maxHeight) {
				newHeight = maxHeight;
				newWidth = (int)(image.getIconWidth()*((float)maxHeight/(float)image.getIconHeight()));
			}
		} else {
			return imageIn;
		}
		
		BufferedImage bImg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics2D = bImg.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
          RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2D.drawImage(image.getImage(), 0, 0, newWidth, newHeight, null);
        
        image.setImage(bImg);
        
        return image;
	}
	
	private JLabel jLabel1;
}

CloneableImageIcon.java
Java:
import java.awt.Image;

import javax.swing.ImageIcon;

public class CloneableImageIcon extends ImageIcon implements Cloneable {
	private static final long serialVersionUID = 6320908079954312732L;

	public CloneableImageIcon(Image image) {
		super(image);
	}
	
	public CloneableImageIcon clone() {
		try {
			return (CloneableImageIcon)super.clone();
		} catch (CloneNotSupportedException e) {
		
		}
		
		return this;
	}
}
 
Hallo TiME-SPLiNTER,

hier ein kleines Beispiel für ein ImageResize:

Java:
public class ImageResize extends JFrame{
	
	public ImageResize() {
		setTitle("Java Tutorial on www.itblogging.de");
		
		ImageContainer imageContainer = new ImageContainer("src/itblogging_half.png");
		add(imageContainer);

		setSize(234, 100);
		setVisible(true);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
	
	public static void main(String[] args) {
		new ImageResize();
	}
	
	class ImageContainer extends JPanel
	{
	   private Image background;
	   
	   public ImageContainer(String imageSource)
	   {
		  Toolkit toolkit = getToolkit();
	      background = toolkit.createImage(imageSource);
	   }
	   
	   public void paintComponent(Graphics g)
	   {
	      int width = getWidth();
	      int height = getHeight();
	      g.drawImage(background, 0, 0, width, height, this);
	   }   
	}
}
 
Kleine Anmerkung: Toolkit ist schon ziemlich alt und ineffizient, was das Lesen von Bilddateien angeht. Nutze besser
Code:
javax.imageio.ImageIO
und deren Methoden zum Lesen von Bilddateien. ImageIO ist wesentlich effizienter und geradliniger in der Anwendung als Toolkit.
 
Vielen Dank an z-mon 😀. Mit der richtigen paintComponent-Methode klappt das nun wunderbar und einfacher als zuvor. (Ich hatte ein Fehler in der Resize-Logik.)

Java:
public void paintComponent(Graphics g) {
          int panelWidth = getWidth();
          int panelHeight = getHeight();   
          int imageWidth = currentImage.getWidth(null);
          int imageHeight = currentImage.getHeight(null);
          
          int newWidth = imageWidth;
          int newHeight = imageHeight;
          
          if(imageWidth > panelWidth || imageHeight > panelHeight) {
	    	  if(imageHeight > panelHeight) {
	    		  newHeight = panelHeight;
	        	  newWidth = (int)(imageWidth*((float)panelHeight/(float)imageHeight)); 
	    	  } else {
	    		  newWidth = panelWidth;
	        	  newHeight = (int)(imageHeight*((float)panelWidth/(float)imageWidth));
	    	  }
	    	  
	    	  if(newHeight > panelHeight) {
	    		  newHeight = panelHeight;
	        	  newWidth = (int)(imageWidth*((float)panelHeight/(float)imageHeight)); 
	    	  }
	    	  
	    	  if(newWidth > panelWidth) {
	    		  newWidth = panelWidth;
	        	  newHeight = (int)(imageHeight*((float)panelWidth/(float)imageWidth));
	    	  }
          }
          
          g.drawImage(currentImage, 0, 0, newWidth, newHeight, this);
       }

Und danke an L-ectron-X für die Info "Toolkit vs. ImageIO" 🙂.
 
Und weil ich es gerade sehe:
Die erste Zeile in der paintComponent()-Methode sollte immer
Java:
super.paintComponent(g);
sein. Das verhindert, dass es zu unerwünschten Effekten beim Zeichnen kommt.
 
Kleine Anmerkung: Toolkit ist schon ziemlich alt und ineffizient, was das Lesen von Bilddateien angeht. Nutze besser
Code:
javax.imageio.ImageIO
und deren Methoden zum Lesen von Bilddateien. ImageIO ist wesentlich effizienter und geradliniger in der Anwendung als Toolkit.

Diese Info war mir auch noch nicht bekannt. Ist auch schon ein wenig her das ich eine GUI entwickelt habe. Aber wie das halt immer so ist in der Informatik: Man lernt nie aus 🙂
 

Zurück
Oben