Customizar JButton
Bom dia.
Preciso fazer um componente da classe JButton ficar com sua aparencia identica a de um JLabel
Tem como alguem de vcs me orientar no que devo fazer para alcançar meu objetivo?
Preciso fazer um componente da classe JButton ficar com sua aparencia identica a de um JLabel
Tem como alguem de vcs me orientar no que devo fazer para alcançar meu objetivo?
Israel Barbosa
Curtidas 0
Respostas
Henrique Weissmann
29/04/2010
Oi Israel:
há algumas alternativas para este problema. Repare que no objeto JButton não há um método como setBackgroundColor ou coisa similar. Isto porque a aparência destes componentes é definido a partir do look and feel que você está usando.
Sendo assim, as opções que temos são:
* Criar um look and feel customizado - é trabalhoso, mas resolveria o seu problema
* Usar um objeto JLabel como botão
* Tentar usar HTML para obter o resultado desejado
* Escolher algum look and feel que possibilite isto.
O que você acha destas alternativas?
há algumas alternativas para este problema. Repare que no objeto JButton não há um método como setBackgroundColor ou coisa similar. Isto porque a aparência destes componentes é definido a partir do look and feel que você está usando.
Sendo assim, as opções que temos são:
* Criar um look and feel customizado - é trabalhoso, mas resolveria o seu problema
* Usar um objeto JLabel como botão
* Tentar usar HTML para obter o resultado desejado
* Escolher algum look and feel que possibilite isto.
O que você acha destas alternativas?
GOSTEI 0
Israel Barbosa
29/04/2010
"Criar um look and feel customizado - é trabalhoso, mas resolveria o seu problema"
Mesmo sendo trabalhoso acredito que talves esta seja a melhor opção para obter o resultado que quero.
"Usar um objeto JLabel como botão" Usar um JLabel não seria a melhor alternativa por que ele não possui o método addActionListener e adicionar este método em uma sub-classe do JLabel tambem é trabalhoso. Eu até consegui fazer uma subClasse do JLabel executar uma ação passada como parametro, porem ele não executa a ação no pressionamento de mnmonicos e nem acelerators. Derrepente se vc quizer dar uma olhada pra ve se congue me ajudar a melhorar esta classe eu te envio o codigo. O que acha?
* Tentar usar HTML para obter o resultado desejado Conheço muito pouco de HTML
"Escolher algum look and feel que possibilite isto."
Ja tentei vários Lafs mas nenhum deu certo.
"Usar um objeto JLabel como botão" Usar um JLabel não seria a melhor alternativa por que ele não possui o método addActionListener e adicionar este método em uma sub-classe do JLabel tambem é trabalhoso. Eu até consegui fazer uma subClasse do JLabel executar uma ação passada como parametro, porem ele não executa a ação no pressionamento de mnmonicos e nem acelerators. Derrepente se vc quizer dar uma olhada pra ve se congue me ajudar a melhorar esta classe eu te envio o codigo. O que acha?
* Tentar usar HTML para obter o resultado desejado Conheço muito pouco de HTML
"Escolher algum look and feel que possibilite isto."
Ja tentei vários Lafs mas nenhum deu certo.
GOSTEI 0
Henrique Weissmann
29/04/2010
Oi Israel,
outra opção que me veio à mente seria você criar uma classe que extenda JButton e em seguida sobrescrever o método paint.
Lembro que na época do awt (eras atrás) era muito comum fazer isto com os componentes do pacote java.awt. Aliás, é uma técnica também muito usada por programadores Java ME
O que acha?
Além disto, encontrei outra solução para o seu problema. De uma lida neste post no StackOverflow e me diga o que acha ok? http://stackoverflow.com/questions/1839074/howto-make-jbutton-with-simple-flat-style
outra opção que me veio à mente seria você criar uma classe que extenda JButton e em seguida sobrescrever o método paint.
Lembro que na época do awt (eras atrás) era muito comum fazer isto com os componentes do pacote java.awt. Aliás, é uma técnica também muito usada por programadores Java ME
O que acha?
Além disto, encontrei outra solução para o seu problema. De uma lida neste post no StackOverflow e me diga o que acha ok? http://stackoverflow.com/questions/1839074/howto-make-jbutton-with-simple-flat-style
GOSTEI 0
Israel Barbosa
29/04/2010
Otima idéia, daqui a pouco te retorno, blz?
GOSTEI 0
Henrique Weissmann
29/04/2010
Ok, no aguardo.
GOSTEI 0
Israel Barbosa
29/04/2010
Ola Henrique testei a solução do stackOverFlow porem sem exito, observe a imagem o botão escrito text foi criado apartir da solução do link que vc indicou.
* Então Henrique eu preciso fazer um menu lateral na minha aplicação porem não posso usar o JXHyperlink , JXTaskPane e nem a JTree do Java porque esses componentes são muito feios.
Tenho que dar um jeito de sumir com essa aparencia 3D do JButton e deixar aparencendo somente o texto dele
assim como em (Cadastros, categorias, usuarios, clientes).
Com relação a escrita do método paint parece ser uma boa alternativa porem não sei como fazer
E quanto a escrever uma classe de Look & Feel alternativo tambem parece ser uma boa idéia, porem em ambos os casos não sei como proceder.
O que faço?
GOSTEI 0
Henrique Weissmann
29/04/2010
Oi Israel,
entre as duas alternativas, reescrever o método paint me parece ser a mais viável.
Há um tutorial excelente que você pode baixar aqui: http://java.sun.com/docs/books/tutorial/uiswing/painting/index.html
entre as duas alternativas, reescrever o método paint me parece ser a mais viável.
Há um tutorial excelente que você pode baixar aqui: http://java.sun.com/docs/books/tutorial/uiswing/painting/index.html
GOSTEI 0
Israel Barbosa
29/04/2010
Vou ler o tutorial, logo mais entro em contato, blz. E quanto a adicionar um método addActionListener ao JLabel?
veja a classe que encontrei na Internet, ela executa um ação que passada ao componente quando ele é clicado,
porém ela não configura outras propriedades provindas de um objeto que extende AbstractAction, como Mnemonicos, Acelerators, Icon ... Se o método de paint não funcionar talves possa-mos melhorar esta classe.
O que me diz?
package br.com.fap.uif_lite.component;
import java.awt.AWTEvent;
import java.awt.AWTEventMulticaster;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent; import javax.swing.Action; import org.jdesktop.swingx.JXLabel; public class ActionLabel extends JXLabel {
public final int XMARGIN = 2, YMARGIN = 2;
public final int ACTIVE = 1, IDLE = 0, PRESSED = 2;
static final Color[] clr = { Color.blue, Color.red, Color.black };
ActionListener lst;
String txt, cmd;
public int state;
int align; // ctor
public ActionLabel(String str, int alg) {
align = alg;
cmd = txt = str;
state = IDLE;
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
lst = null;
} public ActionLabel(String str) {
this(str, Label.LEFT);
}
public ActionLabel(String title, Action action) {
super.setText(title);
this.lst = action;
} public ActionLabel() {
this("", Label.LEFT);
} // paint
// public void paint(Graphics g) {
// FontMetrics fm = getFontMetrics(getFont());
// int wt = fm.stringWidth(txt);
// int ht = fm.getHeight();
// Rectangle r = getBounds();
// int w = r.width;
// int h = r.height;
// int x = (w - wt) >> 1;
// int y = ((h + ht) >> 1) - 2;
// if (align == Label.LEFT)
// x = 0;
// else if (align == Label.RIGHT)
// x = w - wt;
// g.setColor(clr[state]);
// g.drawString(txt, x, y);
// g.drawLine(x, y + 1, x + wt, y + 1);
// } // getMinimumSize
public Dimension getMinimumSize() {
FontMetrics fm = getFontMetrics(getFont());
int h = fm.getHeight() + YMARGIN + YMARGIN;
int w = fm.stringWidth(txt) + XMARGIN + XMARGIN;
return new Dimension(w, h);
} // minimumSize
public Dimension minimumSize() {
return getMinimumSize();
} // preferredSize
public Dimension preferredSize() {
return getMinimumSize();
} // getPreferredSize
public Dimension getPreferredSize() {
return getMinimumSize();
} //
public void released() {
int a = state;
state = ACTIVE;
if (a != state)
repaint();
postAction();
} //
public void pressed() {
int a = state;
state = PRESSED;
if (a != state)
repaint();
} //
public void entered() {
int a = state;
state = ACTIVE;
if (a != state)
repaint();
} //
public void exited() {
int a = state;
state = IDLE;
if (a != state)
repaint();
} //
public void processEvent(AWTEvent e) {
if (e.getID() == MouseEvent.MOUSE_PRESSED)
pressed();
else if (e.getID() == MouseEvent.MOUSE_ENTERED)
entered();
else if (e.getID() == MouseEvent.MOUSE_EXITED)
exited();
else if (e.getID() == MouseEvent.MOUSE_RELEASED)
released();
super.processEvent(e);
} //
public void setActionCommand(String c) {
cmd = c;
} //
public void addActionListener(ActionListener l) {
lst = AWTEventMulticaster.add(lst, l);
} //
public void removeActionListener(ActionListener l) {
lst = AWTEventMulticaster.remove(lst, l);
} //
private void postAction() {
if (lst != null) {
ActionEvent event = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, cmd);
lst.actionPerformed(event);
}
}
}
import java.awt.AWTEventMulticaster;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent; import javax.swing.Action; import org.jdesktop.swingx.JXLabel; public class ActionLabel extends JXLabel {
public final int XMARGIN = 2, YMARGIN = 2;
public final int ACTIVE = 1, IDLE = 0, PRESSED = 2;
static final Color[] clr = { Color.blue, Color.red, Color.black };
ActionListener lst;
String txt, cmd;
public int state;
int align; // ctor
public ActionLabel(String str, int alg) {
align = alg;
cmd = txt = str;
state = IDLE;
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
lst = null;
} public ActionLabel(String str) {
this(str, Label.LEFT);
}
public ActionLabel(String title, Action action) {
super.setText(title);
this.lst = action;
} public ActionLabel() {
this("", Label.LEFT);
} // paint
// public void paint(Graphics g) {
// FontMetrics fm = getFontMetrics(getFont());
// int wt = fm.stringWidth(txt);
// int ht = fm.getHeight();
// Rectangle r = getBounds();
// int w = r.width;
// int h = r.height;
// int x = (w - wt) >> 1;
// int y = ((h + ht) >> 1) - 2;
// if (align == Label.LEFT)
// x = 0;
// else if (align == Label.RIGHT)
// x = w - wt;
// g.setColor(clr[state]);
// g.drawString(txt, x, y);
// g.drawLine(x, y + 1, x + wt, y + 1);
// } // getMinimumSize
public Dimension getMinimumSize() {
FontMetrics fm = getFontMetrics(getFont());
int h = fm.getHeight() + YMARGIN + YMARGIN;
int w = fm.stringWidth(txt) + XMARGIN + XMARGIN;
return new Dimension(w, h);
} // minimumSize
public Dimension minimumSize() {
return getMinimumSize();
} // preferredSize
public Dimension preferredSize() {
return getMinimumSize();
} // getPreferredSize
public Dimension getPreferredSize() {
return getMinimumSize();
} //
public void released() {
int a = state;
state = ACTIVE;
if (a != state)
repaint();
postAction();
} //
public void pressed() {
int a = state;
state = PRESSED;
if (a != state)
repaint();
} //
public void entered() {
int a = state;
state = ACTIVE;
if (a != state)
repaint();
} //
public void exited() {
int a = state;
state = IDLE;
if (a != state)
repaint();
} //
public void processEvent(AWTEvent e) {
if (e.getID() == MouseEvent.MOUSE_PRESSED)
pressed();
else if (e.getID() == MouseEvent.MOUSE_ENTERED)
entered();
else if (e.getID() == MouseEvent.MOUSE_EXITED)
exited();
else if (e.getID() == MouseEvent.MOUSE_RELEASED)
released();
super.processEvent(e);
} //
public void setActionCommand(String c) {
cmd = c;
} //
public void addActionListener(ActionListener l) {
lst = AWTEventMulticaster.add(lst, l);
} //
public void removeActionListener(ActionListener l) {
lst = AWTEventMulticaster.remove(lst, l);
} //
private void postAction() {
if (lst != null) {
ActionEvent event = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, cmd);
lst.actionPerformed(event);
}
}
}
GOSTEI 0
Henrique Weissmann
29/04/2010
Entendi.
Não há como adicionar um actionListener a um JLabel. Mas encontrei uma "alternativa" bem interessante no Java Ranch. Da uma olhada neste link: http://www.coderanch.com/t/345978/Swing-AWT-SWT-JFace/java/actionListener-JLabel
Mais especificamente neste trecho:
No you can't. You can add a MouseListener though.
There is a trick that can give you a "label" that acts like a button. This is based on the notion that a radio button looks very much like a label with a button in front of it:
view plaincopy to clipboardprint?JRadioButton button = new JRadioButton("label"); // other button methods button.setIcon(new Icon() { public void paintIcon(Component c, Graphics g, int x, int y) { // do nothing } public int getIconWidth() { return 0; } public int getIconHeight() { return 0; } }); JRadioButton button = new JRadioButton("label"); // other button methods button.setIcon(new Icon() { public void paintIcon(Component c, Graphics g, int x, int y) { // do nothing } public int getIconWidth() { return 0; } public int getIconHeight() { return 0; } });
Now keep in mind that this is just quick & dirty. A better way would be to create your own subclass of AbstractButton, then use a ButtonUI to do the painting. You can use JRadioButton as an example, but strip the specific radio button behaviour.
Não há como adicionar um actionListener a um JLabel. Mas encontrei uma "alternativa" bem interessante no Java Ranch. Da uma olhada neste link: http://www.coderanch.com/t/345978/Swing-AWT-SWT-JFace/java/actionListener-JLabel
Mais especificamente neste trecho:
No you can't. You can add a MouseListener though.
There is a trick that can give you a "label" that acts like a button. This is based on the notion that a radio button looks very much like a label with a button in front of it:
view plaincopy to clipboardprint?JRadioButton button = new JRadioButton("label"); // other button methods button.setIcon(new Icon() { public void paintIcon(Component c, Graphics g, int x, int y) { // do nothing } public int getIconWidth() { return 0; } public int getIconHeight() { return 0; } }); JRadioButton button = new JRadioButton("label"); // other button methods button.setIcon(new Icon() { public void paintIcon(Component c, Graphics g, int x, int y) { // do nothing } public int getIconWidth() { return 0; } public int getIconHeight() { return 0; } });
Now keep in mind that this is just quick & dirty. A better way would be to create your own subclass of AbstractButton, then use a ButtonUI to do the painting. You can use JRadioButton as an example, but strip the specific radio button behaviour.
GOSTEI 0
Israel Barbosa
29/04/2010
Blz, vou ler o post inteiro para entender e testar a solução, ja te retorno
GOSTEI 0
Israel Barbosa
29/04/2010
Então Henrique, o código funciona porem o problema do mnemonicos e teclas de Atalho ainda persistem.
Tem mais alguma alternativa?
GOSTEI 0
Henrique Weissmann
29/04/2010
Pois é. O problema dos mnemonicos com JLabel é que eles são usados para redirecionar o foco para outro componente (uma caixa de texto relacionada por exemplo).
Neste caso, o que eu sugiro é você adicionar um keylistener ao seu formulário que intercepte as chamadas de teclado relacionadas aos mnemonicos.
Interceptando-as, execute as ações relativas ao seu JLabel.
Não é uma solução elegante, confesso: mas é a única que consigo ver neste momento.
Neste caso, o que eu sugiro é você adicionar um keylistener ao seu formulário que intercepte as chamadas de teclado relacionadas aos mnemonicos.
Interceptando-as, execute as ações relativas ao seu JLabel.
Não é uma solução elegante, confesso: mas é a única que consigo ver neste momento.
GOSTEI 0
Israel Barbosa
29/04/2010
Mas esta tecla ´só vai funcionar se o componente tiver focado. Eu precisava que funcionasse quando o componente estivesse na janela que contem o foco. Tem jeito de fazer?
GOSTEI 0
Henrique Weissmann
29/04/2010
Sim, implementando o evento keylistener no formulário.
GOSTEI 0
Devmedia
29/04/2010
Israel,
a resposta do consultor oi suficiente? Podemos encerrar o chamado?
a resposta do consultor oi suficiente? Podemos encerrar o chamado?
GOSTEI 0
Israel Barbosa
29/04/2010
Eu mesmo encontrei a solução!
GOSTEI 0