Java tutorial
/** * JHylaFax - A java client for HylaFAX. * * Copyright (C) 2005 by Steffen Pingel <steffenp@gmx.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 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package net.sf.jhylafax; import static net.sf.jhylafax.JHylaFAX.i18n; import gnu.hylafax.HylaFAXClient; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.swing.Action; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import net.sf.jhylafax.fax.FaxCover; import net.sf.jhylafax.fax.FaxJob; import net.sf.jhylafax.fax.HylaFAXClientHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xnap.commons.gui.Builder; import org.xnap.commons.gui.Dialogs; import org.xnap.commons.gui.ErrorDialog; import org.xnap.commons.gui.FileChooserPanel; import org.xnap.commons.gui.action.AbstractXNapAction; import org.xnap.commons.io.Job; import org.xnap.commons.io.ProgressMonitor; import org.xnap.commons.io.SubTaskProgressMonitor; import org.xnap.commons.io.UserAbortException; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; /** * A dialog for sending faxes. * * @author Steffen Pingel */ public class SendDialog extends AbstractFaxDialog { private final static Log logger = LogFactory.getLog(AbstractQueuePanel.class); private JLabel documentLabel; private JPanel coverPanel; private JTextField coverSenderTextField; private JLabel coverSenderLabel; private JTextField coverRecepientTextField; private JLabel coverRecepientLabel; private JTextField coverSubjectTextField; private JLabel coverSubjectLabel; private JTextArea coverCommentTextArea; private JLabel coverCommentLabel; private JPanel documentPanel; private DefaultFormBuilder documentPanelBuilder; private List<FileChooserPanel> documentFileChooserPanels; private JCheckBox includeCoverCheckBox; private JLabel includeCoverLabel; private JScrollPane coverCommentScrollPane; private PreviewCoverAction previewCoverAction; private MoreDocumentsAction moreDocumentsAction; private boolean quitAfterSending; public SendDialog(JFrame owner) { super(owner); moreDocumentsAction = new MoreDocumentsAction(); previewCoverAction = new PreviewCoverAction(); addNumberTextField(); addDocumentsPanel(); builder.append("", Builder.createButton(moreDocumentsAction)); builder.nextLine(); addDateControls(); includeCoverCheckBox = new JCheckBox(); includeCoverLabel = builder.append("", includeCoverCheckBox); builder.nextLine(); initializeCoverPanel(); coverPanel.setVisible(false); previewCoverAction.setEnabled(false); includeCoverCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { coverPanel.setVisible(includeCoverCheckBox.isSelected()); previewCoverAction.setEnabled(includeCoverCheckBox.isSelected()); pack(); } }); getButtonPanel().add(Builder.createButton(previewCoverAction), 0); FaxJob job = new FaxJob(); HylaFAXClientHelper.initializeFromSettings(job); setJob(job); updateLabels(); pack(); } private void addDocumentsPanel() { documentFileChooserPanels = new ArrayList<FileChooserPanel>(); FormLayout layout = new FormLayout("left:max(40dlu;pref), 3dlu, pref:grow", ""); documentPanelBuilder = new DefaultFormBuilder(layout); FileChooserPanel documentFileChooserPanel = new MyFileChooserPanel(DEFAULT_COLUMNS); documentFileChooserPanel.getFileChooser().setMultiSelectionEnabled(true); documentFileChooserPanels.add(documentFileChooserPanel); documentLabel = documentPanelBuilder.append("", documentFileChooserPanel); this.builder.appendRow(builder.getLineGapSpec()); this.builder.nextLine(); this.builder.appendRow("fill:pref:grow"); this.builder.append(documentPanelBuilder.getPanel(), 6); builder.nextLine(); } private void initializeCoverPanel() { FormLayout layout = new FormLayout("left:max(40dlu;pref), 3dlu, pref:grow", ""); DefaultFormBuilder builder = new DefaultFormBuilder(layout); coverPanel = builder.getPanel(); this.builder.appendRow(builder.getLineGapSpec()); this.builder.nextLine(); this.builder.appendRow("fill:pref:grow"); this.builder.append(coverPanel, 6); coverSenderTextField = new JTextField(DEFAULT_COLUMNS); coverSenderTextField.setText(Settings.FULLNAME.getValue()); coverSenderLabel = builder.append("", coverSenderTextField); builder.nextLine(); coverRecepientTextField = new JTextField(DEFAULT_COLUMNS); coverRecepientLabel = builder.append("", coverRecepientTextField); builder.nextLine(); coverSubjectTextField = new JTextField(DEFAULT_COLUMNS); coverSubjectLabel = builder.append("", coverSubjectTextField); builder.nextLine(); coverCommentTextArea = new JTextArea(3, DEFAULT_COLUMNS); coverCommentLabel = builder.append(""); builder.appendRow("fill:pref:grow"); // second row for text area CellConstraints cc = new CellConstraints(); coverCommentScrollPane = new JScrollPane(coverCommentTextArea); builder.add(coverCommentScrollPane, cc.xywh(builder.getColumn(), builder.getRow(), 1, 2)); builder.nextLine(2); } @Override public boolean apply() { if (!super.apply()) { return false; } if (!includeCoverCheckBox.isSelected()) { boolean filenameProvided = false; for (FileChooserPanel documentFileChooserPanel : documentFileChooserPanels) { if (documentFileChooserPanel.getTextField().getText().trim().length() != 0) { filenameProvided = true; if (Settings.CONFIRM_NONPS.getValue()) { if (!checkPostScript(documentFileChooserPanel.getTextField().getText())) { documentFileChooserPanel.getTextField().requestFocus(); return false; } } } } if (!filenameProvided) { Dialogs.showError(this, i18n.tr("You must at least send a document or a cover"), i18n.tr("JHylaFAX Error")); documentFileChooserPanels.get(0).getTextField().requestFocus(); return false; } } Fax fax = createFax(); if (fax != null) { if (send(fax)) { if (quitAfterSending) { JHylaFAX.getInstance().exit(); } return true; } } return false; } private boolean checkPostScript(String filename) { try { if (!HylaFAXClientHelper.isPostscript(filename)) { if (Dialogs.showConfirmDialog(this, i18n.tr("Do you really want to send the non PostScript file \"{0}\"?", filename), i18n.tr("JHylaFAX - Send non PostScript file"), JOptionPane.YES_NO_OPTION, Settings.CONFIRM_NONPS) == JOptionPane.NO_OPTION) { return false; } } } catch (IOException e) { logger.debug("Error checking for PostScript", e); ErrorDialog.showError(this, i18n.tr("Could not check for PostScript"), i18n.tr("JHylaFAX Error"), e); return false; } return true; } private Fax createFax() { Fax fax = new Fax(); for (FileChooserPanel documentFileChooserPanel : documentFileChooserPanels) { String filename = documentFileChooserPanel.getTextField().getText(); if (filename.trim().length() > 0) { File file = new File(filename); fax.documents.add(file); } } if (includeCoverCheckBox.isSelected() && !createFaxCover(fax)) { return null; } return fax; } private boolean createFaxCover(Fax fax) { if (fax == null) { throw new IllegalArgumentException("value may not be null"); } String filename; if (Settings.USE_INTERNAL_COVER.getValue()) { filename = "faxcover.ps"; fax.coverIn = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename); } else { filename = Settings.COVER_PATH.getValue(); try { fax.coverIn = new FileInputStream(filename); } catch (FileNotFoundException e) { fax.coverIn = null; } } if (fax.coverIn == null) { Dialogs.showError(this, i18n.tr("Could not read cover file: {0}", filename), i18n.tr("JHylaFAX Error")); return false; } fax.cover = new FaxCover(Settings.PAPER.getValue()); fax.cover.from = coverSenderTextField.getText(); fax.cover.to = coverRecepientTextField.getText(); fax.cover.regarding = coverSubjectTextField.getText(); fax.cover.comments = coverCommentTextArea.getText(); fax.cover.todays_date = SimpleDateFormat.getDateTimeInstance().format(new Date()); for (Iterator<File> it = fax.documents.iterator(); it.hasNext();) { fax.cover.addDocument(it.next().getAbsolutePath()); } return true; } private boolean send(final Fax fax) { Job<?> ioJob = new Job() { public Object run(ProgressMonitor monitor) throws Exception { monitor.setTotalSteps(13 + fax.documents.size() * 10); HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor); monitor.work(1); client.mode(HylaFAXClient.MODE_STREAM); client.type(HylaFAXClient.TYPE_IMAGE); String serverCoverFilename = null; if (fax.cover != null && fax.coverIn != null) { monitor.setText(i18n.tr("Generating cover")); SubTaskProgressMonitor coverMonitor = new SubTaskProgressMonitor(monitor, 5, 0); StringBuffer data = fax.cover.generate(fax.coverIn, coverMonitor); coverMonitor.done(); // Cover senden byte[] buffer = data.toString().getBytes(FaxCover.CHARSET); TransferMonitor transferMonitor = new TransferMonitor(monitor, 5, buffer.length); client.addTransferListener(transferMonitor); InputStream in = new ByteArrayInputStream(buffer); try { serverCoverFilename = client.putTemporary(in); } finally { transferMonitor.transferCompleted(); client.removeTransferListener(transferMonitor); in.close(); } // check if monitor was cancelled monitor.work(0); } else { monitor.work(10); } monitor.setText(i18n.tr("Uploading documents")); List<String> serverFilenames = new ArrayList<String>(); for (File file : fax.documents) { TransferMonitor transferMonitor = new TransferMonitor(monitor, 10, file.length()); client.addTransferListener(transferMonitor); InputStream in = new BufferedInputStream(new FileInputStream(file)); try { serverFilenames.add(client.putTemporary(in)); } finally { transferMonitor.transferCompleted(); client.removeTransferListener(transferMonitor); in.close(); } // check if monitor was cancelled monitor.work(0); } gnu.hylafax.Job sendJob = client.createJob(); HylaFAXClientHelper.applyParameter(sendJob, getJob()); if (serverCoverFilename != null) { if (Settings.SEND_COVER_AS_DOCUMENT.getValue()) { sendJob.addDocument(serverCoverFilename); } else { sendJob.setProperty("COVER ", serverCoverFilename); } } for (String filename : serverFilenames) { sendJob.addDocument(filename); } monitor.work(1); client.submit(sendJob); monitor.work(1); return null; } }; try { JHylaFAX.getInstance().runJob(SendDialog.this, ioJob); JHylaFAX.getInstance().updateTables(); } catch (UserAbortException e) { return false; } catch (Exception e) { logger.debug("Error sending fax", e); ErrorDialog.showError(this, i18n.tr("Could not send fax"), i18n.tr("JHylaFAX Error"), e); return false; } return true; } private File saveCover(final Fax fax) { if (fax.cover == null || fax.coverIn == null) { throw new IllegalArgumentException("fax.cover and fax.coverIn must not be null"); } Job<File> ioJob = new Job<File>() { public File run(ProgressMonitor monitor) throws Exception { monitor.setTotalSteps(10); monitor.setText(i18n.tr("Generating cover")); SubTaskProgressMonitor coverMonitor = new SubTaskProgressMonitor(monitor, 5, 0); StringBuffer data = fax.cover.generate(fax.coverIn, coverMonitor); coverMonitor.done(); File outputFile = File.createTempFile("jhylafax", ".ps"); outputFile.deleteOnExit(); OutputStream out = new FileOutputStream(outputFile); monitor.setText(i18n.tr("Saving cover")); try { out.write(data.toString().getBytes(FaxCover.CHARSET)); } finally { out.close(); } monitor.work(5); return outputFile; } }; try { return JHylaFAX.getInstance().runJob(SendDialog.this, ioJob); } catch (UserAbortException e) { return null; } catch (Exception e) { logger.debug("Error previewing cover", e); ErrorDialog.showError(this, i18n.tr("Could not preview cover"), i18n.tr("JHylaFAX Error"), e); return null; } } public void updateLabels() { super.updateLabels(); setTitle(i18n.tr("Send Fax")); documentLabel.setText(i18n.tr("Document")); includeCoverLabel.setText(i18n.tr("Include Cover")); coverSenderLabel.setText(i18n.tr("Sender")); coverRecepientLabel.setText(i18n.tr("Recepient")); coverSubjectLabel.setText(i18n.tr("Subject")); coverCommentLabel.setText(i18n.tr("Comment")); previewCoverAction.updateLabels(); moreDocumentsAction.updateLabels(); } public void setDocument(String document) { documentFileChooserPanels.get(0).getTextField().setText(document); } /** * A container used for parameter passing. */ private class Fax { FaxCover cover; InputStream coverIn; List<File> documents = new ArrayList<File>(); } private class PreviewCoverAction extends AbstractXNapAction implements LocaleChangeListener { public PreviewCoverAction() { //putValue(ICON_FILENAME, "configure.png"); } public void actionPerformed(ActionEvent event) { if (!includeCoverCheckBox.isSelected()) { throw new IllegalStateException("Cover page is not enabled"); } String viewerPath = JHylaFAXHelper.getViewerPath("docq"); if (viewerPath == null) { return; } Fax fax = createFax(); if (fax == null) { return; } File tempFile = saveCover(fax); if (tempFile != null) { JHylaFAXHelper.view(viewerPath, new File[] { tempFile }); } } public void updateLabels() { putValue(Action.NAME, i18n.tr("Preview Cover")); putValue(Action.SHORT_DESCRIPTION, i18n.tr("Opens an external programm to preview the cover page")); } } private class MoreDocumentsAction extends AbstractXNapAction implements LocaleChangeListener { public MoreDocumentsAction() { } public void actionPerformed(ActionEvent event) { FileChooserPanel documentFileChooserPanel = addDocumentFileChooser(); documentFileChooserPanel.getTextField().requestFocus(); } public void updateLabels() { putValue(Action.NAME, i18n.tr("More")); putValue(Action.SHORT_DESCRIPTION, i18n.tr("Displays an additional field to enter a document filename")); } } private class MyFileChooserPanel extends FileChooserPanel { public MyFileChooserPanel(int columns) { super(columns); } @Override protected void fileSelected(File file) { File[] files = getFileChooser().getSelectedFiles(); if (files != null && files.length > 1) { // files[0] equals file and is handled by the panel for (int i = 1; i < files.length; i++) { // add a new panel for all other files FileChooserPanel chooser = addDocumentFileChooser(); chooser.setFile(files[i]); } } // reset selection getFileChooser().setSelectedFiles(null); } } protected FileChooserPanel addDocumentFileChooser() { FileChooserPanel documentFileChooserPanel = new MyFileChooserPanel(DEFAULT_COLUMNS); documentFileChooserPanel.setFileChooser(documentFileChooserPanels.get(0).getFileChooser()); documentFileChooserPanels.add(documentFileChooserPanel); documentPanelBuilder.append("", documentFileChooserPanel); documentPanelBuilder.nextLine(); pack(); return documentFileChooserPanel; } public void addDocument(String filename) { FileChooserPanel panel = addDocumentFileChooser(); panel.getTextField().setText(filename); } public void setQuitAfterSending(boolean quitAfterSending) { this.quitAfterSending = quitAfterSending; } }