package com.framsticks.gui.controls; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.framsticks.core.Path; import com.framsticks.core.SideNoteKey; import com.framsticks.gui.Frame; import com.framsticks.gui.Gui; import com.framsticks.gui.table.AbstractTableModel; import com.framsticks.params.EventListener; import com.framsticks.params.types.EventParam; import com.framsticks.util.FramsticksUnsupportedOperationException; import com.framsticks.util.dispatching.Dispatching; import com.framsticks.util.dispatching.FutureHandler; import com.framsticks.util.dispatching.RunAt; import com.framsticks.util.lang.Pair; import static com.framsticks.core.TreeOperations.*; /** * @author Piotr Sniegowski */ @SuppressWarnings("serial") public class EventControl extends HistoryControl { // private static final Logger log = LogManager.getLogger(EventControl.class.getName()); @SuppressWarnings("rawtypes") protected final SideNoteKey listenerKey = SideNoteKey.make(EventListener.class); public static class History { protected final List> entries = new ArrayList<>(); }; protected final SideNoteKey historyKey = SideNoteKey.make(History.class); protected TableModel tableModel; public EventControl(final EventParam eventParam) { super(eventParam); mainButton.setText("Subscribe"); mainButton.setName("subscription"); tableModel = new TableModel(); resultsTable.setModel(tableModel); mainButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final Path path = assureCurrentPath(); EventListener listener = getSideNote(path, listenerKey); if (listener != null) { removeSideNote(path, listenerKey); refreshState(); path.getTree().removeListener(path, getParam(), listener, FutureHandler.doNothing(Void.class, owner.getFrame())); return; } final EventListener newListener = new EventListener() { @Override public void action(final Object argument) { /** actions can be invoked from anywhere */ Dispatching.dispatchIfNotActive(owner.getFrame(), new RunAt(owner.getFrame()) { @Override protected void runAt() { getOrCreateSideNote(path.getTree(), path.getTopObject(), historyKey).entries.add(Pair.make(new Date(), argument)); refreshTable(); } }); // owner.getFrame().getStatusBar().showInfo("event " + param + " happened: " + argument); } }; path.getTree().addListener(path, getParam(), newListener, Object.class, new FutureHandler(owner.getFrame()) { @Override protected void result(Void result) { putSideNote(path, listenerKey, newListener); refreshState(); } }); } }); updateFoldState(); Gui.setupTitledControl(this, controlRow, resultsScrollPane); } @Override protected void updateEnabled(boolean enabled) { mainButton.setEnabled(enabled); } public boolean isListening() { return hasSideNote(getCurrentPath(), listenerKey); } protected void refreshButtonState() { mainButton.setText(isListening() ? "Don't listen" : "Listen"); } @Override protected void refreshTable() { History history = getSideNote(assureCurrentPath(), historyKey); tableModel.entries = history != null ? history.entries : null; tableModel.refreshAll(); } @Override protected void clearTable() { History history = getSideNote(assureCurrentPath(), historyKey); if (history != null) { history.entries.clear(); } refreshTable(); } public void refreshState() { refreshButtonState(); refreshTable(); } @Override public EventParam getParam() { return (EventParam) param; } public class TableModel extends AbstractTableModel { List> entries; SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss:SSS"); @Override public Class getColumnClass(int columnIndex) { return String.class; } @Override public int getColumnCount() { return 2; } @Override public String getColumnName(int columnIndex) { return columnIndex == 0 ? "Occured at" : "Argument"; } @Override public int getRowCount() { if (entries == null) { return 0; } if (isFolded()) { return entries.isEmpty() ? 0 : 1; } return entries.size(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (entries == null) { return null; } Pair entry; if (isFolded()) { if (rowIndex > 0) { return null; } if (entries.isEmpty()) { return null; } entry = entries.get(entries.size() - 1); } else { entry = entries.get(rowIndex); } return columnIndex == 0 ? format.format(entry.first) : entry.second; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } @Override public void setValueAt(Object value, int rowIndex, int columnIndex) { throw new FramsticksUnsupportedOperationException().msg("setting value in event history"); } } }