Package com.cburch.logisim.gui.main

Source Code of com.cburch.logisim.gui.main.ExportImage$ExportThread

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.gui.main;

import com.cburch.logisim.circuit.Circuit;
import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.comp.ComponentDrawContext;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.file.Loader;
import com.cburch.logisim.proj.Project;
import com.cburch.logisim.util.GifEncoder;
import com.cburch.logisim.util.StringGetter;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.ProgressMonitor;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;

class ExportImage {
  private static final int SLIDER_DIVISIONS = 6;

  private static final int FORMAT_GIF = 0;
  private static final int FORMAT_PNG = 1;
  private static final int FORMAT_JPG = 2;
 
  private static final int BORDER_SIZE = 5;

  private ExportImage() { }

  static void doExport(Project proj) {
    // First display circuit/parameter selection dialog
    Frame frame = proj.getFrame();
    CircuitJList list = new CircuitJList(proj, true);
    if (list.getModel().getSize() == 0) {
      JOptionPane.showMessageDialog(proj.getFrame(),
          Strings.get("exportEmptyCircuitsMessage"),
          Strings.get("exportEmptyCircuitsTitle"),
          JOptionPane.YES_NO_OPTION);
      return;
    }
    OptionsPanel options = new OptionsPanel(list);
    int action = JOptionPane.showConfirmDialog(frame,
        options, Strings.get("exportImageSelect"),
        JOptionPane.OK_CANCEL_OPTION,
        JOptionPane.QUESTION_MESSAGE);
    if (action != JOptionPane.OK_OPTION) return;
    List<Circuit> circuits = list.getSelectedCircuits();
    double scale = options.getScale();
    boolean printerView = options.getPrinterView();
    if (circuits.isEmpty()) return;
   
    ImageFileFilter filter;
    int fmt = options.getImageFormat();
    switch (options.getImageFormat()) {
    case FORMAT_GIF:
      filter = new ImageFileFilter(fmt, Strings.getter("exportGifFilter"),
        new String[] { "gif" });
      break;
    case FORMAT_PNG:
      filter = new ImageFileFilter(fmt, Strings.getter("exportPngFilter"),
        new String[] { "png" });
      break;
    case FORMAT_JPG:
      filter = new ImageFileFilter(fmt, Strings.getter("exportJpgFilter"),
        new String[] { "jpg", "jpeg", "jpe", "jfi", "jfif", "jfi" });
      break;
    default:
      System.err.println("unexpected format; aborted"); //OK
      return;
    }
   
    // Then display file chooser
    Loader loader = proj.getLogisimFile().getLoader();
    JFileChooser chooser = loader.createChooser();
    if (circuits.size() > 1) {
      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
      chooser.setDialogTitle(Strings.get("exportImageDirectorySelect"));
    } else {
      chooser.setFileFilter(filter);
      chooser.setDialogTitle(Strings.get("exportImageFileSelect"));
    }
    int returnVal = chooser.showDialog(frame, Strings.get("exportImageButton"));
    if (returnVal != JFileChooser.APPROVE_OPTION) return;

    // Determine whether destination is valid
    File dest = chooser.getSelectedFile();
    chooser.setCurrentDirectory(dest.isDirectory() ? dest : dest.getParentFile());
    if (dest.exists()) {
      if (!dest.isDirectory()) {
        int confirm = JOptionPane.showConfirmDialog(proj.getFrame(),
          Strings.get("confirmOverwriteMessage"),
          Strings.get("confirmOverwriteTitle"),
          JOptionPane.YES_NO_OPTION);
        if (confirm != JOptionPane.YES_OPTION) return;
      }
    } else {
      if (circuits.size() > 1) {
        boolean created = dest.mkdir();
        if (!created) {
          JOptionPane.showMessageDialog(proj.getFrame(),
              Strings.get("exportNewDirectoryErrorMessage"),
              Strings.get("exportNewDirectoryErrorTitle"),
              JOptionPane.YES_NO_OPTION);
          return;
        }
      }
    }

    // Create the progress monitor
    ProgressMonitor monitor = new ProgressMonitor(frame,
        Strings.get("exportImageProgress"),
        null,
        0, 10000);
    monitor.setMillisToDecideToPopup(100);
    monitor.setMillisToPopup(200);
    monitor.setProgress(0);

    // And start a thread to actually perform the operation
    // (This is run in a thread so that Swing will update the
    // monitor.)
    new ExportThread(frame, frame.getCanvas(), dest, filter,
        circuits, scale, printerView, monitor).start();

  }

  private static class OptionsPanel extends JPanel implements ChangeListener {
    JSlider slider;
    JLabel curScale;
    JCheckBox printerView;
    JRadioButton formatPng;
    JRadioButton formatGif;
    JRadioButton formatJpg;
    GridBagLayout gridbag;
    GridBagConstraints gbc;
    Dimension curScaleDim;

    OptionsPanel(JList list) {
      // set up components
      formatPng = new JRadioButton("PNG");
      formatGif = new JRadioButton("GIF");
      formatJpg = new JRadioButton("JPEG");
      ButtonGroup bgroup = new ButtonGroup();
      bgroup.add(formatPng);
      bgroup.add(formatGif);
      bgroup.add(formatJpg);
      formatPng.setSelected(true);

      slider = new JSlider(JSlider.HORIZONTAL,
          -3 * SLIDER_DIVISIONS, 3 * SLIDER_DIVISIONS, 0);
      slider.setMajorTickSpacing(10);
      slider.addChangeListener(this);
      curScale = new JLabel("222%");
      curScale.setHorizontalAlignment(SwingConstants.RIGHT);
      curScale.setVerticalAlignment(SwingConstants.CENTER);
      curScaleDim = new Dimension(curScale.getPreferredSize());
      curScaleDim.height = Math.max(curScaleDim.height,
          slider.getPreferredSize().height);
      stateChanged(null);

      printerView = new JCheckBox();
      printerView.setSelected(true);

      // set up panel
      gridbag = new GridBagLayout();
      gbc = new GridBagConstraints();
      setLayout(gridbag);

      // now add components into panel
      gbc.gridy = 0;
      gbc.gridx = GridBagConstraints.RELATIVE;
      gbc.anchor = GridBagConstraints.NORTHWEST;
      gbc.insets = new Insets(5, 0, 5, 0);
      gbc.fill = GridBagConstraints.NONE;
      addGb(new JLabel(Strings.get("labelCircuits") + " "));
      gbc.fill = GridBagConstraints.HORIZONTAL;
      addGb(new JScrollPane(list));
      gbc.fill = GridBagConstraints.NONE;
     
      gbc.gridy++;
      addGb(new JLabel(Strings.get("labelImageFormat") + " "));
      Box formatsPanel = new Box(BoxLayout.Y_AXIS);
      formatsPanel.add(formatPng);
      formatsPanel.add(formatGif);
      formatsPanel.add(formatJpg);
      addGb(formatsPanel);
     
      gbc.gridy++;
      addGb(new JLabel(Strings.get("labelScale") + " "));
      addGb(slider);
      addGb(curScale);
     
      gbc.gridy++;
      addGb(new JLabel(Strings.get("labelPrinterView") + " "));
      addGb(printerView);
    }
   
    private void addGb(JComponent comp) {
      gridbag.setConstraints(comp, gbc);
      add(comp);
    }

    double getScale() {
      return Math.pow(2.0, (double) slider.getValue() / SLIDER_DIVISIONS);
    }
   
    boolean getPrinterView() { return printerView.isSelected(); }
   
    int getImageFormat() {
      if (formatGif.isSelected()) return FORMAT_GIF;
      if (formatJpg.isSelected()) return FORMAT_JPG;
      return FORMAT_PNG;
    }

    public void stateChanged(ChangeEvent e) {
      double scale = getScale();
      curScale.setText((int) Math.round(100.0 * scale) + "%");
      if (curScaleDim != null) curScale.setPreferredSize(curScaleDim);
    }
  }
 
  private static class ImageFileFilter extends FileFilter {
    private int type;
    private String[] extensions;
    private StringGetter desc;
   
    private ImageFileFilter(int type, StringGetter desc, String[] exts) {
      this.type = type;
      this.desc = desc;
      extensions = new String[exts.length];
      for (int i = 0; i < exts.length; i++) {
        extensions[i] = "." + exts[i].toLowerCase();   
      }
    }
   
    @Override
    public boolean accept(File f) {
      String name = f.getName().toLowerCase();
      for (int i = 0; i < extensions.length; i++) {
        if (name.endsWith(extensions[i])) return true;
      }
      return f.isDirectory();
    }

    @Override
    public String getDescription() {
      return desc.get();
    }
  }

  private static class ExportThread extends Thread {
    Frame frame;
    Canvas canvas;
    File dest;
    ImageFileFilter filter;
    List<Circuit> circuits;
    double scale;
    boolean printerView;
    ProgressMonitor monitor;

    ExportThread(Frame frame, Canvas canvas, File dest, ImageFileFilter f,
        List<Circuit> circuits, double scale, boolean printerView,
        ProgressMonitor monitor) {
      this.frame = frame;
      this.canvas = canvas;
      this.dest = dest;
      this.filter = f;
      this.circuits = circuits;
      this.scale = scale;
      this.printerView = printerView;
      this.monitor = monitor;
    }

    @Override
    public void run() {
      for (Circuit circ : circuits) {
        export(circ);
      }
    }
   
    private void export(Circuit circuit) {
      Bounds bds = circuit.getBounds(canvas.getGraphics())
        .expand(BORDER_SIZE);
      int width = (int) Math.round(bds.getWidth() * scale);
      int height = (int) Math.round(bds.getHeight() * scale);
      BufferedImage img = new BufferedImage(width, height,
          BufferedImage.TYPE_INT_RGB);
      Graphics base = img.getGraphics();
      Graphics g = base.create();
      g.setColor(Color.white);
      g.fillRect(0, 0, width, height);
      g.setColor(Color.black);
      if (g instanceof Graphics2D) {
        ((Graphics2D) g).scale(scale, scale);
        ((Graphics2D) g).translate(-bds.getX(), -bds.getY());
      } else {
        JOptionPane.showMessageDialog(frame,
            Strings.get("couldNotCreateImage"));
        monitor.close();
      }

      CircuitState circuitState = canvas.getProject().getCircuitState(circuit);
      ComponentDrawContext context = new ComponentDrawContext(canvas,
          circuit, circuitState, base, g, printerView);
      circuit.draw(context, null);

      File where;
      if (dest.isDirectory()) {
        where = new File(dest, circuit.getName() + filter.extensions[0]);
      } else if (filter.accept(dest)) {
        where = dest;
      } else {
        String newName = dest.getName() + filter.extensions[0];
        where = new File(dest.getParentFile(), newName);
      }
      try {
        switch (filter.type) {
        case FORMAT_GIF: GifEncoder.toFile(img, where, monitor); break;
        case FORMAT_PNG: ImageIO.write(img, "PNG", where); break;
        case FORMAT_JPG: ImageIO.write(img, "JPEG", where); break;
        }
      } catch (Exception e) {
        JOptionPane.showMessageDialog(frame,
            Strings.get("couldNotCreateFile"));
        monitor.close();
        return;
      }
      g.dispose();
      monitor.close();
    }
  }
}
TOP

Related Classes of com.cburch.logisim.gui.main.ExportImage$ExportThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.