JTable Nimbus外观 – 如何清楚哪个单元格具有焦点

当在JTable(Nimbus L&F)中编辑数据时,当用户从一个单元格切换到另一个单元格时,不清楚哪个单元格具有焦点。 如何更清楚地说明哪个细胞有焦点? 我知道有很多属性可以设置来修改Nimbus – 有谁知道我想要哪个属性?

下面的屏幕截图只有一个属性设置为默认值以外的其他属性:

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

JTable屏幕截图

  • 你看看Renderer的概念 ,

  • 通过defimul为Nimbus Look and Feel工作 ,

  • 一些问题可能与JButtons组件(JCheckBox ei)有关 ,但在此论坛上有几次得到解答或解决

在此处输入图像描述

 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 sorter = new TableRowSorter(table.getModel()) { @Override public void toggleSortOrder(int column) { if (column >= 0 && column < getModelWrapper().getColumnCount() && isSortable(column)) { List keys = new ArrayList(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); } } } 

您需要创建一个自定义单元格渲染器类,它将更改前景色(例如,如果选中)。

您的类将扩展DefaultTableCellRenderer覆盖方法getTableCellRendererComponent(JTable表,Object值,boolean isSelected,boolean hasFocus,int row,int column)

例如

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

然后,您需要将该渲染器设置为默认渲染器,通过执行此操作来说明表中的String对象。

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