2011-04-27 77 views
7

Estoy tratando de cambiar el color de un JToggleButton cuando se ha seleccionado de manera fiable, se ve y se siente de forma independiente.Cambio del color de fondo de un JToggleButton seleccionado

Si se utiliza el metal L & M, a continuación, utilizando el UIManager es una aproximación:

UIManager.put("ToggleButton.selected", Color.RED); 

Nota: Iyy señalado que tenía un error tipográfico en el nombre de la propiedad anterior, pero lo dejaré por encima de la gente para llegar hasta aquí, pero el nombre de la propiedad real se supone que es:

UIManager.put("ToggleButton.select", Color.RED); 

sin embargo, esto no funciona en mi mirada actual y Feel (actualmente Windows XP). Después de algunos análisis posteriores, parece que el aspecto del sistema en Windows (todavía XP) no utiliza ninguna de las propiedades Color basadas en para ToggleButton, o al menos no las proporciona (hay un ejemplo rápido) en línea a find all property keys from the UIManager, que en el ejemplo está convenientemente limitado explícitamente a Color propiedades).

He intentado fijar el color de fondo:

Action action = new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { /* stuff */ } 
}; 
JToggleButton button = new JToggleButton(action); 
// tried with and without opaque true 
button.setOpaque(true); 
button.setBackground(Color.RED); 

Ello no sólo no cambia el estado seleccionado, pero que ni siquiera Cómo afecta el estado no seleccionado.

He intentado cambiar el color de fondo sólo después de recibir la acción:

@Override 
public void actionPerformed(ActionEvent e) 
{ 
    JToggleButton button = (JToggleButton)e.getSource(); 
    if (button.isSelected()) // alternatively, (Boolean)getValue(Action.SELECTED_KEY) 
    { 
     button.setBackground(Color.RED); 
    } 
} 

Nada de eso funciona. La única cosa que he encontrado para el trabajo me requiere para extraer el botón de mí mismo en el estado seleccionado (que conduce a un ejemplo de trabajo, aunque buscando no estándar):

private class ColoredToggleButton extends JToggleButton 
{ 
    ColoredToggleButton(Action action, Color color) 
    { 
     super(action); 

     setBackground(color); 
    } 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     if (this.isSelected()) 
     { 
      int w = getWidth(); 
      int h = getHeight(); 
      String s = getText(); 

      // selected color 
      g.setColor(getBackground()); 
      g.fillRect(0, 0, w, h); 
      // selected foreground color 
      g.setColor(SystemColor.controlText); 
      g.drawString(s, 
         (w - g.getFontMetrics().stringWidth(s))/2 + 1, 
         (h + g.getFontMetrics().getAscent())/2 - 1); 
     } 
    } 
} 

que es ligeramente modificado a partir de un comentario en el esto Java bug report. Curiosamente (¿entretenido?), En las reclamaciones que se han corregido en 1998.

¿Alguien sabe de una manera mejor, L & F independiente para establecer el color de fondo de un JToggleButton seleccionado?

+0

puede anular BasicbuttonUI o simplemente MetalButtonUI (entonces sólo para metal L & F) algún indicio http://stackoverflow.com/questions/5751311/creating-custom-button -in-java/5755124 # 5755124 – mKorbel

+0

¿por qué? se supone que el LAF controla el aspecto, mejor deje que sea su deber; si logra interferir, su pintura/color personalizado sobresaldrá como un pulgar dolorido en todo – kleopatra

+0

@kleopatra. Generalmente estoy de acuerdo en que dejar el L & F es una buena práctica, pero simplemente, esta es una característica deseada. En particular, en realidad está destinado a sobresalir. – pickypg

Respuesta

3

Puede ver si setIcon() es suficiente para su propósito, pero también puede anular paint() en el delegado ButtonUI.

Adición: El comentario de @kleopatra es bueno: cambiar el delegado de la interfaz de usuario es no trivial. El reciente example de @ mKorbel muestra tanto la dificultad como la versatilidad del enfoque. Su ventaja esencial es mirar & sentir independencia.

Se mencionan algunos enfoques menos ambiciosos here.

+0

re: implementa una ButtonUI/subclase personalizada una existente - seguro, todo es posible - pero no todo es factible ;-) Un fuerte "No" de mi parte. – kleopatra

+0

@kleopatra: Agradezco su comentario; Intenté poner esto en perspectiva, arriba. – trashgod

+0

@ Jeanette Siempre aprecio tu patada entre mis ojos, porque siempre fue sobre (mi) lo que es poppycock, pero OP puede no querer escuchar que no es posible, espera el parche de BugsParade, entonces tiende a responderte * ** crea CustomComponents, si no estás satisfecho con las opciones setForeground o configura el ícono – mKorbel

5

"ToggleButton.selected" es incorrecto, requiere "ToggleButton.select". Y debe actualizarse al componente.

UIManager.put("ToggleButton.select", Color.WHITE); 
SwingUtilities.updateComponentTreeUI(togglebuttonname); 
+0

¡Es una gran captura y esto funciona! Sin embargo, hay una advertencia bastante grande de que afecta globalmente a todos los 'JToggleButton's a menos que usted cree su propia instancia y proporcione un nuevo' ComponentUI createUI estático (JComponent c) 'para él. Como resultado, todavía estoy atascado, pero para aquellos que quieren cambiar el color de fondo globalmente, su enfoque es una solución de trabajo. – pickypg

+0

Estaba demasiado emocionado, y el error de ortografía es una buena opción. Sin embargo, esto no funciona en el aspecto y la sensación del sistema de Windows. – pickypg

+0

Al examinarlo aún más, parece que el sistema L & F ni siquiera utiliza ninguna de las teclas ToggleButton asociadas con 'Color' (por ejemplo," ToggleButton.background "). – pickypg

3
JToggleButton btn = new JToggleButton(...); 
btn.setUI(new MetalToggleButtonUI() { 
    @Override 
    protected Color getSelectColor() { 
     return Color.RED; 
    } 
}); 
1

simplemente Puede forzar color de fondo antes de cada pintar - para eso se tiene que alterar paintComponent, comprobar si se activa el botón, poner el fondo en función del estado de conmutación y, por último, dejar que superclase hacer lo trabajo de pintura real:

public class ColoredToggleButton extends JToggleButton 
{ 
    @Override 
    public void paintComponent(Graphics g) 
    { 
     Color bg; 
     if (isSelected()){ 
      bg = Color.GREEN; 
     } else { 
      bg = Color.RED; 
     } 
     setBackground(bg); 
     super.paintComponent(g); 
    } 
} 
0

Si prefiere utilizar un detector de acción en lugar de sobreescribir métodos en una interfaz de usuario que acaba puede cambiar la interfaz de usuario de una interfaz de usuario sin ningún selectColor propiedades.

Aquí es un ejemplo he usado recientemente

private class FavouriteToggle extends JToggleButton { 
    public FavouriteToggle() { 
     setUI(new BasicToggleButtonUI()); //Removes selectColor 

     ////Your Custom L&F Settings//// 
     setBackground(new Color(255, 252, 92)); 
     setForeground(Color.GRAY); 
     setText("Favourite"); 
     setBorder(null); 
     setFocusPainted(false); 

     ////Add your own select color by setting background//// 
     addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if(((JToggleButton) e.getSource()).isSelected()) { 
        setForeground(Color.BLACK); 
        setBackground(new Color(255, 251, 0)); 
       } else { 
        setBackground(new Color(255, 252, 92)); 
        setForeground(Color.GRAY); 
       } 
      } 
     }); 
    } 
} 
Cuestiones relacionadas