package org.yamcs.ui.eventviewer; import java.awt.Component; import java.awt.Dimension; import java.util.prefs.Preferences; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JTable; import javax.swing.event.ChangeEvent; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import org.yamcs.protobuf.Yamcs.Event; import org.yamcs.protobuf.Yamcs.Event.EventSeverity; import org.yamcs.ui.PrefsObject; import org.yamcs.ui.UiColors; public class EventTable extends JTable { private static final long serialVersionUID = 1L; private static final ImageIcon INFO_ICON = new ImageIcon(EventTable.class.getResource("/org/yamcs/images/blank.png")); private static final ImageIcon WARNING_ICON = new ImageIcon(EventTable.class.getResource("/org/yamcs/images/warn.png")); private static final ImageIcon ERROR_ICON = new ImageIcon(EventTable.class.getResource("/org/yamcs/images/error.png")); private final EventTableRenderer renderer = new EventTableRenderer(); private boolean inLayout; private Preferences uiPrefs; public EventTable(EventTableModel model) { super(model); setShowHorizontalLines(true); setIntercellSpacing(new Dimension(0, 0)); uiPrefs = Preferences.userNodeForPackage(EventTable.class); Object columnOrder = PrefsObject.getObject(uiPrefs, "ColumnOrder"); if (columnOrder != null) { setColumnOrder((int[]) columnOrder); } } @Override public boolean isCellEditable(int row, int column) { return false; } @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { Component c = super.prepareRenderer(renderer, row, column); if (!isRowSelected(row)) { c.setBackground(getBackground()); int modelRow = convertRowIndexToModel(row); Event event = (Event)getModel().getValueAt(modelRow, EventTableModel.EVENT_TEXT_COL); if(event.getSeverity()==EventSeverity.WARNING) { c.setBackground(UiColors.WARNING_FAINT_BG); //setSelectedTextColor(COLOR_WARNING_BG); //setDisabledTextColor(COLOR_WARNING_BG); } else if(event.getSeverity()==EventSeverity.ERROR) { c.setBackground(UiColors.ERROR_FAINT_BG); } } ((JComponent) c).setBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, UiColors.BORDER_COLOR)); return c; } @Override public TableCellRenderer getCellRenderer(int row, int column) { if (convertColumnIndexToModel(column) == EventTableModel.EVENT_TEXT_COL) { return renderer; } else if (convertColumnIndexToModel(column) == EventTableModel.SOURCE_COL) { return new DefaultTableCellRenderer() { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, false /* no focus ! */, row, column); int modelRow = convertRowIndexToModel(row); Event event = (Event)getModel().getValueAt(modelRow, EventTableModel.EVENT_TEXT_COL); if(event.getSeverity()==EventSeverity.WARNING) { setIcon(WARNING_ICON); } else if(event.getSeverity()==EventSeverity.ERROR) { setIcon(ERROR_ICON); } else if(event.getSeverity()==EventSeverity.INFO) { setIcon(INFO_ICON); } return this; } }; } else { // Disable blue focus border return new DefaultTableCellRenderer() { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return super.getTableCellRendererComponent(table, value, isSelected, false /* no focus ! */, row, column); } }; } } private void setColumnOrder(int[] indices) { // Remember all columns TableColumn[] columns = new TableColumn[columnModel.getColumnCount()]; for (int i = 0; i < columnModel.getColumnCount(); i++) { columns[i] = columnModel.getColumn(i); } // Remove all while (columnModel.getColumnCount() > 0) { columnModel.removeColumn(columnModel.getColumn(0)); } // Re-add, give preference to columns in indices[] for (int i = 0; i < indices.length; i++) { if (indices[i] < columns.length) { columnModel.addColumn(columns[indices[i]]); columns[indices[i]] = null; } } for (TableColumn column : columns) { if (column != null) { columnModel.addColumn(column); } } } /* * Next few methods make sure that event-viewer columns can always * be resized, and that a horizontal scrollbar will appear if needed. * See http://stackoverflow.com/questions/15499255 */ @Override public boolean getScrollableTracksViewportWidth() { return hasExcessWidth(); } @Override public void doLayout() { if (hasExcessWidth()) { // fool super autoResizeMode = AUTO_RESIZE_ALL_COLUMNS; } inLayout = true; super.doLayout(); inLayout = false; autoResizeMode = AUTO_RESIZE_OFF; } protected boolean hasExcessWidth() { return getPreferredSize().width < getParent().getWidth(); } @Override public void columnMarginChanged(ChangeEvent e) { if (isEditing()) { // JW: darn - cleanup to terminate editing ... removeEditor(); } TableColumn resizingColumn = getTableHeader().getResizingColumn(); // Need to do this here, before the parent's // layout manager calls getPreferredSize(). if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF && !inLayout) { resizingColumn.setPreferredWidth(resizingColumn.getWidth()); } resizeAndRepaint(); } public void storePreferences() { // Store column order int[] columnOrder=new int[columnModel.getColumnCount()]; for(int i=0; i<columnModel.getColumnCount(); i++) { columnOrder[i] = columnModel.getColumn(i).getModelIndex(); } PrefsObject.putObject(uiPrefs, "ColumnOrder", columnOrder); } }