2012-04-26 38 views
8

He estado trabajando para hacer una transición de una aplicación Java de WindowsLookAndFeel a Nimbus, en gran parte con éxito, a pesar de las deficiencias de Nimbus. A mis usuarios en general les gusta el Nimbus LaF, pero no me gustaron algunos detalles, algunos de los cuales cambié al consultar preguntas anteriores en este sitio. Ejemplo: copié el LeafIcon, ClosedIcon y OpenIcon de Windows LaF (que les gustó) y los uso en la versión de Nimbus, para una buena combinación de LaFs.cambiando cómo maneja Nimbus LaF JTree nodo resaltado

Atascado en un último (?) Problema.

Tengo un JTree con un DefaultCellRenderer subclasificado para crear las pantallas de nodo apropiadas. Esto funciona bien bajo WindowsLookAndFeel.

Problema: En WindowsLaF cuando se selecciona un nodo, el texto del nodo se resalta y el efecto es visualmente fácil de entender. Bajo Nimbus cuando se selecciona un nodo, el resaltado se realiza con una barra de color (bastante oscuro) que se ejecuta en el ancho de la ventana del árbol (no solo el ancho del texto), y el efecto es desconcertante.

Así que: simplemente quiero el tratamiento con WindowsLaF del resaltado del nodo JTree en el Nimbus LaF (es decir, el fondo de color solo tiene el ancho del texto, y preferiblemente en un color mejor que puedo elegir). Sospecho que esto significa que necesito asignar el tipo correcto de Pintor al "Árbol: TreeCell [Enfocado + Seleccionado] .backgroundPainter", pero no sé cómo escribirlo.

Sugerencias bienvenidas.


EDITAR

Véase el punto culminante nodo seleccionado extraña con Java 7!

enter image description here

public class TreeBorder { 
    public static void main(String[] args) { 
     try{ 
      for(UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
       if("Nimbus".equals(info.getName())) { 
        UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame f = new JFrame(); 
       f.setLocationRelativeTo(null); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.getContentPane().add(getJTree()); 
       f.pack(); 
       f.setVisible(true); 
      } 
      private JTree getJTree() { 
       JTree jTree = new JTree(); 
       jTree.setCellRenderer(new LocalRenderer()); 
       return jTree; 
      } 
     }); 
    } 

    private static class LocalRenderer extends DefaultTreeCellRenderer { 
     @Override 
     public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasfocus) { 
      DefaultTreeCellRenderer result = (DefaultTreeCellRenderer)super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasfocus); 
       if(true) { 
        result.setFont(new JLabel().getFont()); 
        Icon icon = UIManager.getIcon("FileView.floppyDriveIcon"); 
        result.setIcon(icon); 
       } 
      return(result); 
     } 
    } 
} 
+0

Adición a mi publicación: por supuesto, si hay una manera más fácil que un pintor, sería aún mejor. Intenté simplemente cambiar Tree.selectionBackground por un color menos distrayente, pero Nimbus parece ignorar la modificación. – user1359010

+0

Además de mi comentario. No puede establecer Tree.selectionBackground directamente, pero este color se deriva de numbusSelectionBackground, por lo que nimbUID.put ("nimbusSelectionBackground", nuevo ColorUIResource (205,208,216)); produce algunos del efecto deseado (un Tree.selectionBackground más ligero). Todavía se resalta una fila en lugar de solo el texto, por lo que la ayuda para un pintor aún sería apreciada. – user1359010

+0

@oliholz, por favor, puede comentar su generosidad, seguro de que nunca voy a ver esta pregunta, porque el concepto clásico de Renderers sobrecarga las propiedades y configuraciones de Nimbus en la mayoría de los casos – mKorbel

Respuesta

6

Editar

La tecla "Tree.selectionBackground" es lo que controla el resaltado en el JTree - se hace en el nivel de los árboles, no en el nivel TreeCellRenderer (que es por qué es un poco confuso de manejar). Este código le conseguirá un árbol donde se puede controlar el resaltado:

private JTree getJTree() { 

    JTree jTree = new JTree(); 
    jTree.setOpaque(true); 
    jTree.setBackground(Color.white); 
    UIDefaults paneDefaults = new UIDefaults(); 
    paneDefaults.put("Tree.selectionBackground",null); 

    JTextPane pane = new JTextPane(); 
    jTree.putClientProperty("Nimbus.Overrides",paneDefaults); 
    jTree.putClientProperty("Nimbus.Overrides.InheritDefaults",false); 

    jTree.setCellRenderer(new LocalRenderer()); 
    return jTree; 
} 

Y he aquí un ejemplo de cambiar el selector al rojo. Tenga en cuenta que también se resaltará el fondo del icono: este es el comportamiento predeterminado para los no nimbus L & F también. Si no desea que el icono que se puso de relieve, vas a tener que usar algo más elaborado que el defecto JLabel para hacer que el TreeCell:

public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasfocus) { 
     DefaultTreeCellRenderer result = (DefaultTreeCellRenderer)super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasfocus); 
     result.setOpaque(true); 
      if(true) { 
       result.setFont(new JLabel().getFont()); 
       Icon icon = UIManager.getIcon("FileView.floppyDriveIcon"); 
       result.setIcon(icon); 
      } 
      if(sel){ 
       result.setBackground(Color.red); 
      } else{ 
       result.setBackground(Color.white); 
      } 
     return(result); 
    } 

respuesta original

Uno de los más fáciles La forma de solucionar esto es establecer el color de fondo seleccionado en transparente. El problema es que está tratando de pintar el fondo de la etiqueta, que no tiene el genial pintor Nimbus utilizado por la selección de JTree.Así que añadir esta línea a getTreeCellRendererComponent método:

result.setBackgroundSelectionColor(new Color(0,0,0,0)); 

Otra opción es utilizar el pintor aureola para el fondo de la TreeCellRenderer - pero eso parece un exceso en esta situación.

+0

hmm ... en realidad no, ya que entendí que la pregunta se trata de evitar el coloreado de fondo _desde_ el renderizador (manteniéndolo _inside_) Usar un color invisible (si tiene algún efecto) evitaría ambos. – kleopatra

+0

@kleopatra Hehe ... tal vez lea la pregunta completa la próxima vez. Buena atrapada. –

+0

OP aquí; Acabo de regresar después de un largo tiempo, encantado de ver la respuesta a la pregunta, y funciona. Muchas gracias por el código y la información que se maneja en el nivel del árbol. – user1359010

Cuestiones relacionadas