Como criar um JFrame com imagem de fundo

Imagens de fundo são extremamente essenciais para certos layouts.

Imagens de fundo (backgrounds) são extremamente essenciais para certos layouts. Um simples gradient ou uma marca d’água representam um grande diferencial e tornam a aplicação mais agradável.

Infelizmente, o componente JFrame, até a versão 6.0 do JDK, não possui uma propriedade específica que possibilite configurar uma imagem como plano de fundo. Nesse caso é necessário implementar uma maneira, das várias possíveis, para disponibilizar esse recurso.

Definindo uma imagem de fundo

Para o exemplo do artigo, será usada uma imagem simples representando um gradient com dimensões 1024x768, que é a resolução mais utilizada atualmente nos desktops e armazenada no “C:\” como indica a figura a seguir:

O caminho da imagem que será utilizado pelo Java nesse caso será: “C:\bg_gradient.jpg”.

O método paintComponent

Como citado anteriormente, para se criar a possibilidade de definição de uma imagem de fundo, é necessário implementá-la manualmente.

Os JFrames possuem uma propriedade chamada contentPane que é o componente padrão onde são adicionados todos os componentes específicos como botões, labels, áreas de texto, etc.

Este contentPane possui um método chamado paintComponent que é o método responsável por desenhá-lo (o que é exibido para o usuário). E é ele quem será implementado.

A Listagem 01 exibe uma private class que será utilizada mais adiante no artigo. Primeiramente é interessante focar na implementação de paintComponent.

private class NewContentPane extends JPanel{ //método implementado de JPanel protected void paintComponent(final Graphics g) { super.paintComponent(g); g.drawImage(bImage, 0, 0, this); } }

Listagem 01 – Classe interna que implementa paintComponent

A classe interna NewContentPane é uma classe filha de JPanel e será o novo contentPane de JFrame.

Super.paintComponent(g) chama o respectivo método, porém, de JPanel, para que não sejam perdidas as visualizações-padrão de um JPanel. Em seguida, o método drawImage “desenha” bImage (imagem utilizada como background – descrita na próxima etapa do artigo).

Com isso tem-se uma classe filha de JPanel, porém com uma imagem desenhada ao invés de uma cor padrão.

O JFrame com o novo contentPane

Será desenvolvido agora o JFrame adaptado com o novo contentPane.

A Listagem 02 representa o código-fonte da classe JFrameWithBackground com a classe interna criada anteriormente.

package br.com.jm.jframes; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import javax.swing.JFrame; import javax.swing.JPanel; public class JFrameWithBackground extends JFrameFactory{ Image bImage; public JFrameWithBackground(String path){ this.bImage = this.createImage(path); this.initComponents(); } public void initComponents(){ super.setContentPane(new NewContentPane()); super.setExtendedState(JFrame.MAXIMIZED_BOTH); } private Image createImage(String path){ return Toolkit.getDefaultToolkit().createImage(path); } private class NewContentPane extends JPanel{ protected void paintComponent(final Graphics g) { super.paintComponent(g); g.drawImage(bImage, 0, 0, this); } } }

Listagem 02 – JFrameWithBackground

O construtor da classe recebe uma String que representa o caminho da imagem e em seguida chama o método createImage. Esse método chama a função createImage da classe Toolkit (java.awt.Toolkit) que retorna uma imagem de acordo com esse caminho. A variável, anteriormente citada, bImage agora representa a imagem de fundo do JFrame.

É dentro do método initComponents que se faz a alteração do contentPane que agora será uma instância de NewContentPane (classe interna criada no início do artigo e que implementa paintComponent).

Como isso tem-se um JFrame que possui um contentPane diferente do padrão; que possui uma imagem de fundo.

Testando o novo JFrame

Falta apenas testar o novo JFrame e sua nova capacidade (possuir uma imagem de fundo). A Listagem 03 exibe uma classe simples com um panel adicionado.

import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; import br.com.jm.jframes.JFrameWithBackground; public class TesteJFrameWithBackground { public static void main(String[] args) { try{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch(Exception exception){ } JPanel jPanel3 = new JPanel(new BorderLayout()); jPanel3.add(new JLabel("teste-background"), BorderLayout.NORTH); jPanel3.add(new JLabel("texto:"), BorderLayout.WEST); jPanel3.add(new JScrollPane(new JTextArea()), BorderLayout.CENTER); jPanel3.add(new JLabel("teste-background-fim"), BorderLayout.SOUTH); jPanel3.setPreferredSize(new Dimension(400,500)); jPanel3.setBorder(BorderFactory.createTitledBorder("jPanel3")); jPanel3.setOpaque(false); JFrameWithBackground jFrame = new JFrameWithBackground("C:\\bg_gradient.jpg"); jFrame.setLayout(new BorderLayout()); jFrame.getContentPane().add(jPanel3, BorderLayout.NORTH); jFrame.setVisible(true); } }

Listagem 03 – Classe de testes

A imagem passada como parâmetro para JFrameWithBackground é a citada no início do artigo.

Conclusão

Implementando paintComponent de JPanel e armazenando essa implementação como novo contentPane de um JFrame foi possível criar um frame com uma imagem de fundo. À medida que essa nova classe vai sendo desenvolvida, pode-se criar métodos set e get que permitam atualizar, em tempo de execução, a imagem de fundo, tornando-a dinâmica.

Artigos relacionados