/* * Copyright (C) 2011 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * 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, see http://www.gnu.org/licenses/ */ package org.esa.snap.rcp.statistics; import org.esa.snap.core.dataio.ProductReader; import org.esa.snap.core.dataio.ProductReaderPlugIn; import org.esa.snap.core.datamodel.AbstractBand; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.datamodel.ProductData; import org.esa.snap.core.datamodel.TiePointGrid; import org.esa.snap.core.util.ModuleMetadata; import org.esa.snap.core.util.StringUtils; import org.esa.snap.core.util.SystemUtils; import org.openide.windows.TopComponent; import javax.swing.JScrollPane; import javax.swing.JTable; import java.awt.Dimension; import java.util.List; /** * @author Thomas Storm */ class InformationPanel extends TablePagePanel { private static final String DEFAULT_INFORMATION_TEXT = "No information available."; private static final String TITLE_PREFIX = "Information"; private static final String NO_PRODUCT_READER_MESSAGE = "No product reader set"; private static final int index_of_name_column = 0; private static final int index_of_value_and_unit_column = 1; private InformationTableModel tableModel; private int widthOfNameColumn = -1; private int widthOfValueAndUnitColumn = -1; InformationPanel(TopComponent parentComponent, String helpId) { super(parentComponent, helpId, TITLE_PREFIX, DEFAULT_INFORMATION_TEXT); } @Override protected void initComponents() { tableModel = new InformationTableModel(); getTable().setModel(tableModel); getTable().setTableHeader(null); getTable().addMouseListener(new PopupHandler()); getTable().setShowGrid(false); getTable().setRowSelectionAllowed(false); getTable().setColumnSelectionAllowed(false); getTable().setAutoResizeMode(JTable.AUTO_RESIZE_OFF); add(new JScrollPane(getTable())); } @Override protected String getDataAsText() { StringBuilder builder = new StringBuilder(); final List<TableRow> rows = tableModel.rows; for (int i = 0; i < rows.size(); i++) { InformationTableRow row = (InformationTableRow) rows.get(i); builder.append(row.label) .append("\t") .append(row.value) .append(StringUtils.isNotNullAndNotEmpty(row.unit) ? "\t" + row.unit : ""); if (i < rows.size() - 1) { builder.append("\n"); } } return builder.toString(); } @Override protected void updateComponents() { tableModel.clear(); widthOfNameColumn = -1; widthOfValueAndUnitColumn = -1; if (getRaster() instanceof AbstractBand) { final Band band = (Band) getRaster(); addEntry("Name:", band.getName(), ""); addEntry("Type:", "Band", ""); addEntry("Description:", band.getDescription(), ""); addEntry("Geophysical unit:", band.getUnit(), ""); addEntry("Geophysical data type:", ProductData.getTypeString(band.getGeophysicalDataType()), ""); addEntry("Raw data type:", ProductData.getTypeString(band.getDataType()), ""); addEntry("Raster width:", String.valueOf(band.getRasterWidth()), "pixels"); addEntry("Raster height:", String.valueOf(band.getRasterHeight()), "pixels"); addEntry("Scaling factor:", String.valueOf(band.getScalingFactor()), ""); addEntry("Scaling offset:", String.valueOf(band.getScalingOffset()), ""); addEntry("Is log 10 scaled:", String.valueOf(band.isLog10Scaled()), ""); addEntry("Is no-data value used:", String.valueOf(band.isNoDataValueUsed()), ""); addEntry("No-data value:", String.valueOf(band.getNoDataValue()), ""); addEntry("Geophysical no-data value:", String.valueOf(band.getGeophysicalNoDataValue()), ""); addEntry("Valid pixel expression:", String.valueOf(band.getValidPixelExpression()), ""); addEntry("Spectral band index:", String.valueOf(band.getSpectralBandIndex() + 1), ""); addEntry("Wavelength:", String.valueOf(band.getSpectralWavelength()), "nm"); addEntry("Bandwidth:", String.valueOf(band.getSpectralBandwidth()), "nm"); addEntry("Solar flux:", String.valueOf(band.getSolarFlux()), "mW/(m^2*nm)"); } else if (getRaster() instanceof TiePointGrid) { final TiePointGrid grid = (TiePointGrid) getRaster(); addEntry("Name:", grid.getName(), ""); addEntry("Type:", "Tie Point Grid", ""); addEntry("Description:", grid.getDescription(), ""); addEntry("Geophysical unit:", grid.getUnit(), ""); addEntry("Geophysical data type:", ProductData.getTypeString(grid.getGeophysicalDataType()), ""); addEntry("Grid width:", String.valueOf(grid.getGridWidth()), "tie points"); addEntry("Grid height:", String.valueOf(grid.getGridHeight()), "tie points"); addEntry("Offset X:", String.valueOf(grid.getOffsetX()), "pixels"); addEntry("Offset Y:", String.valueOf(grid.getOffsetY()), "pixels"); addEntry("Sub-sampling X:", String.valueOf(grid.getSubSamplingX()), "pixels"); addEntry("Sub-sampling Y:", String.valueOf(grid.getSubSamplingY()), "pixels"); addEntry("Raster width:", String.valueOf(grid.getRasterWidth()), "pixels"); addEntry("Raster height:", String.valueOf(grid.getRasterHeight()), "pixels"); } final Product product = getProduct(); if (product == null) { showNoInformationAvailableMessage(); return; } if (tableModel.getRowCount() > 0) { addEntry("", "", ""); } addEntry("Product name:", product.getName(), ""); addEntry("Product type:", product.getProductType(), ""); addEntry("Product description:", product.getDescription(), ""); final String productFormatName = getProductFormatName(product); final String productFormatNameString = productFormatName != null ? productFormatName : "unknown"; addEntry("Product format:", productFormatNameString, ""); addEntry("Product reader:", getProductReaderDescription(product), ""); addEntry("Product reader class:", getProductReaderClass(product), ""); addEntry("Product reader module:", getProductReaderModule(product), ""); addEntry("Product file location:", product.getFileLocation() != null ? product.getFileLocation().getPath() : "Not yet saved", ""); addEntry("Product scene width:", String.valueOf(product.getSceneRasterWidth()), "pixels"); addEntry("Product scene height:", String.valueOf(product.getSceneRasterHeight()), "pixels"); Dimension preferredTileSize = product.getPreferredTileSize(); if (preferredTileSize != null) { addEntry("Product preferred tile width:", String.valueOf((int)preferredTileSize.getWidth()), "pixels"); addEntry("Product preferred tile height:", String.valueOf((int)preferredTileSize.getHeight()), "pixels"); } final String startTimeString = product.getStartTime() != null ? product.getStartTime().getElemString() : "Not available"; addEntry("Product start time (UTC):", startTimeString, ""); final String stopTimeString = product.getEndTime() != null ? product.getEndTime().getElemString() : "Not available"; addEntry("Product end time (UTC):", stopTimeString, ""); ensureTableModel(); } private void ensureTableModel() { if (getTable().getModel() != tableModel) { getTable().setModel(tableModel); getTable().setAutoResizeMode(JTable.AUTO_RESIZE_OFF); } getTable().getColumnModel().getColumn(index_of_name_column).setPreferredWidth(widthOfNameColumn); getTable().getColumnModel().getColumn(index_of_name_column).setMinWidth(widthOfNameColumn); getTable().getColumnModel().getColumn(index_of_name_column).setMaxWidth(widthOfNameColumn); getTable().getColumnModel().getColumn(index_of_value_and_unit_column).setPreferredWidth(widthOfValueAndUnitColumn); getTable().getColumnModel().getColumn(index_of_value_and_unit_column).setMinWidth(widthOfValueAndUnitColumn); getTable().getColumnModel().getColumn(index_of_value_and_unit_column).setMaxWidth(widthOfValueAndUnitColumn); setColumnRenderer(0, RendererFactory.createRenderer(RendererFactory.ALTERNATING_ROWS)); setColumnRenderer(1, RendererFactory.createRenderer(RendererFactory.ALTERNATING_ROWS | RendererFactory.TOOLTIP_AWARE)); } private void addEntry(final String label, final String value, final String unit) { String formattedLabel = String.format("%1$-30s \t", label); widthOfNameColumn = Math.max(widthOfNameColumn, getFontMetrics(getFont()).stringWidth(formattedLabel) + 10); widthOfValueAndUnitColumn = Math.max(widthOfValueAndUnitColumn, getFontMetrics(getFont()).stringWidth( value + (StringUtils.isNotNullAndNotEmpty(unit) ? " " + unit : "")) + 10); TableRow row = new InformationTableRow(formattedLabel, value, unit); tableModel.addRow(row); } private static String getProductReaderDescription(final Product product) { final ProductReader productReader = product.getProductReader(); if (productReader != null) { final ProductReaderPlugIn readerPlugIn = productReader.getReaderPlugIn(); if (readerPlugIn != null) { String description = readerPlugIn.getDescription(null); if (description != null) { return description; } } } return NO_PRODUCT_READER_MESSAGE; } private static String getProductReaderClass(final Product product) { final ProductReader productReader = product.getProductReader(); if (productReader != null) { final ProductReaderPlugIn readerPlugIn = productReader.getReaderPlugIn(); if (readerPlugIn != null) { return readerPlugIn.getClass().getName(); } } return NO_PRODUCT_READER_MESSAGE; } private static String getProductReaderModule(final Product product) { final ProductReader productReader = product.getProductReader(); if (productReader != null) { ModuleMetadata moduleMetadata = SystemUtils.loadModuleMetadata(productReader.getClass()); if(moduleMetadata != null) { return String.format("%s - v%s", moduleMetadata.getDisplayName(), moduleMetadata.getVersion()); } return "unknown"; } return NO_PRODUCT_READER_MESSAGE; } private static String getProductFormatName(final Product product) { final ProductReader productReader = product.getProductReader(); if (productReader == null) { return null; } final ProductReaderPlugIn readerPlugIn = productReader.getReaderPlugIn(); if (readerPlugIn != null) { return getProductFormatName(readerPlugIn); } return null; } // todo - make this a method in ProductReader and ProductWriter private static String getProductFormatName(final ProductReaderPlugIn readerPlugIn) { final String[] formatNames = readerPlugIn.getFormatNames(); if (formatNames != null && formatNames.length > 0) { return formatNames[0]; } return null; } static class InformationTableRow implements TablePagePanel.TableRow { String label; String value; String unit; public InformationTableRow(String label, String value, String unit) { this.label = label; this.value = value; this.unit = unit; } } private static class InformationTableModel extends TablePagePanelModel { @Override public int getColumnCount() { return 2; } @Override public String getColumnName(int columnIndex) { switch (columnIndex) { case index_of_name_column: return "Name"; case index_of_value_and_unit_column: return "Value and Unit"; } throw new IllegalStateException("Should never come here"); } @Override public Object getValueAt(int rowIndex, int columnIndex) { TableRow row = rows.get(rowIndex); if (!(row instanceof InformationTableRow)) { return row.toString(); } InformationTableRow tableRow = (InformationTableRow) row; switch (columnIndex) { case index_of_name_column: return tableRow.label; case index_of_value_and_unit_column: return tableRow.value + (StringUtils.isNotNullAndNotEmpty(tableRow.unit) ? " " + tableRow.unit : ""); } throw new IllegalStateException("Invalid index: row=" + rowIndex + "; column=" + columnIndex); } } }