/******************************************************************************* * Copyright (c) MOBAC developers * * 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 2 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 mobac.gui.panels; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Arrays; import java.util.TreeSet; import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.components.JTileSizeCombo; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.AtlasCreator; import mobac.program.model.AtlasOutputFormat; import mobac.program.model.Settings; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; public class JTileImageParametersPanel extends JCollapsiblePanel { private static final long serialVersionUID = 1L; private static boolean JPEG_TESTED = false; private JCheckBox enableCustomTileProcessingCheckButton; private JLabel tileSizeWidthLabel; private JLabel tileSizeHeightLabel; private JLabel tileImageFormatLabel; private JTileSizeCombo tileSizeWidth; private JTileSizeCombo tileSizeHeight; private JComboBox<TileImageFormat> tileImageFormat; private boolean widthEnabled = true; private boolean heightEnabled = true; private boolean formatPngEnabled = true; private boolean formatJpgEnabled = true; public JTileImageParametersPanel() { super(I18nUtils.localizedStringForKey("lp_tile_param_title"), new GridBagLayout()); setName("TileImageParameters"); enableCustomTileProcessingCheckButton = new JCheckBox( I18nUtils.localizedStringForKey("lp_tile_param_recreate_checkbox_title")); enableCustomTileProcessingCheckButton.addActionListener(new EnableCustomTileSizeCheckButtonListener()); enableCustomTileProcessingCheckButton.setToolTipText(I18nUtils .localizedStringForKey("lp_tile_param_recreate_checkbox_tips")); tileSizeWidthLabel = new JLabel(I18nUtils.localizedStringForKey("lp_tile_param_width_title")); tileSizeWidth = new JTileSizeCombo(); tileSizeWidth.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_param_width_tips")); tileSizeHeightLabel = new JLabel(I18nUtils.localizedStringForKey("lp_tile_param_height_title")); tileSizeHeight = new JTileSizeCombo(); tileSizeHeight.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_param_height_tips")); tileImageFormatLabel = new JLabel(I18nUtils.localizedStringForKey("lp_tile_param_image_fmt_title")); tileImageFormat = new JComboBox<TileImageFormat>(new TileFormatComboModel(TileImageFormat.values())); tileImageFormat.setMaximumRowCount(tileImageFormat.getItemCount()); tileImageFormat.addActionListener(new TileImageFormatListener()); GBC gbc_std = GBC.std().insets(5, 2, 5, 3); GBC gbc_eol = GBC.eol().insets(5, 2, 5, 3); JPanel tileSizePanel = new JPanel(new GridBagLayout()); tileSizePanel.add(tileSizeWidthLabel, gbc_std); tileSizePanel.add(tileSizeWidth, gbc_std); tileSizePanel.add(tileSizeHeightLabel, gbc_std); tileSizePanel.add(tileSizeHeight, gbc_eol); JPanel tileColorDepthPanel = new JPanel(); tileColorDepthPanel.add(tileImageFormatLabel); tileColorDepthPanel.add(tileImageFormat); contentContainer.add(enableCustomTileProcessingCheckButton, gbc_eol); contentContainer.add(tileSizePanel, GBC.eol()); contentContainer.add(tileColorDepthPanel, GBC.eol()); } public void loadSettings() { Settings settings = Settings.getInstance(); enableCustomTileProcessingCheckButton.setSelected(settings.isCustomTileSize()); updateControlsState(); tileImageFormat.setSelectedItem(settings.getTileImageFormat()); tileSizeHeight.setValue(settings.getTileSize().height); tileSizeWidth.setValue(settings.getTileSize().width); } public void saveSettings() { Settings settings = Settings.getInstance(); settings.setCustomTileSize(enableCustomTileProcessingCheckButton.isSelected()); Dimension tileSize = new Dimension(tileSizeWidth.getValue(), tileSizeHeight.getValue()); settings.setTileSize(tileSize); settings.setTileImageFormat((TileImageFormat) tileImageFormat.getSelectedItem()); } public TileImageParameters getSelectedTileImageParameters() { TileImageParameters customTileParameters = null; boolean customTileSize = enableCustomTileProcessingCheckButton.isSelected(); if (customTileSize) { int width = tileSizeWidth.getValue(); int height = tileSizeHeight.getValue(); TileImageFormat format = (mobac.program.model.TileImageFormat) tileImageFormat.getSelectedItem(); customTileParameters = new TileImageParameters(width, height, format); } return customTileParameters; } public void atlasFormatChanged(AtlasOutputFormat newAtlasOutputFormat) { Class<? extends AtlasCreator> atlasCreatorClass = newAtlasOutputFormat.getMapCreatorClass(); SupportedParameters params = atlasCreatorClass.getAnnotation(SupportedParameters.class); if (params != null) { TreeSet<TileImageParameters.Name> paramNames = new TreeSet<TileImageParameters.Name>(Arrays.asList(params .names())); if (paramNames.contains(Name.format)) { formatPngEnabled = true; formatJpgEnabled = true; } else { formatPngEnabled = paramNames.contains(Name.format_png); formatJpgEnabled = paramNames.contains(Name.format_jpg); } widthEnabled = paramNames.contains(Name.width); heightEnabled = paramNames.contains(Name.height); enableCustomTileProcessingCheckButton.setEnabled(true); } else { formatPngEnabled = false; formatJpgEnabled = false; widthEnabled = false; heightEnabled = false; enableCustomTileProcessingCheckButton.setEnabled(false); } updateControlsState(); } public void updateControlsState() { boolean b = false; if (enableCustomTileProcessingCheckButton.isEnabled()) b = enableCustomTileProcessingCheckButton.isSelected(); tileSizeWidth.setEnabled(b && widthEnabled); tileSizeWidthLabel.setEnabled(b && widthEnabled); tileSizeHeightLabel.setEnabled(b && heightEnabled); tileSizeHeight.setEnabled(b && heightEnabled); boolean formatEnabled = formatJpgEnabled || formatPngEnabled; tileImageFormatLabel.setEnabled(b && formatEnabled); tileImageFormat.setEnabled(b && formatEnabled); if (formatPngEnabled && !formatJpgEnabled) updateFormatComboModel(TileImageFormat.getPngFormats()); else if (!formatPngEnabled && formatJpgEnabled) updateFormatComboModel(TileImageFormat.getJpgFormats()); else updateFormatComboModel(TileImageFormat.values()); } private void updateFormatComboModel(TileImageFormat[] values) { TileFormatComboModel model = (TileFormatComboModel) tileImageFormat.getModel(); model.changeValues(values); } public String getValidationErrorMessages() { String errorText = ""; if (!enableCustomTileProcessingCheckButton.isSelected()) return errorText; if (!tileSizeHeight.isValueValid()) errorText += String.format(I18nUtils.localizedStringForKey("lp_tile_param_msg_valid_height"), JTileSizeCombo.MIN, JTileSizeCombo.MAX); if (!tileSizeWidth.isValueValid()) errorText += String.format(I18nUtils.localizedStringForKey("lp_tile_param_msg_valid_width"), JTileSizeCombo.MIN, JTileSizeCombo.MAX); return errorText; } private class EnableCustomTileSizeCheckButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { updateControlsState(); } } private class TileImageFormatListener implements ActionListener { public void actionPerformed(ActionEvent event) { if (!tileImageFormat.isEnabled()) return; TileImageFormat tif = (TileImageFormat) tileImageFormat.getSelectedItem(); if (tif == null) return; if (!JPEG_TESTED && (tif.getDataWriter() instanceof TileImageJpegDataWriter)) { if (!TileImageJpegDataWriter.performOpenJDKJpegTest()) JOptionPane.showMessageDialog(null, "<html>The JPEG image format is not supported by OpenJDK.<br>" + "Please select a different tile format.</html>", "Image format not available on OpenJDK", JOptionPane.ERROR_MESSAGE); JPEG_TESTED = true; } else if (tif == TileImageFormat.PNG4Bit || tif == TileImageFormat.PNG8Bit) { if (Utilities.testJaiColorQuantizerAvailable()) return; JOptionPane.showMessageDialog(null, "<html>This image format is requires additional libraries to be installed:<br>" + "<b>Java Advanced Image library</b> (jai_core.jar & jai_codec.jar)<br>" + "For more details please see the file <b>README.HTM</b> " + "in section <b>Requirements</b>.</html>", "Image format not available - libraries missing", JOptionPane.ERROR_MESSAGE); tileImageFormat.setSelectedIndex(0); } } } private class TileFormatComboModel extends AbstractListModel<TileImageFormat> implements ComboBoxModel<TileImageFormat> { TileImageFormat[] values; Object selectedObject = null; public TileFormatComboModel(TileImageFormat[] values) { super(); this.values = values; if (values.length > 0) selectedObject = values[0]; } public void changeValues(TileImageFormat[] values) { this.values = values; boolean found = false; for (TileImageFormat format : values) { if (format.equals(selectedObject)) { found = true; break; } } if (!found) selectedObject = values[0]; fireContentsChanged(this, -1, -1); } public int getSize() { return values.length; } public TileImageFormat getElementAt(int index) { return values[index]; } @Override public void setSelectedItem(Object anItem) { if ((selectedObject != null && !selectedObject.equals(anItem)) || selectedObject == null && anItem != null) { selectedObject = anItem; fireContentsChanged(this, -1, -1); } } @Override public Object getSelectedItem() { return selectedObject; } } }