package com.inter6.mail.gui.action;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.annotation.PostConstruct;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.inter6.mail.gui.ConfigObserver;
import com.inter6.mail.gui.data.DataPanel;
import com.inter6.mail.gui.tab.TabComponentPanel;
import com.inter6.mail.job.smtp.AbstractSmtpSendJob;
import com.inter6.mail.model.action.ActionData;
import com.inter6.mail.module.AppConfig;
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ActionPanel extends TabComponentPanel implements ConfigObserver {
private static final long serialVersionUID = -1786161460680791823L;
@Autowired
private AppConfig appConfig;
private LogPanel logPanel;
private DataPanel dataPanel;
private final JButton startButton = new JButton("Start");
private final JButton stopButton = new JButton("Stop");
private final JCheckBox useMultiThreadCheckBox = new JCheckBox("Multi-Thread", true);
private final JTextField maxThreadCountField = new JTextField("8", 2);
private final JLabel elapsedTimeLabel = new JLabel("--:--:--");
private final JProgressBar progressBar = new JProgressBar();
private final JLabel progressLabel = new JLabel("0.00 %");
private AbstractSmtpSendJob currentJob;
public ActionPanel(String tabName) {
super(tabName);
}
@PostConstruct
private void init() {
logPanel = tabComponentManager.getTabComponent(tabName, LogPanel.class);
dataPanel = tabComponentManager.getTabComponent(tabName, DataPanel.class);
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel sendPanel = new JPanel(new FlowLayout());
{
sendPanel.add(this.startButton);
sendPanel.add(this.stopButton);
sendPanel.add(this.useMultiThreadCheckBox);
sendPanel.add(new JLabel("Max:"));
sendPanel.add(this.maxThreadCountField);
this.startButton.addActionListener(this.createStartEvent());
this.stopButton.addActionListener(this.createStopEvent());
this.stopButton.setEnabled(false);
}
this.add(sendPanel);
JPanel progressPanel = new JPanel(new BorderLayout());
{
progressPanel.add(this.elapsedTimeLabel, BorderLayout.WEST);
{
this.progressBar.add(new JLabel("12345"));
this.progressBar.setBorder(new EmptyBorder(0, 10, 0, 10));
this.progressBar.setMaximum(100);
}
progressPanel.add(this.progressBar, BorderLayout.CENTER);
progressPanel.add(this.progressLabel, BorderLayout.EAST);
}
this.add(progressPanel);
this.add(this.logPanel);
}
private ActionListener createStartEvent() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
try {
ActionPanel.this.currentJob = dataPanel.getSendJob();
new Thread(ActionPanel.this.currentJob).start();
} catch (Throwable e) {
ActionPanel.this.logPanel.error("job build fail !", e);
}
}
};
}
private ActionListener createStopEvent() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
if (ActionPanel.this.currentJob == null) {
return;
}
try {
ActionPanel.this.currentJob.terminate();
ActionPanel.this.logPanel.info("request job terminate. wating...");
} catch (Throwable e) {
ActionPanel.this.logPanel.error("job terminate fail !", e);
}
}
};
}
public void onStart(AbstractSmtpSendJob abstractSmtpSendJob, long startTime) {
if (currentJob != abstractSmtpSendJob) {
return;
}
this.elapsedTimeLabel.setText("0:0:0");
this.progressBar.setValue(0);
this.progressLabel.setText("0.00 %");
this.useMultiThreadCheckBox.setEnabled(false);
this.maxThreadCountField.setEnabled(false);
ActionPanel.this.startButton.setEnabled(false);
ActionPanel.this.stopButton.setEnabled(true);
}
public void onDone(AbstractSmtpSendJob abstractSmtpSendJob, long startTime, long elapsedTime) {
if (currentJob != abstractSmtpSendJob) {
return;
}
this.currentJob = null;
this.elapsedTimeLabel.setText(this.formatElapsedTime(elapsedTime));
this.progressBar.setValue(100);
this.progressLabel.setText("100.00 %");
this.useMultiThreadCheckBox.setEnabled(true);
this.maxThreadCountField.setEnabled(true);
ActionPanel.this.startButton.setEnabled(true);
ActionPanel.this.stopButton.setEnabled(false);
}
public void onProgress(AbstractSmtpSendJob abstractSmtpSendJob, float progressRate, long startTime, long currentTime) {
if (currentJob != abstractSmtpSendJob) {
return;
}
this.elapsedTimeLabel.setText(this.formatElapsedTime(currentTime - startTime));
// 끝나기 전까지는 99%로 보여준다.
float validRate = progressRate >= 100 ? 99 : progressRate;
this.progressBar.setValue((int) validRate);
this.progressLabel.setText(String.format("%.2f", validRate) + " %");
}
private String formatElapsedTime(long elapsedTime) {
long elapsedSec = elapsedTime / 1000;
long s = elapsedSec % 60;
elapsedSec /= 60;
long m = elapsedSec % 60;
long h = elapsedSec / 60;
return h + ":" + m + ":" + s;
}
public ActionData getActionData() {
ActionData actionData = new ActionData();
actionData.setUseMultiThread(this.useMultiThreadCheckBox.isSelected());
actionData.setMaxThreadCount(Integer.parseInt(this.maxThreadCountField.getText()));
return actionData;
}
@Override
public void loadConfig() {
ActionData actionData = new Gson().fromJson(this.appConfig.getString(tabName + ".action.data"), ActionData.class);
if (actionData == null) {
return;
}
this.useMultiThreadCheckBox.setSelected(actionData.isUseMultiThread());
this.maxThreadCountField.setText(actionData.getMaxThreadCount() + "");
}
@Override
public void updateConfig() {
this.appConfig.setProperty(tabName + ".action.data", new Gson().toJson(this.getActionData()));
}
}