2012-07-01 12 views
5

Al editar datos en una JTable (Nimbus L & F), como el usuario pestañas de celda a celda, no es obvio qué celda tiene foco. ¿Cómo puedo aclarar qué célula tiene foco? Sé que hay varias propiedades que se pueden configurar para modificar Nimbus. ¿Alguien sabe qué propiedad quiero?JTable Nimbus Look and Feel: cómo dejar en claro qué celda tiene foco

La siguiente captura de pantalla sólo tiene un conjunto de propiedades a algo distinto del predeterminado:

UIManager.put("Table.showGrid", true); 

JTable screen shot

Respuesta

3

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Pattern; 
import javax.swing.Icon; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.RowSorter.SortKey; 
import javax.swing.SortOrder; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.TableColumn; 
import javax.swing.table.TableModel; 
import javax.swing.table.TableRowSorter; 

public class ImageChangeDemo extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JTable table = new javax.swing.JTable(); 
    private JTable table1 = new javax.swing.JTable(); 
    private static Icon ascendingSortIcon; 
    private static Icon descendingSortIcon; 

    public static void main(String args[]) { 
     //comment out the code below to try in Metal L&F 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        ascendingSortIcon = UIManager.getLookAndFeelDefaults().getIcon("Table.ascendingSortIcon"); 
        descendingSortIcon = UIManager.getLookAndFeelDefaults().getIcon("Table.descendingSortIcon"); 
        //UIManager.getLookAndFeelDefaults().put("Table.ascendingSortIcon", new BevelArrowIcon(BevelArrowIcon.UP, false, false)); 
        //UIManager.getLookAndFeelDefaults().put("Table.descendingSortIcon", new BevelArrowIcon(BevelArrowIcon.DOWN, false, false)); 
        break; 
       } 
      } 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ImageChangeDemo().setVisible(true); 
      } 
     }); 
    } 

    public ImageChangeDemo() { 
     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     JScrollPane pane = new javax.swing.JScrollPane(); 
     //table.setAutoCreateRowSorter(true); 
     table.setModel(new javax.swing.table.DefaultTableModel(
       new Object[][]{ 
        {"a", "q", "h", "v"}, 
        {"b", "m", "l", "h"}, 
        {"d", "c", "a", "d"}, 
        {"j", "o", "y", "e"} 
       }, 
       new String[]{ 
        "Col 1", "Col 2", "Col 3", "Col 4" 
       }) { 

      private static final long serialVersionUID = 1L; 
      Class[] types = new Class[]{ 
       String.class, String.class, String.class, String.class 
      }; 

      @Override 
      public Class getColumnClass(int columnIndex) { 
       return types[columnIndex]; 
      } 
     }); 
     TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) { 

      @Override 
      public void toggleSortOrder(int column) { 
       if (column >= 0 && column < getModelWrapper().getColumnCount() && isSortable(column)) { 
        List<SortKey> keys = new ArrayList<SortKey>(getSortKeys()); 
        if (!keys.isEmpty()) { 

         SortKey sortKey = keys.get(0); 
         if (sortKey.getColumn() == column && sortKey.getSortOrder() == SortOrder.DESCENDING) { 
          setSortKeys(null); 
          return; 
         } 
        } 
       } 
       super.toggleSortOrder(column); 
      } 
     }; 
     table.setRowSorter(sorter); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     pane.setViewportView(table); 
     UIManager.getLookAndFeelDefaults().put("Table.ascendingSortIcon", new BevelArrowIcon(BevelArrowIcon.UP, false, false)); 
     UIManager.getLookAndFeelDefaults().put("Table.descendingSortIcon", new BevelArrowIcon(BevelArrowIcon.DOWN, false, false)); 
     SwingUtilities.updateComponentTreeUI(table); 
     add(pane, BorderLayout.NORTH); 
     JScrollPane pane1 = new javax.swing.JScrollPane(); 
     //table.setAutoCreateRowSorter(true); 
     table1.setModel(new javax.swing.table.DefaultTableModel(
       new Object[][]{ 
        {"a", "q", "h", "v"}, 
        {"b", "m", "l", "h"}, 
        {"d", "c", "a", "d"}, 
        {"j", "o", "y", "e"} 
       }, 
       new String[]{ 
        "Col 1", "Col 2", "Col 3", "Col 4" 
       }) { 

      private static final long serialVersionUID = 1L; 
      Class[] types = new Class[]{ 
       String.class, String.class, String.class, String.class 
      }; 

      @Override 
      public Class getColumnClass(int columnIndex) { 
       return types[columnIndex]; 
      } 
     }); 
     table1.setRowSorter(sorter); 
     table1.setPreferredScrollableViewportSize(table1.getPreferredSize()); 
     pane1.setViewportView(table1); 
     add(pane1, BorderLayout.SOUTH); 

     for (int i = 0; i < table1.getColumnCount(); i++) { 
      RowColorRenderer rowRenderer = new RowColorRenderer(i); 
      TableColumn column = table1.getColumnModel().getColumn(i); 
      column.setCellRenderer(rowRenderer); 
     } 
     pack(); 
    } 

    private class RowColorRenderer extends DefaultTableCellRenderer { 

     private static final long serialVersionUID = 1L; 
     private int colNo = 0; 

     RowColorRenderer(int col) { 
      colNo = col; 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, 
       boolean isSelected, boolean hasFocus, int row, int column) { 
      Component comp = super.getTableCellRendererComponent(table, value, 
        isSelected, hasFocus, row, column); 
      JComponent jc = (JComponent) comp; 
      if (!isSelected) { 
       if (table.getValueAt(row, colNo) != null) { 
        String str = table.getValueAt(row, colNo).toString(); 
        if (!str.isEmpty()) { 
         if (Pattern.compile("\\d").matcher(str).find()) { 
          if (((Pattern.compile("[02468]").matcher(str).find())) 
            && (!(Pattern.compile("[13579]").matcher(str).find()))) { 
           setForeground(Color.magenta); 
           setBackground(Color.orange); 
          } else if ((!(Pattern.compile("[02468]").matcher(str).find())) 
            && ((Pattern.compile("[13579]").matcher(str).find()))) { 
           setForeground(Color.blue); 
           setBackground(Color.yellow); 
          } else if (((Pattern.compile("[02468]").matcher(str).find())) 
            && ((Pattern.compile("[13579]").matcher(str).find()))) { 
           setForeground(Color.red); 
           setBackground(Color.cyan); 
          } 
          setFont(new Font("Serif", Font.BOLD, 12)); 
          setHorizontalAlignment(CENTER); 
         } else { 
          setBackground(table.getBackground()); 
          setForeground(table.getForeground()); 
          setFont(new Font("Serif", Font.PLAIN, 8)); 
          setHorizontalAlignment(CENTER); 
         } 
        } 
       } 
      } else { 
       if (hasFocus) { 
        setFont(new Font("Serif", Font.BOLD, 12)); 
        setForeground(Color.magenta); 
        setBackground(Color.orange); 
       } 
      } 
      return this; 
     } 
    } 

    static class BevelArrowIcon implements Icon { 

     public static final int UP = 0;   // direction 
     public static final int DOWN = 1; 
     private static final int DEFAULT_SIZE = 11; 
     private Color edge1; 
     private Color edge2; 
     private Color fill; 
     private int size; 
     private int direction; 

     public BevelArrowIcon(int direction, boolean isRaisedView, boolean isPressedView) { 
      if (isRaisedView) { 
       if (isPressedView) { 
        init(UIManager.getColor("controlLtHighlight"), UIManager.getColor("controlDkShadow"), UIManager.getColor("controlShadow"), DEFAULT_SIZE, direction); 
       } else { 
        init(UIManager.getColor("controlHighlight"), UIManager.getColor("controlShadow"), UIManager.getColor("control"), DEFAULT_SIZE, direction); 
       } 
      } else { 
       if (isPressedView) { 
        init(UIManager.getColor("controlDkShadow"), UIManager.getColor("controlLtHighlight"), UIManager.getColor("controlShadow"), DEFAULT_SIZE, direction); 
       } else { 
        init(UIManager.getColor("controlShadow"), UIManager.getColor("controlHighlight"), UIManager.getColor("control"), DEFAULT_SIZE, direction); 
       } 
      } 
     } 

     public BevelArrowIcon(Color edge1, Color edge2, Color fill, int size, int direction) { 
      init(edge1, edge2, fill, size, direction); 
     } 

     @Override 
     public void paintIcon(Component c, Graphics g, int x, int y) { 
      switch (direction) { 
       case DOWN: 
        drawDownArrow(g, x, y); 
        break; 
       case UP: 
        drawUpArrow(g, x, y); 
        break; 
      } 
     } 

     @Override 
     public int getIconWidth() { 
      return size; 
     } 

     @Override 
     public int getIconHeight() { 
      return size; 
     } 

     private void init(Color edge1, Color edge2, Color fill, int size, int direction) { 
      edge1 = Color.red; 
      edge2 = Color.blue; 
      this.edge1 = edge1; 
      this.edge2 = edge2; 
      this.fill = fill; 
      this.size = size; 
      this.direction = direction; 
     } 

     private void drawDownArrow(Graphics g, int xo, int yo) { 
      g.setColor(edge1); 
      g.drawLine(xo, yo, xo + size - 1, yo); 
      g.drawLine(xo, yo + 1, xo + size - 3, yo + 1); 
      g.setColor(edge2); 
      g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1); 
      int x = xo + 1; 
      int y = yo + 2; 
      int dx = size - 6; 
      while (y + 1 < yo + size) { 
       g.setColor(edge1); 
       g.drawLine(x, y, x + 1, y); 
       g.drawLine(x, y + 1, x + 1, y + 1); 
       if (0 < dx) { 
        g.setColor(fill); 
        g.drawLine(x + 2, y, x + 1 + dx, y); 
        g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1); 
       } 
       g.setColor(edge2); 
       g.drawLine(x + dx + 2, y, x + dx + 3, y); 
       g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1); 
       x += 1; 
       y += 2; 
       dx -= 2; 
      } 
      g.setColor(edge1); 
      g.drawLine(xo + (size/2), yo + size - 1, xo + (size/2), yo + size - 1); 
     } 

     private void drawUpArrow(Graphics g, int xo, int yo) { 
      g.setColor(edge1); 
      int x = xo + (size/2); 
      g.drawLine(x, yo, x, yo); 
      x--; 
      int y = yo + 1; 
      int dx = 0; 
      while (y + 3 < yo + size) { 
       g.setColor(edge1); 
       g.drawLine(x, y, x + 1, y); 
       g.drawLine(x, y + 1, x + 1, y + 1); 
       if (0 < dx) { 
        g.setColor(fill); 
        g.drawLine(x + 2, y, x + 1 + dx, y); 
        g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1); 
       } 
       g.setColor(edge2); 
       g.drawLine(x + dx + 2, y, x + dx + 3, y); 
       g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1); 
       x -= 1; 
       y += 2; 
       dx += 2; 
      } 
      g.setColor(edge1); 
      g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3); 
      g.setColor(edge2); 
      g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2); 
      g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1); 
     } 
    } 
} 
+0

¡Gracias! Esto es exactamente lo que estaba buscando y algo más. Incluso a través de un icono de clasificación personalizado simplemente por diversión :) (El Nimbus Default está bien, pero gracias de todos modos.) Buen ejemplo para ilustrar lo que es posible. – Thorn

+0

encantados de ayudarle, observe que todavía no estoy seguro, si necesita hacer las mismas cosas para TableCellEditor :-) – mKorbel

+0

Tendría que hacer las mismas cosas con TableCellEditor si quiero que el color del foco permanezca mientras edito . En este punto, entiendo completamente CÓMO hacer esto, lo que queda es la decisión de exactamente qué hacer. TableCellEditor explica por qué una vez que el usuario comienza a editar una celda enfocada, la apariencia cambia (del color de fila seleccionado a un fondo blanco). Eso es probablemente lo que quiero, no estoy seguro de que importe mucho. Esta pregunta no era realmente acerca de la apariencia, se trataba de hacer la tabla más intuitiva y utilizable, ya que algunos de mis usuarios son, digamos que no conocedores. – Thorn

1

Es necesario crear una clase de procesador de celdas personalizado que va a cambiar el color de primer plano por ejemplo, si está seleccionado.

Su clase se extender DefaultTableCellRenderer y reemplazar el método getTableCellRendererComponent (tabla JTable, del valor del objeto, boolean isSelected, hasFocus boolean, int fila, columna int).

p. Ej.

public class SpreadsheetCellRenderer extends DefaultTableCellRenderer { 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     /* the following is the similar to DefaultTableCellRenderer */ 
     if (isSelected) { 
      super.setForeground(Color.red); 
     } else { 
      super.setForeground(Color.black); 
     } 
    setText(value.toString()); 
    return this; 
    } 
} 

Luego hay que establecer que el procesador como el procesador predeterminado para los objetos dicen cadena en la tabla al hacer esto.

table.setDefaultRenderer(Class.forName("java.lang.String"), new SpreadsheetCellRenderer()); 
+0

Por cierto, obviamente estoy mostrando un mecanismo fuera de Nimbus, pero esta es una forma general de cambiar las propiedades de una JTable. – Eamonn

+0

Conozco TableCellRenderer y estaba buscando una manera más fácil, pero gracias por el claro ejemplo. Es más fácil crear un renderizador de células personalizado de lo que pensaba. Pero esperaba algo de aquí: http://jasperpotts.com/blogfiles/nimbusdefaults/nimbus.html – Thorn

+0

@Thorn Voy a recuperar mi respuesta aquí, no hay problema – mKorbel

Cuestiones relacionadas