2012-07-01 33 views
5

Khi chỉnh sửa dữ liệu trong JTable (Nimbus L & F), khi người dùng tab từ ô này sang ô khác, không rõ ô nào có tiêu điểm. Làm thế nào tôi có thể làm cho nó rõ ràng hơn mà tế bào đã tập trung? Tôi biết có một số thuộc tính có thể được thiết lập để sửa đổi Nimbus - có ai biết thuộc tính nào tôi muốn không?Nhìn và cảm nhận của JTable Nimbus - làm thế nào để rõ ràng ô nào có tiêu điểm

Màn hình bắn bên dưới chỉ có một tài sản thiết lập để một cái gì đó khác hơn so với mặc định:

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

JTable screen shot

Trả lời

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

Cảm ơn bạn! Đây là chính xác những gì tôi đang tìm kiếm và sau đó một số. Bạn thậm chí thông qua trong một biểu tượng sắp xếp tùy chỉnh chỉ để cho vui :) (The Nimbus Mặc định là tốt, nhưng nhờ anyway.) Ví dụ tốt đẹp để minh họa những gì có thể. – Thorn

+0

vui lòng giúp bạn, hãy chú ý rằng tôi vẫn không chắc chắn, nếu bạn cần phải làm những việc tương tự cho TableCellEditor :-) – mKorbel

+0

Tôi cần phải làm những việc tương tự với TableCellEditor nếu tôi muốn màu tiêu điểm vẫn còn trong khi chỉnh sửa . Tại thời điểm này, tôi hoàn toàn hiểu làm thế nào để làm điều này, những gì còn lại là quyết định chính xác những gì làm. TableCellEditor giải thích lý do tại sao sau khi người dùng bắt đầu chỉnh sửa ô tập trung, giao diện thay đổi (từ màu hàng đã chọn thành nền trắng). Đó có lẽ là điều tôi muốn - tôi không chắc nó quan trọng lắm. Câu hỏi này không thực sự về sự xuất hiện, đó là làm cho bảng trực quan hơn và có thể sử dụng được vì một số người dùng của tôi, chúng ta hãy nói không hiểu biết. – Thorn

1

Bạn cần phải tạo ra một lớp tế bào tùy chỉnh renderer đó sẽ thay đổi màu sắc foreground ví dụ nếu được chọn.

lớp của bạn sẽ mở rộng DefaultTableCellRendererghi đè lên các phương pháp getTableCellRendererComponent (bảng JTable, giá trị Object, boolean isSelected, hasFocus boolean, int hàng, int cột).

ví dụ:

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; 
    } 
} 

Sau đó, bạn cần đặt trình kết xuất đó làm trình kết xuất đồ họa mặc định để nói các đối tượng String trong bảng bằng cách thực hiện việc này.

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

Nhân tiện, tôi rõ ràng đang hiển thị một cơ chế bên ngoài Nimbus, nhưng đây là một cách tổng quát để thay đổi các thuộc tính của một JTable. – Eamonn

+0

Tôi biết về TableCellRenderer và đang tìm kiếm một cách dễ dàng hơn, nhưng cảm ơn bạn vì ví dụ rõ ràng. Tạo một trình kết xuất ô tùy chỉnh dễ dàng hơn tôi nghĩ. Nhưng tôi đã hy vọng cho một cái gì đó từ đây: http://jasperpotts.com/blogfiles/nimbusdefaults/nimbus.html – Thorn

+0

@ Thorn tôi sẽ hủy xóa câu trả lời của tôi ở đây, không có vấn đề – mKorbel