/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* Part of the Processing project - http://processing.org Copyright (c) 2012-15 The Processing Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package processing.app.ui; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.ToolTipManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import processing.app.Language; import processing.app.Mode; import processing.app.Problem; import processing.app.ui.Editor; public class ErrorTable extends JTable { Editor editor; static final String[] columnNames = { "", // the blank column used for spacing Language.text("editor.footer.errors.problem"), Language.text("editor.footer.errors.tab"), Language.text("editor.footer.errors.line") }; static final int DATA_COLUMN = 0; static final int PROBLEM_COLUMN = 1; static final int TAB_COLUMN = 2; static final int LINE_COLUMN = 3; Font headerFont; Color headerColor; Color headerBgColor; // Font rowFont; // Color rowColor; // Color rowBgColor; public ErrorTable(final Editor editor) { super(new DefaultTableModel(columnNames, 0)); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); this.editor = editor; JTableHeader header = getTableHeader(); Mode mode = editor.getMode(); header.setDefaultRenderer(new GradyHeaderRenderer(mode)); setDefaultRenderer(Object.class, new GradyRowRenderer(mode)); //setShowGrid(false); setIntercellSpacing(new Dimension(0, 0)); // be specific about the width of the first column TableColumn emptyColumn = columnModel.getColumn(0); emptyColumn.setMaxWidth(Editor.LEFT_GUTTER); emptyColumn.setMinWidth(Editor.LEFT_GUTTER); columnModel.getColumn(PROBLEM_COLUMN).setPreferredWidth(400); columnModel.getColumn(TAB_COLUMN).setPreferredWidth(100); columnModel.getColumn(LINE_COLUMN).setPreferredWidth(50); // // the other columns are just a preference // for (int i = 1; i < columnModel.getColumnCount(); i++) { // columnModel.getColumn(i).setPreferredWidth(columnWidths[i]); // } addMouseListener(new MouseAdapter() { @Override synchronized public void mouseClicked(MouseEvent e) { try { int row = ((ErrorTable) e.getSource()).getSelectedRow(); if (row >= 0 && row < getRowCount()) { Object data = getModel().getValueAt(row, DATA_COLUMN); int clickCount = e.getClickCount(); if (clickCount == 1) { editor.errorTableClick(data); } else if (clickCount > 1) { editor.errorTableDoubleClick(data); } editor.getTextArea().requestFocusInWindow(); // editor.getErrorChecker().scrollToErrorLine(row); } } catch (Exception ex) { ex.printStackTrace(); } } }); header.setReorderingAllowed(false); setFillsViewportHeight(true); ToolTipManager.sharedInstance().registerComponent(this); } public void clearRows() { DefaultTableModel dtm = (DefaultTableModel) getModel(); dtm.setRowCount(0); } public void addRow(Problem data, String msg, String filename, String line) { DefaultTableModel dtm = (DefaultTableModel) getModel(); dtm.addRow(new Object[] { data, msg, filename, line }); } @Override public boolean isCellEditable(int rowIndex, int colIndex) { return false; // Disallow the editing of any cell } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . static class GradyHeaderRenderer extends JLabel implements TableCellRenderer { public GradyHeaderRenderer(Mode mode) { setFont(mode.getFont("errors.header.font")); setAlignmentX(LEFT_ALIGNMENT); setForeground(mode.getColor("errors.header.fgcolor")); setBackground(mode.getColor("errors.header.bgcolor")); setOpaque(true); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { // Adjust height for magnified displays. The font is scaled properly, // but the rows don't automatically use the scaled preferred size. // https://github.com/processing/processing/issues/4936 int high = getPreferredSize().height; if (high != 0) { JTableHeader header = table.getTableHeader(); int current = header.getSize().height; if (current != high) { table.setPreferredSize(new Dimension(table.getWidth(), high)); } } setText(value == null ? "" : value.toString()); return this; } } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . static class GradyRowRenderer extends JLabel implements TableCellRenderer { Color textColor; Color bgColor; Color textColorSelected; Color bgColorSelected; Color bgColorError; Color bgColorWarning; Color errorIndicatorColor; Color warningIndicatorColor; public GradyRowRenderer(Mode mode) { setFont(mode.getFont("errors.row.font")); setAlignmentX(LEFT_ALIGNMENT); textColor = mode.getColor("errors.row.fgcolor"); bgColor = mode.getColor("errors.row.bgcolor"); textColorSelected = mode.getColor("errors.selection.fgcolor"); bgColorSelected = mode.getColor("errors.selection.bgcolor"); bgColorError = mode.getColor("errors.selection.error.bgcolor"); bgColorWarning = mode.getColor("errors.selection.warning.bgcolor"); errorIndicatorColor = mode.getColor("errors.indicator.error.color"); warningIndicatorColor = mode.getColor("errors.indicator.warning.color"); setOpaque(true); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { Problem entry = (Problem) table.getValueAt(row, DATA_COLUMN); // Adjust row height for magnified displays. The font is scaled properly, // but the rows don't automatically use the scaled preferred size. // https://github.com/processing/processing/issues/4936 int high = getPreferredSize().height; if (high != 0) { int current = table.getRowHeight(); if (current != high) { table.setRowHeight(high); } } if (selected) { setForeground(textColorSelected); if (entry.isError()) { setBackground(bgColorError); } else if (entry.isWarning()) { setBackground(bgColorWarning); } else { setBackground(bgColorSelected); } } else { setForeground(textColor); setBackground(bgColor); } if (column == DATA_COLUMN) { setText("\u2022"); setHorizontalAlignment(SwingConstants.CENTER); if (entry.isError()) { setForeground(errorIndicatorColor); } else if (entry.isWarning()) { setForeground(warningIndicatorColor); } else { setText(""); // no dot } } else if (value == null) { setText(""); } else { setHorizontalAlignment(SwingConstants.LEFT); setText(value.toString()); } return this; } } }