/* * Copyright (C) 2010 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.colormanip; import com.bc.ceres.core.Assert; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.ColorPaletteDef; import org.esa.snap.core.datamodel.ImageInfo; import org.esa.snap.core.datamodel.IndexCoding; import org.esa.snap.core.datamodel.ProductNodeEvent; import org.esa.snap.core.datamodel.RasterDataNode; import org.esa.snap.core.datamodel.Stx; import org.esa.snap.ui.color.ColorTableCellEditor; import org.esa.snap.ui.color.ColorTableCellRenderer; import javax.swing.AbstractButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableRowSorter; import java.awt.Color; import java.awt.Component; import java.text.NumberFormat; class Discrete1BandTabularForm implements ColorManipulationChildForm { private static final String[] COLUMN_NAMES = new String[]{"Label", "Colour", "Value", "Frequency", "Description"}; private static final Class<?>[] COLUMN_TYPES = new Class<?>[]{String.class, Color.class, String.class, Double.class, String.class}; private final ColorManipulationForm parentForm; private JComponent contentPanel; private ImageInfoTableModel tableModel; private MoreOptionsForm moreOptionsForm; public Discrete1BandTabularForm(ColorManipulationForm parentForm) { this.parentForm = parentForm; tableModel = new ImageInfoTableModel(); moreOptionsForm = new MoreOptionsForm(this, false); final JTable table = new JTable(tableModel); table.setRowSorter(new TableRowSorter<>(tableModel)); table.setDefaultRenderer(Color.class, new ColorTableCellRenderer()); table.setDefaultEditor(Color.class, new ColorTableCellEditor()); table.getTableHeader().setReorderingAllowed(false); table.getColumnModel().getColumn(1).setPreferredWidth(140); table.getColumnModel().getColumn(3).setCellRenderer(new PercentageRenderer()); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); final JScrollPane tableScrollPane = new JScrollPane(table); tableScrollPane.getViewport().setPreferredSize(table.getPreferredSize()); contentPanel = tableScrollPane; } @Override public ColorManipulationForm getParentForm() { return parentForm; } @Override public void handleFormShown(FormModel formModel) { updateFormModel(formModel); } @Override public void handleFormHidden(FormModel formModel) { } @Override public void updateFormModel(FormModel formModel) { parentForm.getStx(formModel.getRaster()); tableModel.fireTableDataChanged(); } @Override public void resetFormModel(FormModel formModel) { updateFormModel(formModel); } @Override public void handleRasterPropertyChange(ProductNodeEvent event, RasterDataNode raster) { } @Override public AbstractButton[] getToolButtons() { return new AbstractButton[0]; } @Override public Component getContentPanel() { return contentPanel; } @Override public RasterDataNode[] getRasters() { return parentForm.getFormModel().getRasters(); } @Override public MoreOptionsForm getMoreOptionsForm() { return moreOptionsForm; } private static class PercentageRenderer extends DefaultTableCellRenderer { private final NumberFormat formatter; public PercentageRenderer() { setHorizontalAlignment(JLabel.RIGHT); formatter = NumberFormat.getPercentInstance(); formatter.setMinimumFractionDigits(3); formatter.setMaximumFractionDigits(3); } @Override public void setValue(Object value) { setText(formatter.format(value)); } } private class ImageInfoTableModel extends AbstractTableModel { private ImageInfoTableModel() { } public ImageInfo getImageInfo() { return parentForm.getFormModel().getModifiedImageInfo(); } @Override public String getColumnName(int columnIndex) { return COLUMN_NAMES[columnIndex]; } @Override public Class<?> getColumnClass(int columnIndex) { return COLUMN_TYPES[columnIndex]; } public int getColumnCount() { return COLUMN_NAMES.length; } public int getRowCount() { if (getImageInfo() == null) { return 0; } return getImageInfo().getColorPaletteDef().getNumPoints(); } public Object getValueAt(int rowIndex, int columnIndex) { if (getImageInfo() == null) { return null; } final ColorPaletteDef.Point point = getImageInfo().getColorPaletteDef().getPointAt(rowIndex); if (columnIndex == 0) { return point.getLabel(); } else if (columnIndex == 1) { final Color color = point.getColor(); return color.equals(ImageInfo.NO_COLOR) ? null : color; } else if (columnIndex == 2) { return Double.isNaN(point.getSample()) ? "Uncoded" : (int) point.getSample(); } else if (columnIndex == 3) { final RasterDataNode raster = parentForm.getFormModel().getRaster(); final Stx stx = raster.getStx(); Assert.notNull(stx, "stx"); final int[] frequencies = stx.getHistogramBins(); Assert.notNull(frequencies, "frequencies"); if (raster instanceof Band) { Band band = (Band) raster; final IndexCoding indexCoding = band.getIndexCoding(); if (indexCoding != null) { final String[] indexNames = indexCoding.getIndexNames(); if (rowIndex < indexNames.length) { final int indexValue = indexCoding.getAttributeIndex(indexCoding.getIndex(indexNames[rowIndex])); final double frequency = frequencies[indexValue]; return frequency / stx.getSampleCount(); } } } return 0.0; } else if (columnIndex == 4) { final RasterDataNode raster = parentForm.getFormModel().getRaster(); if (raster instanceof Band) { Band band = (Band) raster; final IndexCoding indexCoding = band.getIndexCoding(); if (indexCoding != null && rowIndex < indexCoding.getSampleCount()) { final String text = indexCoding.getAttributeAt(rowIndex).getDescription(); return text != null ? text : ""; } } return ""; } return null; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (getImageInfo() == null) { return; } final ColorPaletteDef.Point point = getImageInfo().getColorPaletteDef().getPointAt(rowIndex); if (columnIndex == 0) { point.setLabel((String) aValue); fireTableCellUpdated(rowIndex, columnIndex); parentForm.applyChanges(); } else if (columnIndex == 1) { final Color color = (Color) aValue; point.setColor(color == null ? ImageInfo.NO_COLOR : color); fireTableCellUpdated(rowIndex, columnIndex); parentForm.applyChanges(); } } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex == 0 || columnIndex == 1; } } }