/* * This file is part of the Illarion project. * * Copyright © 2014 - Illarion e.V. * * Illarion is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Illarion 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. */ package illarion.easynpc.gui; import illarion.easynpc.Lang; import illarion.easynpc.ParsedNpc; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.swing.*; import javax.swing.table.AbstractTableModel; import java.awt.*; import java.awt.color.ColorSpace; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.*; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.ListIterator; /** * This error pane is showing all needed components to display the errors * occurred in the script. * * @author Martin Karing <nitram@illarion.org> */ final class ErrorPane extends JPanel { public static final class ErrorPaneTableModel extends AbstractTableModel { /** * */ private static final long serialVersionUID = 1L; private final List<Editor> errorEditors = new ArrayList<>(); ErrorPaneTableModel() { // nothing } public void addEditor(Editor editor) { if (errorEditors.contains(editor)) { return; } errorEditors.add(editor); } public void focusError(int rowIndex) { int editorCount = errorEditors.size(); int errorCount = 0; for (int i = 0; i < editorCount; i++) { ParsedNpc problemNpc = errorEditors.get(i).getErrorNpc(); if (problemNpc == null) { errorEditors.remove(i); editorCount--; i--; } else { int localErrors = problemNpc.getErrorCount(); if ((errorCount + localErrors) >= (rowIndex + 1)) { ParsedNpc.Error error = problemNpc.getError(rowIndex - errorCount); errorEditors.get(i).getLineToFocus(error.getLine()); } errorCount += localErrors; } } } @Override public int getColumnCount() { return 3; } /** * Get the name of the columns. */ @Nullable @Override public String getColumnName(int column) { switch (column) { case 0: return Lang.getMsg(getClass(), "description"); case 1: return Lang.getMsg(getClass(), "file"); case 2: return Lang.getMsg(getClass(), "location"); } return null; } @Override public int getRowCount() { int editorCount = errorEditors.size(); int errorCount = 0; for (int i = 0; i < editorCount; i++) { ParsedNpc problemNpc = errorEditors.get(i).getErrorNpc(); if (problemNpc == null) { errorEditors.remove(i); editorCount--; i--; } else { errorCount += problemNpc.getErrorCount(); } } return errorCount; } @Nullable @Override public Object getValueAt(int rowIndex, int columnIndex) { int errorCount = 0; ListIterator<Editor> editorItr = errorEditors.listIterator(); while (editorItr.hasNext()) { Editor editor = editorItr.next(); ParsedNpc problemNpc = editor.getErrorNpc(); if (problemNpc == null) { editorItr.remove(); } else { int localErrors = problemNpc.getErrorCount(); if ((errorCount + localErrors) >= (rowIndex + 1)) { if (columnIndex == 1) { return editor.getFileName(); } ParsedNpc.Error error = problemNpc.getError(rowIndex - errorCount); if (columnIndex == 0) { return error.getMessage(); } if (columnIndex == 2) { return "line " + Integer.toString(error.getLine()); } } errorCount += localErrors; } } return null; } @Override public boolean isCellEditable(int rowIndex, int vColIndex) { return false; } public void removeEditor(Editor editor) { errorEditors.remove(editor); } } /** * The serialization UID of this script. */ private static final long serialVersionUID = 1L; @Nonnull private final JTable errorList; private final String errorMessage = Lang.getMsg(ErrorPane.class, "errors"); @Nonnull private final JLabel summery; @Nonnull private final ErrorPaneTableModel tableModel; public ErrorPane() { super(new BorderLayout(5, 0)); summery = new JLabel(String.format(errorMessage, Integer.toString(20))); tableModel = new ErrorPaneTableModel(); errorList = new JTable(tableModel); errorList.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent e) { tableModel.focusError(errorList.getSelectedRow()); } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } }); JScrollPane errorListScroll = new JScrollPane(errorList); Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon"); ComponentColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8, 8}, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); WritableRaster raster = Raster .createInterleavedRaster(DataBuffer.TYPE_BYTE, errorIcon.getIconWidth(), errorIcon.getIconHeight(), 4, null); BufferedImage image = new BufferedImage(colorModel, raster, false, new Hashtable<>()); errorIcon.paintIcon(null, image.getGraphics(), 0, 0); new ImageIcon(image.getScaledInstance(14, 14, Image.SCALE_SMOOTH)); add(summery, BorderLayout.NORTH); add(errorListScroll, BorderLayout.CENTER); getPreferredSize(); setMinimumSize(new Dimension(100, 150)); setPreferredSize(new Dimension(300, 300)); setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); updateErrors(); } public void addErrorEditor(Editor editor) { tableModel.addEditor(editor); updateErrors(); } public void removeErrorEditor(Editor editor) { tableModel.removeEditor(editor); updateErrors(); } void updateErrors() { tableModel.fireTableDataChanged(); summery.setText(String.format(errorMessage, errorList.getRowCount())); } }