📄 indicatorscannerjpanel.java
字号:
if(indicator.isTriggered()) {
addIndicatorToTable(indicator);
alert(indicator);
}
else {
removeIndicatorFromTable(indicator);
}
}
}
else
{
// Multiple indicators alert.
boolean alert = true;
for(OperatorIndicator indicator : indicators) {
indicator.setStock(stock);
if(indicator.isTriggered() == false) {
alert = false;
break;
}
}
if(alert) {
for(OperatorIndicator indicator : indicators) {
addIndicatorToTable(indicator);
alert(indicator);
}
}
else {
for(OperatorIndicator indicator : indicators) {
removeIndicatorFromTable(indicator);
}
}
}
}
}
// Should we synchronized the jTable1, or post the job at GUI event dispatch
// queue?
private void addIndicatorToTable(final Indicator indicator) {
final Runnable r = new Runnable() {
public void run() {
IndicatorTableModel tableModel = (IndicatorTableModel)jTable1.getModel();
// Dirty way to prevent background thread from showing indicators
// on the table.
if(allowIndicatorShown)
tableModel.addIndicator(indicator);
}
};
SwingUtilities.invokeLater(r);
}
private void removeIndicatorFromTable(final Indicator indicator) {
final Runnable r = new Runnable() {
public void run() {
IndicatorTableModel tableModel = (IndicatorTableModel)jTable1.getModel();
tableModel.removeIndicator(indicator);
}
};
SwingUtilities.invokeLater(r);
}
private void removeAllIndicatorsFromTable() {
final Runnable r = new Runnable() {
public void run() {
IndicatorTableModel tableModel = (IndicatorTableModel)jTable1.getModel();
tableModel.removeAll();
}
};
SwingUtilities.invokeLater(r);
}
private class TableRowPopupListener extends MouseAdapter {
public void mouseClicked(MouseEvent evt) {
}
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
if(jTable1.getSelectedColumn() != -1)
getMyJTablePopupMenu().show(e.getComponent(), e.getX(), e.getY());
}
}
}
private ImageIcon getImageIcon(String imageIcon) {
return new javax.swing.ImageIcon(getClass().getResource(imageIcon));
}
private JPopupMenu getMyJTablePopupMenu() {
JPopupMenu popup = new JPopupMenu();
TableModel tableModel = jTable1.getModel();
final MainFrame m = getMainFrame();
javax.swing.JMenuItem menuItem = new JMenuItem("History...", this.getImageIcon("/images/16x16/strokedocker.png"));
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
int rows[] = jTable1.getSelectedRows();
final IndicatorTableModel tableModel = (IndicatorTableModel)jTable1.getModel();
for(int row : rows) {
final int modelIndex = jTable1.convertRowIndexToModel(row);
final Indicator indicator = tableModel.getIndicator(modelIndex);
if(indicator != null)
m.displayHistoryChart(indicator.getStock());
}
}
});
popup.add(menuItem);
popup.add(menuItem);
return popup;
}
private String getIndicatorKey(Indicator indicator) {
// Stock shouldn't be null.
assert(indicator.getStock() != null);
return indicator.toString() + indicator.getStock().getCode();
}
private void alert(final Indicator indicator) {
final MainFrame m = getMainFrame();
final JStockOptions jStockOptions = MainFrame.getJStockOptions();
synchronized(alertRecords) {
if(jStockOptions.isSingleIndicatorAlert() == true) {
final String key = getIndicatorKey(indicator);
if(alertRecords.contains(key)) return;
alertRecords.add(key);
}
else {
/* When performing multiple indicators alert, we will only display once for a same stock. */
final String code = indicator.getStock().getCode().toString();
if(alertRecords.contains(code)) return;
alertRecords.add(code);
}
}
if(jStockOptions.isPopupMessage()) {
final Runnable r = new Runnable() {
public void run() {
final Stock stock = indicator.getStock();
final String message = stock.getSymbol() + " (" + stock.getCode() + " " +
"last=" + stock.getLastPrice() + " high=" + stock.getHighPrice() + " " +
"low=" + stock.getLowPrice() + ") hits " + indicator.toString();
if (jStockOptions.isPopupMessage()) {
m.displayPopupMessage(stock.getSymbol().toString(), message);
try {
Thread.sleep(jStockOptions.getAlertSpeed() * 1000);
}
catch(InterruptedException exp) {
log.error("", exp);
}
}
}
};
try {
systemTrayAlertPool.submit(r);
}
catch(java.util.concurrent.RejectedExecutionException exp) {
log.error("", exp);
}
}
if(jStockOptions.isSendEmail()) {
final Runnable r = new Runnable() {
public void run() {
final Stock stock = indicator.getStock();
final String title = stock.getSymbol() + " (" + stock.getCode() + " " +
"last=" + stock.getLastPrice() + " high=" + stock.getHighPrice() + " " +
"low=" + stock.getLowPrice() + ") hits " + indicator.toString();
final String message = title + "\nbrought to you by JStock";
try {
String email = Utils.decrypt(jStockOptions.getEmail());
GoogleMail.Send(email, Utils.decrypt(jStockOptions.getEmailPassword()), email + "@gmail.com", message, message);
} catch (AddressException exp) {
log.error("", exp);
} catch (MessagingException exp) {
log.error("", exp);
}
}
};
try {
emailAlertPool.submit(r);
}
catch(java.util.concurrent.RejectedExecutionException exp) {
log.error("", exp);
}
}
}
private MainFrame getMainFrame()
{
if (mainFrame == null)
{
mainFrame = MainFrame.getMe();
}
return mainFrame;
}
public void repaintTable() {
jTable1.repaint();
}
public void clearTableSelection() {
jTable1.getSelectionModel().clearSelection();
}
private Thread getStartScanThread(final WizardModel wizardModel, final MainFrame mainFrame)
{
return new Thread(new Runnable() {
@Override
public void run() {
WizardPanelDescriptor wizardPanelDescriptor0 = wizardModel.getPanelDescriptor(WizardSelectStockDescriptor.IDENTIFIER);
WizardSelectStockJPanel wizardSelectStockJPanel = (WizardSelectStockJPanel)wizardPanelDescriptor0.getPanelComponent();
if(wizardSelectStockJPanel.buildSelectedCode() == false) {
// Unlikely.
log.error("Fail to build selected stock");
return;
}
initRealTimeStockMonitor(mainFrame.getStockServerFactory());
initStockHistoryMonitor(mainFrame.getStockServerFactory());
removeAllIndicatorsFromTable();
alertRecords.clear();
initOperatorIndicators(wizardModel);
submitOperatorIndicatorToMonitor();
}
});
}
private Wizard wizard;
private RealTimeStockMonitor realTimeStockMonitor;
private org.yccheok.jstock.engine.Observer<RealTimeStockMonitor, java.util.List<Stock>> realTimeStockMonitorObserver = this.getRealTimeStockMonitorObserver();
private java.util.Map<Code, java.util.List<OperatorIndicator>> operatorIndicators = new java.util.concurrent.ConcurrentHashMap<Code, java.util.List<OperatorIndicator>>();
private java.util.List<String> alertRecords = new java.util.ArrayList<String>();
private ExecutorService emailAlertPool = Executors.newFixedThreadPool(1);
private ExecutorService systemTrayAlertPool = Executors.newFixedThreadPool(1);
private MainFrame mainFrame = null;
private org.yccheok.jstock.engine.Observer<StockHistoryMonitor, StockHistoryMonitor.StockHistoryRunnable> stockHistoryMonitorObserver = this.getStockHistoryMonitorObserver();
private StockHistoryMonitor stockHistoryMonitor = null;
// Dirty flag to be used with clear method and start button method.
// Ensure we have an instant way to prevent background thread from showing
// indicators on the table, after we call clear method.
// This is a dirty way, but it just work :)
private volatile Boolean allowIndicatorShown = true;
private Thread startScanThread = null;
private static final Log log = LogFactory.getLog(IndicatorScannerJPanel.class);
private static final int NUM_OF_THREADS_HISTORY_MONITOR = 4;
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration//GEN-END:variables
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -