Java tutorial
/* * JStock - Free Stock Market Software * Copyright (C) 2009 Yan Cheng Cheok <yccheok@yahoo.com> * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.yccheok.jstock.gui.analysis; import java.awt.Color; import java.awt.Cursor; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Observer; import javax.swing.Icon; import javax.swing.SwingWorker; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.yccheok.jstock.gui.Icons; import org.yccheok.jstock.gui.IndicatorProjectManager; import org.yccheok.jstock.gui.JStock; import org.yccheok.jstock.gui.Utils; import org.yccheok.jstock.internationalization.GUIBundle; /** * * @author yccheok */ public class WizardDownloadIndicatorJPanel extends javax.swing.JPanel { /** Creates new form WizardDownloadIndicatorJPanel */ public WizardDownloadIndicatorJPanel(IndicatorProjectManager indicatorProjectManager) { this.indicatorProjectManager = indicatorProjectManager; initComponents(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jXHeader1 = new org.jdesktop.swingx.JXHeader(); jPanel1 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); setLayout(new java.awt.BorderLayout()); java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/yccheok/jstock/data/gui"); // NOI18N jXHeader1.setDescription(bundle.getString("WizardDownloadlIndicatorJPanel_Description")); // NOI18N jXHeader1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/32x32/ark2.png"))); // NOI18N jXHeader1.setTitle(bundle.getString("WizardDownloadlIndicatorJPanel_Title")); // NOI18N add(jXHeader1, java.awt.BorderLayout.NORTH); jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); jLabel1.setForeground(new java.awt.Color(0, 0, 255)); jLabel1.setText(bundle.getString("WizardDownloadlIndicatorJPanel_DownloadingIndicators...")); // NOI18N jLabel1.setForeground(Color.BLUE); jPanel1.add(jLabel1); jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/16x16/spinner.gif"))); // NOI18N jPanel1.add(jLabel2); jLabel3.setText(bundle.getString("WizardDownloadlIndicatorJPanel_ViewLog")); // NOI18N this.jLabel3.setVisible(false); jLabel3.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { jLabel3MouseClicked(evt); } public void mouseEntered(java.awt.event.MouseEvent evt) { jLabel3MouseEntered(evt); } public void mouseExited(java.awt.event.MouseEvent evt) { jLabel3MouseExited(evt); } }); jPanel1.add(jLabel3); add(jPanel1, java.awt.BorderLayout.CENTER); }// </editor-fold>//GEN-END:initComponents private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel3MouseClicked MemoryLogJDialog memoryLogJDialog = new MemoryLogJDialog(JStock.instance(), true); memoryLogJDialog.setLocationRelativeTo(this); memoryLogJDialog.setLog(memoryLog); memoryLogJDialog.setVisible(true); }//GEN-LAST:event_jLabel3MouseClicked private void jLabel3MouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel3MouseEntered this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); }//GEN-LAST:event_jLabel3MouseEntered private void jLabel3MouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel3MouseExited this.setCursor(Cursor.getDefaultCursor()); }//GEN-LAST:event_jLabel3MouseExited public void start() { if (this.downloadIndicatorTask == null) { this.downloadIndicatorTask = this.getDownloadIndicatorTask(); this.downloadIndicatorTask.execute(); } } public void cancel() { if (this.downloadIndicatorTask != null) { this.downloadIndicatorTask.cancel(true); } this.downloadIndicatorTask = null; } public boolean isNextFinishButtonEnabled() { if (this.downloadIndicatorTask == null) { return false; } return this.downloadIndicatorTask.isDone(); } public void setIndicatorDownloadInfos(List<IndicatorDownloadManager.Info> indicatorDownloadInfos) { this.indicatorDownloadInfos = indicatorDownloadInfos; } private static class Status { public final String message; public final Icon icon; private Status(String message, Icon icon) { if (message == null || icon == null) { throw new IllegalArgumentException("Method arguments cannot be null"); } this.message = message; this.icon = icon; } public static Status newInstance(String message, Icon icon) { return new Status(message, icon); } } private SwingWorker<Void, Status> getDownloadIndicatorTask() { SwingWorker<Void, Status> worker = new SwingWorker<Void, Status>() { @Override protected void done() { // Inform wizard. WizardDownloadIndicatorJPanel.this.observable.setChanged(); WizardDownloadIndicatorJPanel.this.observable.notifyObservers(); } @Override protected void process(java.util.List<Status> statuses) { for (Status status : statuses) { writeToMemoryLog(status.message); jLabel1.setText(status.message); jLabel2.setIcon(status.icon); if (status.icon == Icons.ERROR || status.icon == Icons.WARNING) { jLabel1.setForeground(Color.RED); jLabel3.setVisible(true); } else { jLabel1.setForeground(Color.BLUE); jLabel3.setVisible(false); } } } @Override protected Void doInBackground() { if (isCancelled()) { return null; } memoryLog.clear(); final int expected = indicatorDownloadInfos.size(); int actual = 0; for (IndicatorDownloadManager.Info info : indicatorDownloadInfos) { final String message0 = MessageFormat.format( GUIBundle.getString("WizardDownloadlIndicatorJPanel_DownloadingIndicator_template..."), info.projectName); publish(Status.newInstance(message0, Icons.BUSY)); final File temp = Utils.downloadAsTempFile(info.fileURL.toString()); if (temp == null) { final String fail_message0 = MessageFormat.format( GUIBundle .getString("WizardDownloadlIndicatorJPanel_DownloadIndicatorFail_template"), info.projectName); publish(Status.newInstance(fail_message0, Icons.BUSY)); continue; } // Check for zipfile check sum. final String message1 = MessageFormat.format( GUIBundle.getString("WizardDownloadlIndicatorJPanel_CheckingCheckSum_template..."), info.projectName); publish(Status.newInstance(message1, Icons.BUSY)); final long checksum = org.yccheok.jstock.analysis.Utils.getChecksum(temp); if (checksum != info.checksum) { final String fail_message1 = MessageFormat.format( GUIBundle.getString("WizardDownloadlIndicatorJPanel_CheckCheckSumFail_template"), info.projectName); publish(Status.newInstance(fail_message1, Icons.BUSY)); continue; } if (isCancelled()) { // Early return. return null; } // Install. final String message2 = MessageFormat.format( GUIBundle.getString("WizardDownloadlIndicatorJPanel_InstallingIndicator_template..."), info.projectName); publish(Status.newInstance(message2, Icons.BUSY)); if (indicatorProjectManager.install(temp)) { actual++; } else { final String fail_message2 = MessageFormat.format( GUIBundle.getString("WizardDownloadlIndicatorJPanel_InstallIndicatorFail_template"), info.projectName); publish(Status.newInstance(fail_message2, Icons.BUSY)); } } final String message = MessageFormat.format( GUIBundle.getString( "WizardDownloadlIndicatorJPanel_NOutOfMIndicatorsInstalledSuccessfully_template"), actual, expected); if (actual == expected) { publish(Status.newInstance(message, Icons.OK)); } else { if (actual > 0) { publish(Status.newInstance(message, Icons.WARNING)); } else { publish(Status.newInstance(message, Icons.ERROR)); } } return null; } }; return worker; } public void addObserver(Observer o) { observable.addObserver(o); } private void writeToMemoryLog(String message) { // http://www.leepoint.net/notes-java/io/10file/sys-indep-newline.html // public static String newline = System.getProperty("line.separator"); // When NOT to use the system independent newline characters // JTextArea lines should be separated by a single '\n' character, not the sequence that is used for file line separators in the operating system. // Console output (eg, System.out.println()), works fine with '\n', even on Windows. final DateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a"); final String s = dateFormat.format(new Date()) + "\n" + message; this.memoryLog.add(s); } private volatile SwingWorker<Void, Status> downloadIndicatorTask = null; private final IndicatorProjectManager indicatorProjectManager; private List<IndicatorDownloadManager.Info> indicatorDownloadInfos; // setChanged must be called, before calling notifyObservers. // Cumbersome! Perhaps we still should stick back with our own Subject // Observer framework. private static final class ObservableEx extends java.util.Observable { @Override public void setChanged() { super.setChanged(); } } private final ObservableEx observable = new ObservableEx(); private static final Log log = LogFactory.getLog(WizardDownloadIndicatorJPanel.class); private final List<String> memoryLog = new ArrayList<String>(); // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JPanel jPanel1; private org.jdesktop.swingx.JXHeader jXHeader1; // End of variables declaration//GEN-END:variables }