GARANTIR DESCONTO

Fórum [RESOLVIDO] Colocar imagem de fundo em um JButton #569625

09/11/2011

0

Olá! Gostaria de saber como faço para por uma imagem de fundo (.png) em um JButton. Tentei algumas coisas aqui, mas nada que chegasse perto do desejado. Com o [i]setIcon()[/i], aparece o ícone do lado do texto. O que quero é que o texto fique por cima da imagem... Obrigado!
William Seefeld

William Seefeld

Responder

Posts

09/11/2011

Douglas Eric

Você pode... criar uma subclasse de JButton e sobreescrever o método paintComponent, para desenhar a imagem antes de colocar o texto assim
public class BackgroundButton extends javax.swing.JButton{
    //Carrega a sua imagem
    ImageIcon imagem = new ImageIcon(this.getClass().getResource("images/Fundo.png"));
    
    public void paintComponent(Graphics g) {
        
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        final Image backgroundImage = imagem.getImage();
        double scaleX = getWidth() / (double) backgroundImage.getWidth(null);
        double scaleY = getHeight() / (double) backgroundImage.getHeight(null);
        AffineTransform xform = AffineTransform.getScaleInstance(scaleX, scaleY);
        ((Graphics2D) g).drawImage(backgroundImage, xform, this);
        
        String texto = this.getText();
            
        // Find the size of string s in font f in the current Graphics context g.
        Font font = new Font("Dialog", Font.PLAIN, 11);
        java.awt.FontMetrics fm   = g.getFontMetrics(font);
        java.awt.geom.Rectangle2D rect = fm.getStringBounds(texto, g);

        int textWidth  = (int)(rect.getWidth());
        int textHeight = (int)(rect.getHeight());

        Dimension size = this.getSize();

        int x = (size.width - textWidth)/2;
        int y = (size.height - textHeight)/2 + fm.getAscent();

        g.drawString(texto, x, y);
        
    }
}
Pra centralizar a String, eu usei isso aqui como base http://www.leepoint.net/notes-java/GUI-appearance/fonts/18font.html Mas por algum motivo, se o botão for pequeno e o texto muito grande, ele acaba ficando fora do lugar. [img]http://javafree.uol.com.br/forum/images/smiles/icon_arrow.gif[/img]
Responder

Gostei + 0

10/11/2011

Douglas Eric

:D Era isso mesmo que eu queria, até melhor..., pois a imagem é desenhada no tamanho do botão! Quanto ao texto fora da posição acho que não vai ficar tão mal... não pretendo colocar mais do que 20 caracteres. Bom, surgiu outro probleminha... Nos JButton's é possível usar html para definir o texto. Com essa modificação ele não processa mais. Como resolver isso? Pensei em desenhar um JLabel no lugar do texto... Vou tentar amanhã quando tiver tempo. Dou o resultado aqui...
Responder

Gostei + 0

10/11/2011

Douglas Eric

Desenhar um JLabel teoricamente funciona... deixa eu fazer uns testes aqui
Responder

Gostei + 0

10/11/2011

Douglas Eric

feito!
public class BackgroundHtmlButton extends javax.swing.JButton{  

     JLabel label ;
     ImageIcon imagem = new ImageIcon(this.getClass().getResource("images/Fundo.png")); 
     
     public BackgroundHtmlButton(String text){
         this(); //ops, tinha faltado essa linha!
         label.setText(text);
     }
     
     public BackgroundHtmlButton(){
         label = new JLabel();
         this.add(label);
     }
     
     
      
    public void paintComponent(Graphics g) {  

        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
          
        final Image backgroundImage = imagem.getImage();  
        double scaleX = getWidth() / (double) backgroundImage.getWidth(null);  
        double scaleY = getHeight() / (double) backgroundImage.getHeight(null);  
        AffineTransform xform = AffineTransform.getScaleInstance(scaleX, scaleY);  
        ((Graphics2D) g).drawImage(backgroundImage, xform, this); 
          
    }  
    /**
     * Para redirecionar o setText para o label
     * 
     * @param text, texto do botão em html
     */
    @Override
    public void setText(String text){
        label.setText(text);
    }
}  
Responder

Gostei + 0

11/11/2011

Douglas Eric

:evil: :evil: :evil: Cara... vc faz isso paracer simples pra caramba! Obrigado pela ajuda, problema resolvido! Só uma última dúvida, sobre o código agora... Para que serve o [i]this();[/i] na linha 7?
Responder

Gostei + 0

11/11/2011

Douglas Eric

Humm.... já entendi aqui... O this() dentro do primeiro construtor chama o outro construtor, sem parâmetros!
Responder

Gostei + 0

11/11/2011

Douglas Eric

[quote="SLeanderS"]Humm.... já entendi aqui... O this() dentro do primeiro construtor chama o outro construtor, sem parâmetros!
Isso, só pra explicar melhor, a primeira linha de um construtor pode ter duas chamadas especiais: [color=blue]this[/color] ou [color=blue]super[/color] this, vai chamar outro construtor da mesma classe, mas que tenha um número diferente de argumentos, pode ser qualquer construtor, exceto o próprio que o está chamando (pois daria [url=http://javafree.uol.com.br/topic-882405-FAQ-Stack-Trace.html?page=1#201709]StackOverflowError[/url]). Geralmente esta tecnica é usada para não repetir código, por exemplo, os mesmos construtores dessa classe poderiam ser feitos desta forma
       
     public BackgroundHtmlButton(String text){  
         label = new JLabel();  
         this.add(label);
         label.setText(text);  
     }  
       
     public BackgroundHtmlButton(){  
         label = new JLabel();  
         this.add(label);  
     } 
Perceba que, o inicio do primeiro construtor, é igual ao segundo construtor, então, o código só está se repetindo. super, por sua vez, é usado em situações diferentes, você pode chamar qualquer construtor da super classe, com qualquer finalidade. Mas o importante é lembrar que: tanto this quanto super, PRECISAM ser a primeira linha do construtor, sendo assim, só é possível chamar um deles. Não se pode chamar dois construtores diferentes no mesmo construtor (mas se pode fazer uma cadeia de construtores para chamar todos eles :D )
Responder

Gostei + 0

11/11/2011

Douglas Eric

acresentando: se NÃO tiver nem 'super' nem 'this' na primeira linha, o compilador assume "super" sem argumentos (erro se a superclasse só tiver construtores com argumentos) [[]]
Responder

Gostei + 0

11/11/2011

Douglas Eric

Ficou ainda mais claro agora... Valeu pela atenção!
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar