JLable Bildgröße ändern

Ich probiere zur Zeit im JFrame Bilder hinzuzufügen, ich schaffe es zwar mit setBounds() die Position zu ändern, aber nicht die Größe.

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

class Frame extends JFrame
{
	Frame(String title)
	{
		super(title);
		setLayout(null);
		setSize(1000, 700);
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		ImageIcon bg = new ImageIcon(getClass().getResource("gfx/background.jpg"));
		JLabel lBg = new JLabel(bg);
		lBg.setBounds(0, 0, 1000, 700);
		add(lBg);
		
		setVisible(true);
	}
}

Und ich habe noch eine 2. Frage, gibt es eine bessere Möglichkeit Bilder hinzuzufügen?

Ich freue mich auf euere Antworten :slight_smile:

LG Huntro

Mit setBounds ändert man die Bounds des Labels. Aber nicht die Größe des Bildes. Je nachdem, was genau du erreichen willst, kannst du entweder das Bild direkt laden und skalieren, bevor du das ImageIcon daraus erstellst, oder das Bild skaliert zeichnen lassen. Ggf. auch mal in http://wiki.byte-welt.net/wiki/Bilder_skalieren oder http://forum.byte-welt.net/threads/4653-Bilder-der-Label-Größe-anpassen?p=21873&viewfull=1#post21873 schauen, FALLS es das ist, was du vorhast.

NullLayout = evil

zum “besser” : wenn es, wie in deinem fall, ein “background” werden soll könnte man auch ein JPanel nehmen und dessen paintComponent() überschreiben
dann nimmt man noch ein JLayeredPane und ein zweites JPanel das man durchsichtig macht, und schon hat man zumindest das end-ergebnis
ob es noch “besser” geht lehn ich mich mal nich ausm fenster

http://docs.oracle.com/javase/tutorial/2d/images/

Das hier wäre ausreichendd:

        BufferedImage bi = ImageIO.read(new File("C:\\Users\\UseNam\\Desktop\\Unbenannt.PNG"));
        //resizing
        int w = bi.getWidth();
        int h = bi.getHeight();
        for (int j = 0; j < h / 2; j++) {
            //if (j % 2 == 0) {
            //    for (int i = 0; i < w / 2; i++) {
            //        bi.setRGB(i, j, bi.getRGB(i * 2, j));
            //    }
            //} else {
            for (int i = 0; i < w / 2; i++) {
                bi.setRGB(i, j, bi.getRGB(i * 2, j * 2));
            }
            //}
        }
        //displaying
        JFrame jf = new JFrame("My jpeg image");
        jf.add(new JLabel(new ImageIcon(bi)));
        jf.pack();
        jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        jf.setVisible(true);
    }```

Also am einfachsten mit JLabel und Icon/ImageIcon....

Hab’ ich mir auch gedacht, als ich das gesehen habe :wink: Das ist wohl die ineffizienteste und unflexibelste Art, ein Bild zu skalieren, die man sich vorstellen kann…

Danke, ich habe es jetzt mit so gemacht:

	    
double w = image.getIconWidth();
double h = image.getIconHeight();

image.setImage(image.getImage().getScaledInstance((int) w, (int) h, Image.SCALE_DEFAULT));
JLabel labelImage = new JLabel(image);
labelImage.setBounds(0, 0, (int) w, (int) h);```

Aber ich habe nochmal eine 2. Frage. Ich habe jetzt alle Bilder im Konstruktor geladen, außer eines dies will ich in einer Methode laden lassen. Ich habe auch alles hin bekommen, aber das Problem ist es wird hinter den anderen generiert und nicht auf erster Stelle. Daher wollte ich fragen, wie ich das Label auf erster Stelle setzten kann.

LG Huntro

Ineffizient ist das nicht, wohl anderseits unflexible Art. :wink:

PS.: Mit Transparenz habe ich auch rum gespielt.

Auch wenn man bestimmte Aussagen oft bis in absurde Details zerpflücken kann: Ich hätte nicht (so) gesagt, dass es ineffizient ist, wenn es nicht ineffizient wäre. Aber…
back to topic…
ja, getScaledInstance ist eine Möglichkeit, unter den Vorbehalten, die im verlinkten Wiki-Eintrag (und im von dort aus verlinkten Artikel) erwähnt sind.

Wenn du jetzt aber von “hinter die anderen” und verschiedenen “Stellen” redest, klingt das, als würdest du die JLabels als Sprites mißbrauchen (das würde auch das null-Layout erklären). Man könnte jetzt Tipps geben, die in Richung JLayeredPane oder Container#setComponentZOrder gehen, aber dass du damit vermeintlich (!) das Problem lösen würdest, würde dich ggf. nur noch tiefer in den Morast reiten. Darum mein Tipp: Verwende nicht JLabels, wenn du Sprites zeichnen willst!

Wenns nur darum geht ein skalierbares ImagePanel zu bekommen…

  private Image img;

  public ImagePanel(Image toView) {
    setImage(toView);
  }

  protected synchronized void setImage(Image toView) {
    toView = loadImage(toView);
    if(toView == null) {
      throw new IllegalArgumentException("invalid image");
    }
    img = toView;
  }

  public void paint(Graphics g) {
    g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
  }

  public static BufferedImage loadImage(Image toLoad) {
    if(toLoad == null) {
      return null;
    }
    if(toLoad instanceof BufferedImage) {
      return (BufferedImage) toLoad;
    }
    ImageProducer producer = toLoad.getSource();
    final BufferedImage[] rc = new BufferedImage[1];
    ImageConsumer consumer = new ImageConsumer() {
      private Hashtable<?, ?> props;
      private ColorModel model;
      private WritableRaster raster;
      private int width, height;
      boolean err = true;

      public void setProperties(Hashtable<?, ?> props) {
        this.props = props;
      }

      public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
        if(this.model == null) {
          this.model = model;
        }
        if(this.model != model) {
          err = true;
        }
        raster = model.createCompatibleWritableRaster(width, height);
        raster.setDataElements(x, y, w, h, pixels);
      }

      public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
        if(this.model == null) {
           this.model = model;
        }
        if(this.model != model) {
          err = true;
        }
        raster = model.createCompatibleWritableRaster(width, height);
        raster.setDataElements(x, y, w, h, pixels);
      }

      public void setHints(int hintflags) {
      }

      public void setDimensions(int width, int height) {
        this.width = width;
        this.height = height;
      }

      public void setColorModel(ColorModel model) {
        this.model = model;
      }

      public void imageComplete(int status) {
        if(status == SINGLEFRAMEDONE || status == STATICIMAGEDONE && !err) {
          rc[0] = new BufferedImage(model, raster, model.isAlphaPremultiplied(), props);
        }
        synchronized (this) {
          notifyAll();
        }
      }
    };
    producer.startProduction(consumer);
    synchronized(consumer) {
      try {
        consumer.wait();
      } catch(InterruptedException e) {
        // tja
      }
    }
    return rc[0];
  }
}```und wenn man von dem Panel eine gescalte Instanz haben möchte...
```BufferedImage resized = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
myImagePanel.setSize(800, 600);
myImagePanel.paint(resized.createGraphics());
ImagePanel resizedImagePanel = new ImagePanel(resized);```

Aber wenn du Sprites erstellen und animieren willst, dann erweitere um Himmels Willen BufferedImage oder implementiere RenderedImage, aber keinesfalls irgendwas mit Component!