[RESOLVIDO] Colocar imagem de fundo em um JButton
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
Curtidas 0
Respostas
Douglas Eric
09/11/2011
Você pode...
criar uma subclasse de JButton e sobreescrever o método paintComponent, para desenhar a imagem antes de colocar o texto
assim
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]
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);
}
}
GOSTEI 0
Douglas Eric
09/11/2011
: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...
GOSTEI 0
Douglas Eric
09/11/2011
Desenhar um JLabel teoricamente funciona...
deixa eu fazer uns testes aqui
GOSTEI 0
Douglas Eric
09/11/2011
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);
}
}
GOSTEI 0
Douglas Eric
09/11/2011
: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?
GOSTEI 0
Douglas Eric
09/11/2011
Humm.... já entendi aqui...
O this() dentro do primeiro construtor chama o outro construtor, sem parâmetros!
GOSTEI 0
Douglas Eric
09/11/2011
[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);
}
GOSTEI 0
Douglas Eric
09/11/2011
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)
[[]]
GOSTEI 0
Douglas Eric
09/11/2011
Ficou ainda mais claro agora...
Valeu pela atenção!
GOSTEI 0