Posts for the month of April 2006

Switch to GPL license?

I'm thinking to switch the license of BlogTrader Platform from BSD to GPL.

Making the license under GPL will encourage the contributors (include me) to release more source code to public, and means compatible to GPLed softwares that may be integrated into this project, such as: Sleepycat's Berkeley DB.

Of course, the source code that had been released will remain under BSD license, but I will not update it any more.

How to add a dropdown menu to toolbar in NetBeans Platform

To add a dropdown menu to toolbar, you should extends CallableSystemAction and override method: public Component getToolbarPresenter()

Dropdown menu should be banded with a JToggleButton, when JToggleButton is pressed down, show a JPopupMenu on JToggleButton.

Example:

public class PickDrawingLineAction extends CallableSystemAction {
    private static JToggleButton toggleButton;
    private static ButtonGroup buttonGroup;
    private static JPopupMenu popup;
    private MyMenuItemListener menuItemListener;
    
    List<AbstractHandledChart> handledCharts;
    
    public PickDrawingLineAction() {
    }
    
    
    public void performAction() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                toggleButton.setSelected(true);
            }
        });
        
    }
    
    public String getName() {
        return "Pick Drawing Line";
    }
    
    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }
    
    protected boolean asynchronous() {
        return false;
    }
    
    public Component getToolbarPresenter() {
        Image iconImage = Utilities.loadImage(
            "org/blogtrader/platform/core/netbeans/
             resources/drawingLine.png");
        ImageIcon icon = new ImageIcon(iconImage);
        
        toggleButton = new JToggleButton();
        
        toggleButton.setIcon(icon);
        toggleButton.setToolTipText("Pick Drawing Line");
        
        popup = new JPopupMenu();
        menuItemListener = new MyMenuItemListener();
        
        handledCharts = PersistenceManager.getDefalut()
                        .getAllAvailableHandledChart();
        
        buttonGroup = new ButtonGroup();
        
        for (AbstractHandledChart handledChart : handledCharts) {
            JRadioButtonMenuItem item = 
                new JRadioButtonMenuItem(handledChart.toString());
            item.addActionListener(menuItemListener);
            buttonGroup.add(item);
            popup.add(item);
        }
        
        toggleButton.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                int state = e.getStateChange();
                if (state == ItemEvent.SELECTED) {
                    // show popup menu on toggleButton at position:(0, height)
                    popup.show(toggleButton, 0, toggleButton.getHeight());
                }
            }
        });
        
        popup.addPopupMenuListener(new PopupMenuListener() {
            public void popupMenuCanceled(PopupMenuEvent e) {
                toggleButton.setSelected(false);
            }
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                toggleButton.setSelected(false);
            }
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }
        });
        
        
        return toggleButton;
    }
    
    private class MyMenuItemListener implements ActionListener {
        public void actionPerformed(ActionEvent ev) {
            JMenuItem item = (JMenuItem)ev.getSource();
            String selectedStr = item.getText();
            
            AnalysisChartTopComponent analysisTc =
                AnalysisChartTopComponent.getSelected();
            
            if (analysisTc == null) {
                return;
            }
            
            AbstractChartViewContainer viewContainer = 
                analysisTc.getSelectedViewContainer();
            AbstractChartView masterView = viewContainer.getMasterView();
            if (!(masterView instanceof WithDrawingPart)) {
                return;
            }
            
            DrawingPart drawingPart = 
                ((WithDrawingPart)masterView).getCurrentDrawing();
            
            if (drawingPart == null) {
                JOptionPane.showMessageDialog(
                        WindowManager.getDefault().getMainWindow(),
                        "Please add a layer firstly to pick line type",
                        "Pick line type",
                        JOptionPane.OK_OPTION,
                        null);
                return;
            }
            
            AbstractHandledChart selectedHandledChart = null;
            
            for (AbstractHandledChart handledChart : handledCharts) {
                if (handledChart.toString().equalsIgnoreCase(selectedStr)) {
                    selectedHandledChart = handledChart;
                    break;
                }
            }
            
            if (selectedHandledChart == null) {
                return;
            }
            
            AbstractHandledChart handledChart = 
                selectedHandledChart.createNewInstance();
            handledChart.setPart(drawingPart);
            drawingPart.setHandledChart(handledChart);
            
            Series masterSeries = viewContainer.getMasterSeries();
            DrawingDescriptor description = 
                viewContainer.getDescriptors().findDrawingDescriptor(
                    drawingPart.getLayerName(),
                    masterSeries.getUnit(),
                    masterSeries.getNUnits());
            
            if (description != null) {
                Node stockNode = analysisTc.getActivatedNodes()[0];
                Node node = 
                    stockNode.getChildren()
                        .findChild(DescriptorGroupNode.DRAWINGS)
                        .getChildren().findChild(description.getDisplayName());
                
                if (node != null) {
                    ViewAction action = 
                        (ViewAction)node.getLookup().lookup(ViewAction.class);
                    assert action != null : 
                        "view action of this layer's node is null!";
                    action.view();
                }
            } else {
                /** best effort, should not happen */
                viewContainer.setCursorCrossVisible(false);
                drawingPart.setActived(true);
                
                SwitchHideShowDrawingLineAction.updateToolbar(viewContainer);
            }
            
        }
    }
    
    
}

How to hide/show toolbar dynamically in NetBeans Platform

To hide/show toolbar dynamically in NetBeans Platform, you should pre-define a toolbar Configuration firstly, then set to what you want via:

ToolbarPool.getDefault().set(String toolbarConfiguratonName);

1. Define toolbar configuration files in module's resource director: blogtrader-platform-branding\src\org\blogtrader\platform\branding\netbeans\resources\Toolbars\

Standard.xml:

<?xml version="1.0"?>
<!DOCTYPE Configuration PUBLIC "-//NetBeans IDE//DTD toolbar//EN"
 "http://www.netbeans.org/dtds/toolbar.dtd">

<Configuration>
    <Row>
        <Toolbar name="View" />
        <Toolbar name="Control" />
        <Toolbar name="Indicator" />
        <Toolbar name="Draw" />
        <Toolbar name="Memory" />
    </Row>
  
    <Row>
        <Toolbar name="File" position="2" visible="false" />
        <Toolbar name="Edit" position="2" visible="false" />
        <Toolbar name="Build" position="2" visible="false" />
        <Toolbar name="Debug" position="2" visible="false" />
        <Toolbar name="Versioning" position="2" visible="false" />
    </Row>
</Configuration>

Developing.xml:

<?xml version="1.0"?>

<!DOCTYPE Configuration PUBLIC "-//NetBeans IDE//DTD toolbar//EN" 
"http://www.netbeans.org/dtds/toolbar.dtd">

<Configuration>
    <Row>
        <Toolbar name="View" />
        <Toolbar name="Control" />
        <Toolbar name="Indicator" />
        <Toolbar name="Draw" />
        <Toolbar name="Memory" />
    </Row>
  
    <Row>
        <Toolbar name="File" position="2" />
        <Toolbar name="Edit" position="2" />
        <Toolbar name="Build" position="2" />
        <Toolbar name="Debug" position="2" visible="false" />
        <Toolbar name="Versioning" position="2" visible="false" />
    </Row>
</Configuration>

2. register the configuration files in layer.xml:<br>

<?xml version="1.0"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.0//EN"
 "http://www.netbeans.org/dtds/filesystem-1_0.dtd">
<filesystem>    
    <folder name="Toolbars">
    
        <file name="Standard.xml" url="Toolbars/Standard.xml">
        </file>
        <attr name="Standard.xml/Developing.xml" boolvalue="true" />
        <file name="Developing.xml" url="Toolbars/Developing.xml">
        </file>

    </folder >
</filesystem>

3. set to toolbar configuration that you want via:

// change to toolbar layer as Standard
ToolbarPool.getDefault().set("Standard"); 

// change to toolbar layer as Developing
ToolbarPool.getDefault().set("Developing"); 

An interesting face of BlogTrader Platform

I applied the napkin look and feel on BlogTrader Platform, here's what it looks like:</p>

napkinlaf.png

The first custom indicator lives in BlogTrader Platform

Here's the screenshot shows the first custom indicator lives in the coming BlogTrader? Platform which is scheduled at mid of May.

customIndicator.png

An Elliott Wave analyse on Shanghai Index 4 years ago

It was 4 years ago, I wrote an article about the Elliott Wave analyse on Shanghai Stock Exchange Index. At that time, the Shanghai Index dropped from the highest point 2245 at Jun 2001 to a low around 1300. I posted a picture and made some estimations:

* Be ware of that a Big C wave, which may point to around 1043 * The C wave may last to at least 65x3=195 weeks (about to June 2005)

4 years passed, the Shanghai Index arrived a lowest 998 at June 2005. I think that a new wave-1 has been in its step, and the 2007 will be a good year.

Here's the link to orginal  post (in Chinese) and the picture:

wave0205.gif

Programming language for custom indicator?

I tried to write the MA indicator in javascript, here's what it looks:

this._sname = "MA";
this._lname = "Moving Average";
this._overlapping = true;
    
var period1 = new P("Period 1", 5.0 );
var period2 = new P("Period 2", 10.0);
var period3 = new P("Period 3", 20.0);
    
var ma1 = new Var("ma1", Chart.LINE);
var ma2 = new Var("ma2", Chart.LINE);
var ma3 = new Var("ma3", Chart.LINE);
    
function computeCont(int fromIdx) {
    for (int i = fromIdx; i < this._dataSize; i++) {
            
        ma1.set(i, ma(i, C, period1.value()));
        ma2.set(i, ma(i, C, period2.value()));
        ma3.set(i, ma(i, C, period3.value()));
    }
}

And the Java version:

public class MAIndicator extends AbstractContIndicator {
    {   
        _sname = "MA";
        _lname = "Moving Average";
        _overlapping = true;
    }
    
    P period1 = new P("Period 1", 5.0 );
    P period2 = new P("Period 2", 10.0);
    P period3 = new P("Period 3", 20.0);
    
    Var<Float> ma1 = new Var("ma1", Chart.LINE);
    Var<Float> ma2 = new Var("ma2", Chart.LINE);
    Var<Float> ma3 = new Var("ma3", Chart.LINE);
    
    void computeCont(int fromIdx) {
        for (int i = fromIdx; i < _dataSize; i++) {
            
            ma1.set(i, ma(i, C, period1.value()));
            ma2.set(i, ma(i, C, period2.value()));
            ma3.set(i, ma(i, C, period3.value()));
        }
    }
    
}

There is rare difference between those two versions. So, why should we extend this platform via script language if we've built a helpful framework?

Java also has better support via IDE. It's easier to implement code completing, debug etc in java than script language.

For the learning curve, the basic syntax of Java is almost same as javascript. If you don't want to write UI, Network features from the scratch, Java is same easier as javascript.

This comes out my decision: I'll implement the feature of custom indicator directly in Java via wizard and templet. It will be integrated with most of the features in NetBeans IDE for developing module.

And the packed size of binary package will grow to 15M size. But you get a BlogTrader? Platform Developer Edition.