package org.yamcs.ui.yamcsmonitor; import java.awt.*; import java.awt.event.MouseEvent; import java.text.NumberFormat; import java.util.Locale; import javax.swing.*; import javax.swing.border.Border; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import org.yamcs.protobuf.YamcsManagement.LinkInfo; import org.yamcs.ui.UiColors; public class LinkTable extends JTable { private static final long serialVersionUID = 1L; private LinkTableModel linkTableModel; private LinkCellRenderer linkInfoRenderer; private DataCountCellRenderer dataCountRenderer; public LinkTable(LinkTableModel linkTableModel) { super(linkTableModel); this.linkTableModel = linkTableModel; setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setAutoCreateRowSorter(true); linkInfoRenderer = new LinkCellRenderer(this); dataCountRenderer = new DataCountCellRenderer(this); } @Override public String getToolTipText(MouseEvent e) { int row = rowAtPoint(e.getPoint()); if (row == -1) return ""; row = convertRowIndexToModel(row); return linkTableModel.getLinkInfo(row).getDetailedStatus(); } @Override public TableCellRenderer getCellRenderer(int row, int column) { final int modelColumn = convertColumnIndexToModel(column); if (modelColumn == 5) { return dataCountRenderer; } else { return linkInfoRenderer; } } private static class LinkCellRenderer extends DefaultTableCellRenderer { private static final long serialVersionUID = 1L; final Border statusBorder; final Border statusBorderSelected; final Font statusFont; final LinkTable linkTable; LinkCellRenderer(LinkTable linkTable) { this.linkTable = linkTable; statusBorder = BorderFactory.createMatteBorder(1, 1, 1, 1, linkTable.getBackground()); statusBorderSelected = BorderFactory.createMatteBorder(1, 1, 1, 1, linkTable.getSelectionBackground()); statusFont = linkTable.getFont().deriveFont(getFont().getSize() * .8f); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, false /* Prevent blue focus border */, row, column); final int modelRow = linkTable.convertRowIndexToModel(row); final int modelColumn = linkTable.convertColumnIndexToModel(column); final LinkInfo info = linkTable.linkTableModel.getLinkInfo(modelRow); setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); if (info != null && modelColumn==4) { setHorizontalAlignment(SwingConstants.CENTER); setFont(statusFont); setBorder(isSelected ? statusBorderSelected : statusBorder); if(info.getDisabled()) { setBackground(UiColors.DISABLED_FAINT_BG); setForeground(UiColors.DISABLED_FAINT_FG); } else if ("OK".equals(info.getStatus())) { if (linkTable.linkTableModel.isDataCountIncreasing(modelRow)) { setBackground(UiColors.GOOD_BRIGHT_BG); setForeground(UiColors.GOOD_BRIGHT_FG); } else { setBackground(UiColors.GOOD_FAINT_BG); setForeground(UiColors.GOOD_FAINT_FG); } } else { setBackground(UiColors.ERROR_FAINT_BG); setForeground(UiColors.ERROR_FAINT_FG); } } else if(modelColumn == 5) { // Data count setHorizontalAlignment(SwingConstants.RIGHT); } else { setHorizontalAlignment(SwingConstants.LEFT); } return this; } } /** * Adds some extra capabilities for the data count column to render big numbers in groups of three */ private static final class DataCountCellRenderer extends LinkCellRenderer { private static final long serialVersionUID = 1L; private final NumberFormat formatter = NumberFormat.getInstance(Locale.US); DataCountCellRenderer(LinkTable linkTable) { super(linkTable); } @Override protected void setValue(Object value) { Object result = value; if (value != null) { Number numberValue = (Number) value; result = formatter.format(numberValue.doubleValue()); } super.setValue(result); } } }