/* * Copyright 2004-2010 Information & Software Engineering Group (188/1) * Institute of Software Technology and Interactive Systems * Vienna University of Technology, Austria * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.ifs.tuwien.ac.at/dm/somtoolbox/license.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.tuwien.ifs.somtoolbox.apps.viewer; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Properties; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import at.tuwien.ifs.somtoolbox.SOMToolboxException; import at.tuwien.ifs.somtoolbox.apps.viewer.fileutils.ExportUtils; import at.tuwien.ifs.somtoolbox.data.InputData; import at.tuwien.ifs.somtoolbox.data.SOMLibClassInformation; import at.tuwien.ifs.somtoolbox.layers.GrowingLayer; import at.tuwien.ifs.somtoolbox.util.CentredDialog; import at.tuwien.ifs.somtoolbox.util.FileUtils; import at.tuwien.ifs.somtoolbox.util.VisualisationUtils; /** * Provides a dialog for setting various options when exporting visualisations. * * @author Rudolf Mayer * @version $Id: ExportDialog.java 3873 2010-10-28 09:29:58Z frank $ */ public class ExportDialog extends CentredDialog implements ActionListener { private static final long serialVersionUID = 1L; private static final int defaultUnitWidth = 25; private JCheckBox exportBackgroundCheckBox = new JCheckBox("Export background image"); private JButton exportButton = new JButton("Export"); private JCheckBox exportImagemapCheckBox = new JCheckBox("Export image map"); private JCheckBox exportVisCheckBox = new JCheckBox("Export visualisation"); private JCheckBox exportGridCheckBox = new JCheckBox("Draw grid"); private JCheckBox exportNoteSymbolsCheckBox = new JCheckBox("Draw note symbols"); private JCheckBox exportHybridImageCheckBox = new JCheckBox("Export hybrid visualisation"); private JCheckBox regenerateImagesCheckBox = new JCheckBox("Generate visualization image(s)"); // TODO: enable this only when data-type is audio-rp private JCheckBox generateRhythmPatternsCheckBox = new JCheckBox("Generate Rhythm Pattern plots"); private JCheckBox copyDataCheckBox = new JCheckBox("Copy data items"); private JTextField fileNameTextField = new JTextField(30); private JTextField cleanDataNamesTextField = new JTextField(30); private JTextField streamingURLTextField = new JTextField(30); private JTextField templatesTextField = new JTextField(30); private JTextField titleTextField = new JTextField(30); private GrowingLayer layer; private SpinnerNumberModel spinnerNumberModel; private CommonSOMViewerStateData state; private JSpinner widthSpinner; private JLabel panelComputedDimension; private InputData inputVector; private boolean isAudioSOM; private String dataDir; public ExportDialog(JFrame owner, CommonSOMViewerStateData state) { super(owner, "Export", true); this.state = state; layer = state.growingLayer; inputVector = state.inputDataObjects.getInputData(); isAudioSOM = inputVector != null && inputVector.getContentType().equalsIgnoreCase("audio"); dataDir = "data"; // isAudioSOM = true; // temporary fix, should make check for audio type work // fileNameTextField.setText(state.viewerWorkingDirectoryName); // cleanDataNamesTextField.setText(state.viewerWorkingDirectoryName); // streamingURLTextField.setText(state.viewerWorkingDirectoryName); titleTextField.setText("My Map"); // // temporarily for mozart // fileNameTextField.setText("/home/mayer/workspace/mozart/mozart"); // cleanDataNamesTextField.setText("/mnt/nemesis/work/mozart/filelist_edit.txt"); // streamingURLTextField.setText("http://www.ifs.tuwien.ac.at/mir/mozart/"); // // // temporarily for ISMIR // fileNameTextField.setText("/home/mayer/workspace/mir/playsom/demo/ballroom_dance"); // cleanDataNamesTextField.setText(""); // streamingURLTextField.setText("http://www.ifs.tuwien.ac.at/mir/playsom/demo/"); // templatesTextField.setText("/home/mayer/workspace/mir/playsom/demo/style/"); // titleTextField.setText("PlaySOM-Demo: Ballroom dance music"); // // // temporarily for FoDok // fileNameTextField.setText("/home/mayer/work/fodok/webDemo/fodokWebDemo"); // cleanDataNamesTextField.setText(""); // streamingURLTextField.setText("http://www.ifs.tuwien.ac.at/~mayer/fodok/demo/"); // templatesTextField.setText("/home/mayer/work/fodok/webDemo/style"); // titleTextField.setText("FoDok Austria - Web Demo"); // // // temporarily for ISMIR Poster // fileNameTextField.setText("/home/mayer/work/papers/ISMIR2006/poster/screeners"); // // // temporarily for crime data // titleTextField.setText("Crime Data - Simple"); // fileNameTextField.setText("/home/mayer/work/crime-data/web/simple/som"); templatesTextField.setText(""); getContentPane().setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridy = 0; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(5, 5, 5, 5); getContentPane().add(new JLabel("Output Path + Filename"), c); getContentPane().add(fileNameTextField, c); JButton browseButton = new JButton("Browse"); browseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { File filePath = ExportUtils.getFilePath(ExportDialog.this, ExportDialog.this.state.getFileChooser(), "Export file name base"); if (filePath != null) { ExportDialog.this.fileNameTextField.setText(filePath.getAbsolutePath()); } } }); getContentPane().add(browseButton, c); c.gridy = c.gridy + 1; getContentPane().add(new JLabel("HTML templates"), c); getContentPane().add(templatesTextField, c); JButton browseButtonHTMLTemplates = new JButton("Browse"); browseButtonHTMLTemplates.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { File filePath = ExportUtils.getFilePath(ExportDialog.this, ExportDialog.this.state.getFileChooser(), "HTML templates"); if (filePath != null) { ExportDialog.this.templatesTextField.setText(filePath.getAbsolutePath()); } } }); getContentPane().add(browseButtonHTMLTemplates, c); c.gridy = c.gridy + 1; getContentPane().add(new JLabel("Clean Data Names"), c); getContentPane().add(cleanDataNamesTextField, c); JButton browseButtonDataNames = new JButton("Browse"); browseButtonDataNames.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { File filePath = ExportUtils.getFilePath(ExportDialog.this, ExportDialog.this.state.getFileChooser(), "Data item name mapping"); if (filePath != null) { ExportDialog.this.cleanDataNamesTextField.setText(filePath.getAbsolutePath()); } } }); getContentPane().add(browseButtonDataNames, c); // if (isAudioSOM) { c.gridy = c.gridy + 1; getContentPane().add(new JLabel("Data Dir / Streaming URL"), c); getContentPane().add(streamingURLTextField, c); JButton browseButtonStreamingURL = new JButton("Browse"); browseButtonStreamingURL.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { File filePath = ExportUtils.getFilePath(ExportDialog.this, ExportDialog.this.state.getFileChooser(), "Streaming URL"); if (filePath != null) { ExportDialog.this.streamingURLTextField.setText(filePath.getAbsolutePath()); } } }); getContentPane().add(browseButtonStreamingURL, c); // } c.gridy = c.gridy + 1; getContentPane().add(new JLabel("Unit-width: "), c); // spinnerNumberModel = new SpinnerNumberModel(layer.getXSize() * defaultUnitWidth, layer.getXSize(), // layer.getXSize() * 200, layer.getXSize()); spinnerNumberModel = new SpinnerNumberModel(defaultUnitWidth, 1, 200, 1); widthSpinner = new JSpinner(spinnerNumberModel); widthSpinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { // panelComputedHeight.setText(String.valueOf(((Integer) spinnerNumberModel.getValue()).intValue() // / defaultUnitWidth * layer.getYSize())); int intValue = ((Integer) spinnerNumberModel.getValue()).intValue(); panelComputedDimension.setText(intValue * layer.getXSize() + "x" + intValue * layer.getYSize()); } }); JPanel panelWidth = new JPanel(); panelWidth.add(widthSpinner, c); panelWidth.add(new JLabel(" == ")); panelComputedDimension = new JLabel(defaultUnitWidth * layer.getXSize() + "x" + defaultUnitWidth * layer.getYSize()); panelWidth.add(panelComputedDimension, c); panelWidth.add(new JLabel("pixel")); getContentPane().add(panelWidth, c); c.gridy = c.gridy + 1; getContentPane().add(new JLabel("Image map header"), c); getContentPane().add(titleTextField, c); c.gridwidth = 3; c.gridy = c.gridy + 1; JPanel exportImagesPanel = new JPanel(new GridLayout(1, 3)); if (state.mapPNode.getCurrentVisualization() == null) { exportVisCheckBox.setEnabled(false); } else { exportVisCheckBox.setSelected(true); } exportImagesPanel.add(exportVisCheckBox, c); if (state.mapPNode.getBackgroundImage() == null) { exportBackgroundCheckBox.setEnabled(false); } else { exportBackgroundCheckBox.setSelected(true); } exportImagesPanel.add(exportBackgroundCheckBox, c); if (state.mapPNode.getBackgroundImage() != null && state.mapPNode.getCurrentVisualization() != null) { exportHybridImageCheckBox.setSelected(true); } else { exportHybridImageCheckBox.setEnabled(false); } exportImagesPanel.add(exportHybridImageCheckBox, c); getContentPane().add(exportImagesPanel, c); c.gridy = c.gridy + 1; JPanel imageLayerPanel = new JPanel(new GridLayout(1, 3)); if (state.mapPNode.getBackgroundImage() != null || state.mapPNode.getCurrentVisualization() != null) { exportGridCheckBox.setSelected(true); } else { // exportGridCheckBox.setEnabled(false); } imageLayerPanel.add(exportGridCheckBox, c); getContentPane().add(imageLayerPanel, c); c.gridy = c.gridy + 1; JPanel imageMapPanel = new JPanel(new GridLayout(1, 3)); exportImagemapCheckBox.setSelected(true); imageMapPanel.add(exportImagemapCheckBox, c); getContentPane().add(imageMapPanel, c); JPanel regeneratePanel = new JPanel(new GridLayout(1, 3)); c.gridy = c.gridy + 1; regenerateImagesCheckBox.setSelected(true); regeneratePanel.add(regenerateImagesCheckBox, c); getContentPane().add(regeneratePanel, c); if (isAudioSOM) { JPanel audioPanel = new JPanel(new GridLayout(1, 3)); audioPanel.setBorder(BorderFactory.createTitledBorder("Audio")); c.gridy = c.gridy + 1; // c.fill = GridBagConstraints.HORIZONTAL; if (state.mapPNode.getBackgroundImage() != null || state.mapPNode.getCurrentVisualization() != null) { exportNoteSymbolsCheckBox.setSelected(true); } else { exportNoteSymbolsCheckBox.setEnabled(false); } audioPanel.add(exportNoteSymbolsCheckBox, c); generateRhythmPatternsCheckBox.setSelected(true); audioPanel.add(generateRhythmPatternsCheckBox, c); getContentPane().add(audioPanel, c); } else { // change to text SOM! JPanel dataPanel = new JPanel(new GridLayout(1, 3)); dataPanel.setBorder(BorderFactory.createTitledBorder("Data")); c.gridy = c.gridy + 1; // c.fill = GridBagConstraints.HORIZONTAL; dataPanel.add(copyDataCheckBox, c); copyDataCheckBox.setSelected(true); getContentPane().add(dataPanel, c); } c.gridy = c.gridy + 1; c.anchor = GridBagConstraints.EAST; exportButton.addActionListener(this); getContentPane().add(exportButton, c); pack(); } @Override public void actionPerformed(ActionEvent e) { int unitWidth = ((Integer) spinnerNumberModel.getValue()).intValue(); int width = unitWidth * layer.getXSize(); int height = unitWidth * layer.getYSize(); String baseName = fileNameTextField.getText(); String imageDir = baseName + "_map/"; new File(imageDir).mkdir(); String absoluteDir = new File(FileUtils.getPathFrom(baseName)).getAbsolutePath(); boolean doCopyData = copyDataCheckBox.isSelected(); dataDir = streamingURLTextField.getText(); // data is not copied if data dir is a URL // TODO: give a warning or make copyDataCheckBox disabled if URL is entered in streamingURLTextField if (FileUtils.isURL(dataDir)) { doCopyData = false; } try { ArrayList<String[]> linkInfo = new ArrayList<String[]>(); if (exportBackgroundCheckBox.isSelected()) { linkInfo.add(new String[] { "Image", "Mozart-Silhouette" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage image = ExportUtils.scaleBackgroundImage(state, width); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) image.getGraphics(), state.growingSOM, width, height, Color.GRAY); } if (exportNoteSymbolsCheckBox.isSelected()) { ExportUtils.drawLinkInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) image.getGraphics(), CommonSOMViewerStateData.fileNamePrefix); } FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", image); } if (state.inputDataObjects.getClassInfo() != null) { linkInfo.add(new String[] { "Image-ClassInfo", "[+categories]" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage background = ExportUtils.scaleBackgroundImage(state, width); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) background.getGraphics(), state.growingSOM, width, height, Color.GRAY); } ExportUtils.drawClassInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) background.getGraphics()); FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", background); linkInfo.add(new String[] { "Image-ClassInfo-only", "[categories]" }); // BufferedImage classesOnly = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) background.getGraphics(), state.growingSOM, width, height, Color.GRAY); } ExportUtils.drawClassInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) background.getGraphics()); FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", background); } } linkInfo.add(new String[] { "SPACER", "  " }); } if (exportVisCheckBox.isSelected()) { linkInfo.add(new String[] { "Visualisation", "Topic Islands" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage image = ExportUtils.getVisualization(state, unitWidth); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) image.getGraphics(), state.growingSOM, width, height, Color.GRAY); } if (exportNoteSymbolsCheckBox.isSelected()) { ExportUtils.drawLinkInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) image.getGraphics(), CommonSOMViewerStateData.fileNamePrefix); } FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", image); } if (state.inputDataObjects.getClassInfo() != null) { linkInfo.add(new String[] { "Visualisation-ClassInfo", "[+categories]" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage image = ExportUtils.getVisualization(state, unitWidth); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) image.getGraphics(), state.growingSOM, width, height, Color.GRAY); } ExportUtils.drawClassInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) image.getGraphics()); FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", image); } } linkInfo.add(new String[] { "SPACER", "  " }); } else { linkInfo.add(new String[] { "Map", "Plain" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) image.getGraphics(), state.growingSOM, width, height, Color.GRAY); } if (exportNoteSymbolsCheckBox.isSelected()) { ExportUtils.drawLinkInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) image.getGraphics(), CommonSOMViewerStateData.fileNamePrefix); } FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", image); } if (state.inputDataObjects.getClassInfo() != null) { linkInfo.add(new String[] { "Map-ClassInfo", "[+categories]" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) image.getGraphics(), state.growingSOM, width, height, Color.GRAY); } ExportUtils.drawClassInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) image.getGraphics()); FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", image); } } linkInfo.add(new String[] { "SPACER", "  " }); } if (exportHybridImageCheckBox.isSelected()) { linkInfo.add(new String[] { "Hybrid", "Silhouette & Islands" }); if (regenerateImagesCheckBox.isSelected()) { // generate image only when check box is selected BufferedImage image = ExportUtils.scaleBackgroundImage(state, width); // set opacity factor for alpha composition float alpha = 55 / 100f; Graphics2D g = (Graphics2D) image.getGraphics(); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); g.drawImage(ExportUtils.getVisualization(state, unitWidth), 0, 0, null); if (exportGridCheckBox.isSelected()) { VisualisationUtils.drawUnitGrid((Graphics2D) image.getGraphics(), state.growingSOM, width, height, Color.GRAY); } ExportUtils.drawLinkInfo(state.growingLayer, state.mapPNode, unitWidth, (Graphics2D) image.getGraphics(), CommonSOMViewerStateData.fileNamePrefix); FileUtils.saveImageToFile(imageDir + linkInfo.get(linkInfo.size() - 1)[0] + ".png", image); } } if (doCopyData) { new File(absoluteDir + File.separator + dataDir).mkdirs(); try { ExportUtils.copyData(CommonSOMViewerStateData.fileNamePrefix, absoluteDir + File.separator + dataDir, "../" + new File(baseName).getName() + "_details/styleUnitDetails.css", state.growingLayer.getAllMappedDataNames()); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } if (exportImagemapCheckBox.isSelected()) { String[][] visualisations = new String[linkInfo.size()][2]; for (int i = 0; i < visualisations.length; i++) { visualisations[i] = linkInfo.get(i); } Properties cleanDataNamesMapping = null; if (cleanDataNamesTextField.getText() != null && !cleanDataNamesTextField.getText().trim().equals("")) { try { cleanDataNamesMapping = new Properties(); cleanDataNamesMapping.load(new FileInputStream(cleanDataNamesTextField.getText().trim())); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } String htmlTemplatesDir = null; if (templatesTextField.getText() != null && !templatesTextField.getText().trim().equals("")) { htmlTemplatesDir = templatesTextField.getText().trim(); } String imageMapTitle = null; if (titleTextField.getText() != null && !titleTextField.getText().trim().equals("")) { imageMapTitle = titleTextField.getText().trim(); } SOMLibClassInformation classInfo = state.inputDataObjects.getClassInfo(); Color[] classLegendColors = ((SOMViewer) getParent()).getClassLegendColors(); new ExportUtils().saveImageMap(state.growingLayer, unitWidth, baseName, new File(baseName).getName(), visualisations, isAudioSOM, classInfo, classLegendColors, cleanDataNamesMapping, CommonSOMViewerStateData.fileNamePrefix, dataDir, htmlTemplatesDir, imageMapTitle, generateRhythmPatternsCheckBox.isSelected(), true); } JOptionPane.showMessageDialog(this, "Export finished!"); } catch (SOMToolboxException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(getParent(), ex.getMessage(), "Error during export", JOptionPane.ERROR_MESSAGE); } } }