Pergunta
Existe uma maneira de criar um JButton
com o seu próprio botão de gráfico e não apenas com uma imagem dentro do botão?
Se não, existe alguma outra forma de criar um personalizado JButton
em java?
Solução
Quando eu estava começando a aprender Java que nós tínhamos que fazer Yahtzee e eu pensei que seria legal criar personalizado Balanço de componentes e containers em vez de apenas desenhar tudo em um JPanel
.O benefício de estender Swing
componentes, é claro, é ter a capacidade de adicionar suporte para atalhos de teclado e outras funcionalidades de acessibilidade que você não pode fazer apenas por ter um paint()
método de impressão de uma imagem bonita.Ele não pode ser feito da melhor maneira, no entanto, mas pode ser um bom ponto de partida para você.
Editar 8/6 - Se que não era aparente a partir das imagens, cada dado é um botão, você pode clicar.Isto irá movê-lo para a DiceContainer
abaixo.Olhando o código fonte você pode ver que cada dado que o botão é desenhado de forma dinâmica, com base em seu valor.
Aqui estão as etapas básicas:
- Criar uma classe que estende
JComponent
- Chamada principal construtor
super()
em seu construtores - Certifique-se de que a classe implementa
MouseListener
Coloque isso no construtor:
enableInputMethods(true); addMouseListener(this);
Substituir esses métodos:
public Dimension getPreferredSize() public Dimension getMinimumSize() public Dimension getMaximumSize()
Substituir esse método:
public void paintComponent(Graphics g)
A quantidade de espaço que você tem para trabalhar com quando o desenho do botão que é definida por getPreferredSize()
, assumindo getMinimumSize()
e getMaximumSize()
retornar o mesmo valor.Eu ainda não experimentei muito com isso, mas, dependendo do layout que você usar para o GUI o botão de olhar completamente diferente.
E, finalmente, o código-fonte.No caso de eu perdi alguma coisa.
Outras dicas
Sim, isso é possível.Uma das principais vantagens para o uso de Swing é a facilidade com a qual o resumo controles podem ser criados e manipulados.
Aqui está uma maneira rápida e suja de estender o existente JButton classe para desenhar um círculo à direita do texto.
package test;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyButton extends JButton {
private static final long serialVersionUID = 1L;
private Color circleColor = Color.BLACK;
public MyButton(String label) {
super(label);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension originalSize = super.getPreferredSize();
int gap = (int) (originalSize.height * 0.2);
int x = originalSize.width + gap;
int y = gap;
int diameter = originalSize.height - (gap * 2);
g.setColor(circleColor);
g.fillOval(x, y, diameter, diameter);
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width += size.height;
return size;
}
/*Test the button*/
public static void main(String[] args) {
MyButton button = new MyButton("Hello, World!");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(button);
frame.setVisible(true);
}
}
Observe que substituindo paintComponent o conteúdo do botão pode ser alterado, mas que a fronteira é pintado pelo paintBorder o método.O getPreferredSize o método também precisa ser gerenciado de forma dinâmica apoio alterações ao conteúdo.O cuidado precisa ser tomado quando da medição e métricas de fonte dimensões da imagem.
Para criar um controle que você pode confiar, o código acima não é a abordagem correta.Dimensões e cores são dinâmicas no Balanço e são dependentes do olhar e sentir que está sendo usado.Até mesmo o padrão Metal olhar foi alterado entre as versões do JRE.Seria melhor implementar AbstractButton e estão em conformidade com as linhas orientadoras definidas pelo Swing API.Um bom ponto de partida é olhar para o javax.swing.LookAndFeel e javax.swing.UIManager classes.
http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html
http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html
Compreender a anatomia de LookAndFeel é útil para escrever controles:Criar uma Aparência Personalizada e Sentir
Você pode sempre tentar o Sintetizador de olhar e sentir.Você forneça um arquivo xml que funciona como um tipo de folha de estilo, juntamente com as imagens que você deseja usar.O código teria esta aparência:
try {
SynthLookAndFeel synth = new SynthLookAndFeel();
Class aClass = MainFrame.class;
InputStream stream = aClass.getResourceAsStream("\\default.xml");
if (stream == null) {
System.err.println("Missing configuration file");
System.exit(-1);
}
synth.load(stream, aClass);
UIManager.setLookAndFeel(synth);
} catch (ParseException pe) {
System.err.println("Bad configuration file");
pe.printStackTrace();
System.exit(-2);
} catch (UnsupportedLookAndFeelException ulfe) {
System.err.println("Old JRE in use. Get a new one");
System.exit(-3);
}
De lá, vá em frente e adicione o seu JButton como você normalmente faria.A única alteração é que você use o setName(string) método para identificar o que o botão deve mapa no arquivo xml.
O arquivo xml pode ter este aspecto:
<synth>
<style id="button">
<font name="DIALOG" size="12" style="BOLD"/>
<state value="MOUSE_OVER">
<imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
<insets top="2" botton="2" right="2" left="2"/>
</state>
<state value="ENABLED">
<imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
<insets top="2" botton="2" right="2" left="2"/>
</state>
</style>
<bind style="button" type="name" key="dirt"/>
</synth>
O bind elemento não especifica o que a mapa (neste exemplo, ele vai aplicar o estilo a qualquer dos botões cujo nome de propriedade tem sido definido como "sujeira").
E um par de links úteis:
http://javadesktop.org/articles/synth/
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html
Eu provavelmente vou um milhão de milhas errado direta (mas eu sou jovem só :P ).mas não consegui adicionar o gráfico para um painel e, em seguida, um mouselistener para o objeto gráfico, de modo que quando o usuário no gráfico a sua ação é executada.
Eu não fiz SWING desenvolvimento desde o início do meu CS classes, mas se ele não foi construída em apenas poderia herdar javax.swing.AbstractButton
e criar o seu próprio.Deve ser bastante simples de arame algo junto com seu quadro existente.