Imagens

Já li em vários post diferentes sobre as imagens, consigo trabalhar com elas dentro de jLabel e jButtons perfeitamente
mas
não existe uma maneira de usar como plano de fundo num jPanel sem usar um jLabel pra isso??

pq se eu usar uma imagem dentro de um jLabel pra fazer o plano de fundo, tenho q usar o layout null, para poder colcoar outros objetos e estou usando o border layout+gridbadlayout

A forma mais fácil é sobrescrever o método paintComponent(Graphics) do JPanel e nele pintar a imagem de fundo.
Só tem que lembrar que se houver outros paineis inseridos no JPanel, tem que fazer setOpaque(false).

1 curtida

consegui fazer dessa maneira

    public static void main(String args[]) {
    
    NewJFrame F = new NewJFrame ();
    
    try{
        F.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("/iso/App/img_padrao/fundo.png")))));
    }catch(IOException e){
        System.out.println("nao tem iamgem");
    }
    F.setSize(800,600);
    F.setVisible(true);
    F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

mas só funciona quando coloco o caminho absoluto da imagem, quando coloco o caminho interno, do pacote q criei com todas imagens q uso, não funciona

alguma ideia?

Um JLabel não deveria ser usado como container.

concordo, n c deve fazer essas gambiarras
mas não consigo fazer a imagem ficar no painel, java dificulta tudo, hehehh

se tiver algum exemplo agradeço…
estou o dia todo olhando videos no youtube sobre o assunto

Já tentou fazer o que sugeri, de sobrescrever o paintComponent?

depois de muito ler, consegui fazer isso:

import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class fundoPainel extends JPanel {

    public fundoPainel() {
        initComponents();
                
    }
    
    @Override
    public void paintComponent(Graphics g){
        
        super.paintComponent(g);
        ImageIcon i = new ImageIcon("/iso/App/img/fundo.png");
        i.paintIcon(this, g, 0, 0);
        
    }

    public static void main(String[] args){
        
        fundoPainel t = new fundoPainel();
        JFrame fr = new JFrame();
        fr.setTitle("titulo teste");
        fr.setSize(800,600);
        fr.setVisible(true);
        fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        fr.add(t);
    }

a img entra direto no frame…
agora estou tentando colocar dentro do painel correto
alguma ideia de como setar o painel ?

desculpa as bobagens, mas estou migrando pro java, mtaaaaa coisa diferente

descobri o erro
mesmo deixando o panel com a opção opaque desabilitada não estava aparecendo a img
não estava entendendo, mas é que estou usando um scrollpanel, e mesmo com a opção opaque desabilitada ele n mostra a img de fundo

se é um jpanel aparece
scrollpanel n aparece, q azar :sweat:

se eu descobrir algo posto aqui

Veja como eu costumo fazer:

Primeiro crio uma classe ImagePanel que nada mais é do que um JPanel que renderiza uma imagem ao fundo:

import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel {

	/**
	 * Cria um ImagePanel que renderiza a imagem de forma centralizada
	 */
	public static ImagePanel centered(InputStream input) throws IOException {
		return new ImagePanel(input, new Painter() {

			@Override
			public void paint(Container container, Image image, Graphics graphics) {
				int containerWidth = container.getWidth();
				int containerHeight = container.getHeight();
				int imageWidth = image.getWidth(container);
				int imageHeight = image.getHeight(container);
				int x = (containerWidth - imageWidth) / 2;
				int y = (containerHeight - imageHeight) / 2;
				graphics.drawImage(image, x, y, imageWidth, imageHeight, container);
			}
		});
	}

	/**
	 * Cria um ImagePanel que renderiza a imagem de forma esticada
	 */
	public static ImagePanel stretched(InputStream input) throws IOException {
		return new ImagePanel(input, new Painter() {

			@Override
			public void paint(Container container, Image image, Graphics graphics) {
				int containerWidth = container.getWidth();
				int containerHeight = container.getHeight();
				int x = 0;
				int y = 0;
				graphics.drawImage(image, x, y, containerWidth, containerHeight, container);
			}
		});
	}

	private static interface Painter {

		public void paint(Container container, Image image, Graphics graphics);
	}

	private static final long serialVersionUID = 1;

	private final BufferedImage image;
	private final Painter painter;

	private ImagePanel(InputStream input, Painter painter) throws IOException {
		if (input == null) {
			throw new IllegalArgumentException("input cannot be null");
		}
		if (painter == null) {
			throw new IllegalArgumentException("painter cannot be null");
		}
		this.image = ImageIO.read(input);
		this.painter = painter;
	}

	@Override
	protected void paintComponent(Graphics graphics) {
		super.paintComponent(graphics);
		painter.paint(this, image, graphics);
	}
}

Depois utilizo esse ImagePanel quando eu preciso de um Container que desenhe uma imagem de fundo, veja o exemplo abaixo:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Exemplo {

	public static void main(String[] args) {
		try {
			Exemplo programa = new Exemplo();
			programa.executar();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

	private void executar() throws IOException {
		InputStream imagem1 = getClass().getResourceAsStream("/imagem.jpg");
		ImagePanel imagePanel1 = ImagePanel.centered(imagem1);
		JFrame janela1 = criaJanela(imagePanel1, "Centralizada");

		InputStream imagem2 = getClass().getResourceAsStream("/imagem.jpg");
		ImagePanel imagePanel2 = ImagePanel.stretched(imagem2);
		JFrame janela2 = criaJanela(imagePanel2, "Esticada");

		Rectangle r = janela1.getBounds();
		janela1.setLocation(r.x - r.width / 2, r.y);
		janela2.setLocation(r.x + r.width / 2, r.y);

		janela1.setVisible(true);
		janela2.setVisible(true);
	}

	private JFrame criaJanela(ImagePanel imagePanel, String titulo) {
		JPanel painelSuperior = new JPanel();
		painelSuperior.setOpaque(false);

		painelSuperior.add(new JLabel("Label"));
		painelSuperior.add(new JTextField("TextField"));

		JScrollPane painelInferior = new JScrollPane(new JTextArea("TextArea"));
		painelInferior.setPreferredSize(new Dimension(100, 150));
		painelInferior.setOpaque(false);

		imagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		imagePanel.setLayout(new BorderLayout());
		imagePanel.add(painelSuperior, BorderLayout.NORTH);
		imagePanel.add(painelInferior, BorderLayout.SOUTH);

		JFrame frame = new JFrame(titulo);
		frame.setContentPane(imagePanel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(800, 600);
		frame.setLocationRelativeTo(null);
		return frame;
	}
}
1 curtida

isso, eu ja estava fazendo assim, uma classe JPanel e uma jFrame
aquele codigo ali que postei só foi um exemplo q fiz pra mostrar como eu estava chamando a img e que funcionava

ta funcionando com um pequeno erro, a imagem não amplia… por algum motivo a imagem esta ficando do mesmo tamanho que o Jpanel na guai design

Se estiver criando o ImagePanel com o método stretched, a imagem vai ter o tamanho do ImagePanel
Se criar usando o método centered, ela ficará centralizada
Se quiseres renderizar de qualquer forma diferente, é só implementar um novo método pra isso.
:slight_smile:

cara mto obg pela ajuda

da trabalho mas fica bem mais bonito usando imagens/texturas, doq uma cor opaca, hehehh

orgazinar as img dentro dos layout deu trabalho mas ficou sho

vlws a paciencia :grin:

unico problema é que a img tem q colocar o caminho absoluto, quando coloco o caminho da img dentro do pacote nao funciona

Provavelmente você está usando a classe File para carregar a imagem, não faz isso não, utiliza o getResourceAsStream da classe Class, aí basta começar o caminho com "/" que ele vai procurar a partir da raíz do classpath.

É só olhar o método executar do exemplo que postei.

depois eu troquei e esqueci de avisar aqui
ta funcionando perfeito :slight_smile:

1 curtida