Fórum Customizar JButton #376581
29/04/2010
0
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
Curtir tópico
+ 0Posts
29/04/2010
Henrique Weissmann
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
29/04/2010
Israel Barbosa
"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
29/04/2010
Henrique Weissmann
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
29/04/2010
Israel Barbosa
Gostei + 0
29/04/2010
Henrique Weissmann
Gostei + 0
29/04/2010
Israel Barbosa
Gostei + 0
29/04/2010
Henrique Weissmann
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
29/04/2010
Israel Barbosa
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
29/04/2010
Henrique Weissmann
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
29/04/2010
Israel Barbosa
Gostei + 0
29/04/2010
Israel Barbosa
Gostei + 0
29/04/2010
Henrique Weissmann
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
29/04/2010
Israel Barbosa
Gostei + 0
29/04/2010
Henrique Weissmann
Gostei + 0
10/05/2010
Devmedia
a resposta do consultor oi suficiente? Podemos encerrar o chamado?
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)