/**
* Copyright 2011 Juan Gabriel Carrera Otero
*
* 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.apache.org/licenses/LICENSE-2.0
*
* 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 net.xan.taskstack;
import java.awt.Color;
import java.awt.Component;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Stack;
import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import net.xan.easyjtable.EnumComboBox;
import net.xan.easyjtable.GenericClassTableModel;
import org.jdesktop.application.Action;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.TaskMonitor;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;
/**
* The application's main frame.
*/
public class TaskStackView extends FrameView {
private static boolean saved;
protected AutoRecalculateThread autoRecalculateThread;
@SuppressWarnings("serial")
public TaskStackView(SingleFrameApplication app) throws InstantiationException, IllegalAccessException {
super(app);
stack = new TaskStack();
initComponents();
asignationsTable.setDefaultRenderer(DateTime.class, new TSTimeCellRender());
asignationsTable.setDefaultRenderer(Duration.class, new TSDurationCellRender());
tasksTable.setDefaultRenderer(DateTime.class, new TSTimeCellRender());
tasksTable.setDefaultRenderer(Duration.class, new TSDurationCellRender());
tasksTable.setDefaultEditor(TaskState.class, new DefaultCellEditor(new EnumComboBox<TaskState>(TaskState.class)));
tasksTable.setDefaultRenderer(TaskState.class, new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (this.getText().equals(TaskState.Closed.toString()))
this.setBackground(Color.decode("#BDFFBD"));
else if (this.getText().equals(TaskState.Stalled.toString()))
this.setBackground(Color.decode("#FFFFBD"));
else if (this.getText().equals(TaskState.Running.toString()))
this.setBackground(Color.decode("#FFBDBD"));
this.setOpaque(true);
return this;
}
});
tasksTable.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
new Thread() {
@Override
public void run() {
super.run();
createBackupFile();
}
}.start();
}
});
tasksTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@SuppressWarnings("unchecked")
@Override
public void valueChanged(ListSelectionEvent e) {
int selectedRow = tasksTable.getSelectedRow();
if (selectedRow >= 0) {
TaskStackTableModel taskStackTableModel = (TaskStackTableModel) tasksTable.getModel();
ArrayList<Interval> asignations = taskStackTableModel.getValueAt(selectedRow).getAsignations();
ArrayList<IntervalAdapter> newasignations = new ArrayList<IntervalAdapter>();
for (Interval i : asignations) {
newasignations.add(new IntervalAdapter(i));
}
((GenericClassTableModel<IntervalAdapter, ArrayList<IntervalAdapter>>) (asignationsTable.getModel())).setData(newasignations);
} else {
((GenericClassTableModel<IntervalAdapter, ArrayList<IntervalAdapter>>) (asignationsTable.getModel())).clear();
}
}
});
jTextField1.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
push();
}
}
});
// status bar initialization - message timeout, idle icon and busy
// animation, etc
ResourceMap resourceMap = getResourceMap();
int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
messageTimer = new Timer(messageTimeout, new ActionListener() {
public void actionPerformed(ActionEvent e) {
statusMessageLabel.setText("");
}
});
messageTimer.setRepeats(false);
int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
for (int i = 0; i < busyIcons.length; i++) {
busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
}
busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
public void actionPerformed(ActionEvent e) {
busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
}
});
idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
statusAnimationLabel.setIcon(idleIcon);
progressBar.setVisible(false);
// connecting action tasks to status bar via TaskMonitor
TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if ("started".equals(propertyName)) {
if (!busyIconTimer.isRunning()) {
statusAnimationLabel.setIcon(busyIcons[0]);
busyIconIndex = 0;
busyIconTimer.start();
}
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
} else if ("done".equals(propertyName)) {
busyIconTimer.stop();
statusAnimationLabel.setIcon(idleIcon);
progressBar.setVisible(false);
progressBar.setValue(0);
} else if ("message".equals(propertyName)) {
String text = (String) (evt.getNewValue());
statusMessageLabel.setText((text == null) ? "" : text);
messageTimer.restart();
} else if ("progress".equals(propertyName)) {
int value = (Integer) (evt.getNewValue());
progressBar.setVisible(true);
progressBar.setIndeterminate(false);
progressBar.setValue(value);
}
}
});
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource("resources/tslogo.png"));
getFrame().setIconImage(img);
loadBackup(true);
setAutoRecalculate(1000);
}
/**
* This method is called from within the constructor to initialize the form.
*
* @throws IllegalAccessException
* @throws InstantiationException
*/
private void initComponents() throws InstantiationException, IllegalAccessException {
mainPanel = new javax.swing.JPanel();
jToolBar1 = new javax.swing.JToolBar();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
setActiveButton = new JButton();
jButton4 = new javax.swing.JButton();
jButton5 = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
jScrollPane3 = new javax.swing.JScrollPane();
jSplitPane1 = new JSplitPane();
tasksTable = new javax.swing.JTable();
asignationsTable = new javax.swing.JTable();
newTaskLabel = new JLabel();
jTextField1 = new javax.swing.JTextField();
menuBar = new javax.swing.JMenuBar();
javax.swing.JMenu fileMenu = new javax.swing.JMenu();
javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenuItem saveMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenuItem clearMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenuItem loadMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenuItem logMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenu helpMenu = new javax.swing.JMenu();
javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
statusPanel = new javax.swing.JPanel();
javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
statusMessageLabel = new javax.swing.JLabel();
statusAnimationLabel = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
mainPanel.setName("mainPanel"); // NOI18N
jToolBar1.setRollover(true);
jToolBar1.setName("jToolBar1"); // NOI18N
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(net.xan.taskstack.TaskStackApp.class).getContext().getActionMap(TaskStackView.class, this);
jButton1.setAction(actionMap.get("push")); // NOI18N
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(net.xan.taskstack.TaskStackApp.class).getContext().getResourceMap(TaskStackView.class);
jButton1.setText(resourceMap.getString("pushButton.text")); // NOI18N
jButton1.setToolTipText(resourceMap.getString("pushButton.toolTipText")); // NOI18N
jButton1.setFocusable(false);
jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton1.setName("pushButton"); // NOI18N
jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToolBar1.add(jButton1);
jButton1.getAccessibleContext().setAccessibleName(resourceMap.getString("jButton1.AccessibleContext.accessibleName")); // NOI18N
jButton1.getAccessibleContext().setAccessibleDescription(resourceMap.getString("jButton1.AccessibleContext.accessibleDescription")); // NOI18N
jButton2.setAction(actionMap.get("pop")); // NOI18N
jButton2.setText(resourceMap.getString("popButton.text")); // NOI18N
jButton2.setToolTipText(resourceMap.getString("popButton.toolTipText")); // NOI18N
jButton2.setFocusable(false);
jButton2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton2.setName("popButton"); // NOI18N
jButton2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToolBar1.add(jButton2);
jButton2.getAccessibleContext().setAccessibleName(resourceMap.getString("jButton2.AccessibleContext.accessibleName")); // NOI18N
jButton2.getAccessibleContext().setAccessibleDescription(resourceMap.getString("jButton2.AccessibleContext.accessibleDescription")); // NOI18N
setActiveButton.setAction(actionMap.get("setActive"));
setActiveButton.setText(resourceMap.getString("setActiveButton.text"));
setActiveButton.setToolTipText(resourceMap.getString("setActiveButton.toolTipText"));
setActiveButton.setFocusable(false);
setActiveButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
setActiveButton.setText(resourceMap.getString("setActiveButton.label"));
setActiveButton.setName("setActiveButton");
setActiveButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToolBar1.add(setActiveButton);
setActiveButton.getAccessibleContext().setAccessibleName(resourceMap.getString("setActiveButton.AccessibleContext.accessibleName"));
setActiveButton.getAccessibleContext().setAccessibleDescription(resourceMap.getString("setActiveButton.AccessibleContext.accessibleDescription"));
jButton3.setAction(actionMap.get("close"));
jButton3.setText(resourceMap.getString("buttonComplete.text"));
jButton3.setToolTipText(resourceMap.getString("buttonComplete.toolTipText"));
jButton3.setFocusable(false);
jButton3.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton3.setText(resourceMap.getString("buttonComplete.label")); // NOI18N
jButton3.setName("buttonComplete"); // NOI18N
jButton3.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToolBar1.add(jButton3);
jButton3.getAccessibleContext().setAccessibleName(resourceMap.getString("jButton3.AccessibleContext.accessibleName")); // NOI18N
jButton3.getAccessibleContext().setAccessibleDescription(resourceMap.getString("jButton3.AccessibleContext.accessibleDescription")); // NOI18N
jButton4.setAction(actionMap.get("moveUp"));
jButton4.setText(resourceMap.getString("buttonMoveUp.text"));
jButton4.setToolTipText(resourceMap.getString("buttonMoveUp.toolTipText"));
jButton4.setFocusable(false);
jButton4.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton4.setText(resourceMap.getString("buttonMoveUp.label")); // NOI18N
jButton4.setName("buttonMoveUp"); // NOI18N
jButton4.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToolBar1.add(jButton4);
jButton4.getAccessibleContext().setAccessibleName(resourceMap.getString("jButton4.AccessibleContext.accessibleName")); // NOI18N
jButton4.getAccessibleContext().setAccessibleDescription(resourceMap.getString("jButton4.AccessibleContext.accessibleDescription")); // NOI18N
jButton5.setAction(actionMap.get("moveDown"));
jButton5.setText(resourceMap.getString("buttonMoveDown.text"));
jButton5.setToolTipText(resourceMap.getString("buttonMoveDown.toolTipText"));
jButton5.setText(resourceMap.getString("buttonMoveDown.text")); // NOI18N
jButton5.setFocusable(false);
jButton5.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton5.setName("buttonMoveDown"); // NOI18N
jButton5.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToolBar1.add(jButton5);
jButton5.getAccessibleContext().setAccessibleDescription(resourceMap.getString("jButton5.AccessibleContext.accessibleDescription")); // NOI18N
jScrollPane2.setName("jScrollPane2"); // NOI18N
tasksTable.setAutoCreateRowSorter(true);
GenericClassTableModel<Task, Stack<Task>> taskTableModel = new TaskStackTableModel(stack);
tasksTable.setModel(taskTableModel);
tasksTable.setName("jTable1"); // NOI18N
jScrollPane2.setViewportView(tasksTable);
jScrollPane3.setName("jScrollPane3"); // NOI18N
asignationsTable.setAutoCreateRowSorter(true);
GenericClassTableModel<IntervalAdapter, ArrayList<IntervalAdapter>> asignationsTableModel = new AsignationsTableModel(new IntervalList());
asignationsTable.setModel(asignationsTableModel);
asignationsTable.setName("asignationsTable"); // NOI18N
jScrollPane3.setViewportView(asignationsTable);
jSplitPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder());
jSplitPane1.setDividerLocation(200);
jSplitPane1.setDividerSize(10);
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
jSplitPane1.setResizeWeight(1.0);
jSplitPane1.setName("jSplitPane1"); // NOI18N
jSplitPane1.setRightComponent(jScrollPane3);
jSplitPane1.setLeftComponent(jScrollPane2);
newTaskLabel.setText(resourceMap.getString("jLabel1.text"));
newTaskLabel.setName("jLabel1");
jTextField1.setText(resourceMap.getString("taskNameField.text"));
jTextField1.setName("taskNameField");
javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
mainPanel.setLayout(mainPanelLayout);
mainPanelLayout.setHorizontalGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
// .addGroup(
// mainPanelLayout.createSequentialGroup()
// .addContainerGap()
// .addComponent(jToolBar1,
// javax.swing.GroupLayout.DEFAULT_SIZE, 984, Short.MAX_VALUE)
.addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
// .addContainerGap()
// )
.addGroup(
mainPanelLayout.createSequentialGroup().addContainerGap().addComponent(newTaskLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18).addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 960, Short.MAX_VALUE).addContainerGap()
// mainPanelLayout.createSequentialGroup()
// .addContainerGap()
// .addComponent(newTaskLabel,javax.swing.GroupLayout.DEFAULT_SIZE,
// 500, 500)
// .addContainerGap()
// .addComponent(jTextField1,
// javax.swing.GroupLayout.DEFAULT_SIZE, 960, Short.MAX_VALUE)
// .addContainerGap()
).addGroup(mainPanelLayout.createSequentialGroup().addContainerGap().addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 960, Short.MAX_VALUE).addContainerGap())
);
mainPanelLayout.setVerticalGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
mainPanelLayout.createSequentialGroup().addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE).addGap(18, 18, 18)
// .addGroup(
.addGroup(
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(newTaskLabel).addComponent(jTextField1,
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
// mainPanelLayout.createParallelGroup()
// .addComponent(newTaskLabel,javax.swing.GroupLayout.PREFERRED_SIZE,
// javax.swing.GroupLayout.DEFAULT_SIZE,
// javax.swing.GroupLayout.PREFERRED_SIZE)
// .addComponent(jTextField1,
// javax.swing.GroupLayout.PREFERRED_SIZE,
// javax.swing.GroupLayout.DEFAULT_SIZE,
// javax.swing.GroupLayout.PREFERRED_SIZE)
)
.addGap(18, 18, 18).addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE).addContainerGap()));
menuBar.setName("menuBar"); // NOI18N
fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
fileMenu.setName("fileMenu"); // NOI18N
exitMenuItem.setAction(actionMap.get("quit"));
exitMenuItem.setName("exitMenuItem");
saveMenuItem.setAction(actionMap.get("save"));
saveMenuItem.setName("saveMenuItem");
clearMenuItem.setAction(actionMap.get("clear"));
clearMenuItem.setName("clearMenuItem");
loadMenuItem.setAction(actionMap.get("load"));
loadMenuItem.setName("loadMenuItem");
logMenuItem.setAction(actionMap.get("log"));
logMenuItem.setName("logMenuItem");
fileMenu.add(exitMenuItem);
fileMenu.add(clearMenuItem);
fileMenu.add(saveMenuItem);
fileMenu.add(loadMenuItem);
fileMenu.add(logMenuItem);
menuBar.add(fileMenu);
helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
helpMenu.setName("helpMenu"); // NOI18N
aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
aboutMenuItem.setName("aboutMenuItem"); // NOI18N
helpMenu.add(aboutMenuItem);
menuBar.add(helpMenu);
statusPanel.setName("statusPanel"); // NOI18N
statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N
statusMessageLabel.setName("statusMessageLabel"); // NOI18N
statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N
progressBar.setName("progressBar"); // NOI18N
javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
statusPanel.setLayout(statusPanelLayout);
statusPanelLayout.setHorizontalGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE,
984, Short.MAX_VALUE).addGroup(
statusPanelLayout.createSequentialGroup().addContainerGap().addComponent(statusMessageLabel).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 798, Short.MAX_VALUE)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(statusAnimationLabel).addContainerGap()));
statusPanelLayout.setVerticalGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
statusPanelLayout.createSequentialGroup().addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addGroup(
statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(statusMessageLabel).addComponent(statusAnimationLabel).addComponent(progressBar,
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)).addGap(3, 3, 3)));
setComponent(mainPanel);
setMenuBar(menuBar);
setStatusBar(statusPanel);
setToolBar(jToolBar1);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton setActiveButton;
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JTable tasksTable;
private javax.swing.JTable asignationsTable;
private javax.swing.JLabel newTaskLabel;
private javax.swing.JTextField jTextField1;
private javax.swing.JToolBar jToolBar1;
private javax.swing.JPanel mainPanel;
private javax.swing.JMenuBar menuBar;
private javax.swing.JProgressBar progressBar;
private javax.swing.JLabel statusAnimationLabel;
private javax.swing.JLabel statusMessageLabel;
private javax.swing.JPanel statusPanel;
// End of variables declaration//GEN-END:variables
private final Timer messageTimer;
private final Timer busyIconTimer;
private final Icon idleIcon;
private final Icon[] busyIcons = new Icon[15];
private int busyIconIndex = 0;
private JDialog aboutBox;
// TODO : CHECK IF WE NEED TO KEEP THIS REFERENCE OR WE CAN USE ALWASY THE TABLEMODEL REFERENCE
private TaskStack stack;
public TaskStack getStack() {
return stack;
}
public void setStack(TaskStack stack) {
this.stack = stack;
}
@Action
public void push() {
String taskName = jTextField1.getText().trim();
push(taskName);
}
Object[] yesNoOptions = { "Yes", "No" };
@Action
public void clear() {
// final JOptionPane optionPane = new JOptionPane(
// "If you clear the data, it might be unrecoverable.\nDo you still want to clear?",
// JOptionPane.QUESTION_MESSAGE,
// JOptionPane.YES_NO_OPTION);
// boolean answer = 0 == JOptionPane.showOptionDialog(this.getFrame(), "If you clear the data, it might be unrecoverable.\nDo you still want to clear?", "Clear data", JOptionPane.YES_NO_OPTION);
boolean answer = 0 == JOptionPane.showConfirmDialog(this.getFrame(), "If you clear the data, it might be unrecoverable.\nDo you still want to clear?","Clear data",JOptionPane.YES_NO_OPTION);
if (answer) {
((TaskStackTableModel) tasksTable.getModel()).clear();
}
}
public void push(String taskName) {
Task task = new Task(taskName);
TaskStackTableModel model = (TaskStackTableModel) tasksTable.getModel();
model.push(task);
int last = model.getRowCount() - 1;
tasksTable.setRowSelectionInterval(last, last);
}
@Action
public void pop() {
TaskStackTableModel model = (TaskStackTableModel) tasksTable.getModel();
if (model.getRowCount()>0){
model.pop();
int last = model.getRowCount() - 1;
tasksTable.setRowSelectionInterval(last, last);
}
}
@Action
public void close() {
int selectedRow = tasksTable.getSelectedRow();
if (selectedRow >= 0) {
((TaskStackTableModel) tasksTable.getModel()).close(selectedRow);
}
}
@Action
public void setActive() {
int selectedRow = tasksTable.getSelectedRow();
TaskStackTableModel model = (TaskStackTableModel) tasksTable.getModel();
int idx = model.setActive(selectedRow);
}
@Action
public void moveUp() {
int selectedRow = tasksTable.getSelectedRow();
TaskStackTableModel model = (TaskStackTableModel) tasksTable.getModel();
if (selectedRow > 0) {
int idx = model.moveUp(selectedRow);
tasksTable.setRowSelectionInterval(idx, idx);
}
}
@Action
public void moveDown() {
int selectedRow = tasksTable.getSelectedRow();
TaskStackTableModel model = (TaskStackTableModel) tasksTable.getModel();
if (selectedRow <= model.getRowCount() - 1) {
int idx = model.moveDown(selectedRow);
tasksTable.setRowSelectionInterval(idx, idx);
}
}
@Action
public void showAboutBox() {
if (aboutBox == null) {
JFrame mainFrame = TaskStackApp.getApplication().getMainFrame();
aboutBox = new TaskStackAboutBox(mainFrame);
aboutBox.setLocationRelativeTo(mainFrame);
}
TaskStackApp.getApplication().show(aboutBox);
}
@Action
public void save() {
JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
chooser.setSelectedFile(new File(new DateTime().toString("YYYY-MM-dd-HH.mm.ss").concat(".xml")));
if (chooser.showSaveDialog(this.getFrame()) == JFileChooser.APPROVE_OPTION) {
save(chooser.getSelectedFile());
}
}
private void save(File selectedFile) {
try {
XMLEncoder encoder = new XMLEncoder(new FileOutputStream(selectedFile));
encoder.setPersistenceDelegate(Interval.class, new PersistenceDelegate() {
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, oldInstance.getClass(), "new", new Object[] { ((Interval) oldInstance).getStart(), ((Interval) oldInstance).getEnd() });
}
});
encoder.setPersistenceDelegate(Duration.class, new PersistenceDelegate() {
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, oldInstance.getClass(), "new", new Object[] { ((Duration) oldInstance).getMillis() });
}
});
encoder.setPersistenceDelegate(DateTime.class, new PersistenceDelegate() {
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, oldInstance.getClass(), "new", new Object[] { ((DateTime) oldInstance).getMillis() });
}
});
encoder.writeObject(((TaskStackTableModel) tasksTable.getModel()).getData());
encoder.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Object[] appendOptions = { "Append", "Override" };
@Action
public void log() {
JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
chooser.setSelectedFile(new File(new DateTime().toString("YYYY-MM-dd").concat(".log")));
FileWriter fw = null;
if (chooser.showSaveDialog(this.getFrame()) == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
boolean append = file.exists() && choosesAppend();
try {
fw = new FileWriter(file, append);
fw.write(((TaskStack) (((TaskStackTableModel) tasksTable.getModel()).getData())).toLog());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null)
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private boolean choosesAppend() {
return 0 == JOptionPane.showOptionDialog(this.getFrame(), "The selected file already exists. Do you \n" + "want to override the file or to append the \n" + "new information?.\n",
"Append to file?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, appendOptions, appendOptions[0]);
}
@Action
public void load() {
JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
if (chooser.showOpenDialog(this.getFrame()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = chooser.getSelectedFile();
load(selectedFile);
}
}
private void load(File selectedFile) {
try {
XMLDecoder decoder = new XMLDecoder(new FileInputStream(selectedFile));
TaskStack data = (TaskStack) decoder.readObject();
decoder.close();
((TaskStackTableModel) tasksTable.getModel()).setData(data);
this.stack = data;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private void createBackupFile() {
File tempfile = getBackupFile();
save(tempfile);
// for windows
try {
if (System.getProperty("os.name").toLowerCase().contains("win"))
Runtime.getRuntime().exec("attrib +H " + tempfile.getName());
} catch (IOException e) {
e.printStackTrace();
}
}
private File getBackupFile() {
return new File("./.tmp_" + System.getProperty("user.name"));
}
private void loadBackup(Boolean ask) {
File tempfile = getBackupFile();
if (tempfile.exists()) {
if ((!ask || askForLoadBackup())) {
load(tempfile);
}
// tempfile.delete();
}
}
private boolean askForLoadBackup() {
return 0 == JOptionPane.showConfirmDialog(this.getFrame(),
"A backup file has been found. The previous execution\n" +
"of the program might have been closed unexpectedly.\n" +
"\nDo you want to load the content of the backup file?.\n",
"Load backup?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
}
/**
*
*/
public void deleteTemporaryFiles() {
File tempfile = getBackupFile();
if (tempfile.exists())
tempfile.delete();
}
public void setAutoRecalculate(long millis) {
if (0 != millis) {
if (autoRecalculateThread == null) {
autoRecalculateThread = new AutoRecalculateThread();
}
autoRecalculateThread.setRefreshTime(millis);
if (!autoRecalculateThread.isAlive()) {
autoRecalculateThread.start();
}
} else {
if (autoRecalculateThread != null) {
autoRecalculateThread.setRefreshTime(0);
}
}
}
class AutoRecalculateThread extends Thread {
long refreshTime;
void setRefreshTime(long millis) {
refreshTime = millis;
}
@Override
public void run() {
super.run();
while (refreshTime > 0) {
try {
TaskStackTableModel model = (TaskStackTableModel) tasksTable.getModel();
int lastRow = model.getRowCount()-1;
if (lastRow >= 0) {
Task lastTask = model.getValueAt(lastRow);
if (lastTask.getState() == TaskState.Running) {
lastTask.closeCurrentAsignation();
// model.fireTableRowsUpdated(lastRow, lastRow);
// model.fireTableDataChanged();
TableModelEvent event = new TableModelEvent(model, lastRow, lastRow, TableModelEvent.ALL_COLUMNS, TableModelEvent.UPDATE);
model.fireTableDataChanged(event);
}
}
sleep(refreshTime);
} catch (InterruptedException e) {
}
}
System.out.println("Terminating recalculation thread");
}
}
}