package org.chartsy.main;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import org.chartsy.main.chart.Indicator;
import org.chartsy.main.data.ChartData;
import org.chartsy.main.utils.SerialVersion;
/**
*
* @author Administrator
*/
public class IndicatorsPanel extends JPanel implements Serializable
{
private static final long serialVersionUID = SerialVersion.APPVERSION;
private ChartFrame chartFrame;
public IndicatorsPanel(ChartFrame frame)
{
chartFrame = frame;
setOpaque(false);
setDoubleBuffered(true);
setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
setLayout(new LayoutManager() {
@Override
public void addLayoutComponent(String name, Component comp) {}
@Override
public void removeLayoutComponent(Component comp) {}
@Override
public Dimension preferredLayoutSize(Container parent) { return new Dimension(0, 0); }
@Override
public Dimension minimumLayoutSize(Container parent) { return new Dimension(0, 0); }
@Override
public void layoutContainer(Container parent) {
Component[] components = parent.getComponents();
if (components.length == 0) return;
Insets insets = parent.getInsets();
int width = parent.getWidth() - insets.left - insets.right;
int x = insets.left;
int y = insets.top;
for (int i = 0; i < components.length; i++)
{
int height = ((IndicatorPanel)components[i]).getPanelHeight();
components[i].setBounds(x, y, width, height);
y += height;
}
}
});
Resizeable resizeable = new Resizeable(this);
addMouseListener(resizeable);
addMouseMotionListener(resizeable);
ChartFrameAdapter frameAdapter = new ChartFrameAdapter()
{
@Override
public void indicatorAdded(Indicator indicator)
{
int count = getIndicatorsCount();
IndicatorPanel indicatorPanel = new IndicatorPanel(chartFrame, indicator);
indicatorPanel.setMaximizedHeight(Indicator.DEFAULT_HEIGHT);
add(indicatorPanel, count);
updateIndicatorsToolbar();
calculateHeight();
chartFrame.validate();
chartFrame.repaint();
}
@Override
public void indicatorRemoved(Indicator indicator)
{
IndicatorPanel indicatorPanel = getIndicatorPanel(indicator);
if (indicatorPanel != null)
{
indicator.clearDatasets();
remove(indicatorPanel);
updateIndicatorsToolbar();
calculateHeight();
chartFrame.validate();
chartFrame.repaint();
}
}
};
chartFrame.addChartFrameListener(frameAdapter);
}
public ChartFrame getChartFrame()
{ return chartFrame; }
public void setChartFrame(ChartFrame frame)
{ chartFrame = frame; }
public int getIndicatorsCount()
{
return getComponentCount();
}
public IndicatorPanel getIndicatorPanel(Indicator ind)
{
IndicatorPanel[] panels = getIndicatorPanels();
for (int i = 0; i < panels.length; i++)
if (ind.equals(panels[i].getIndicator()))
return panels[i];
return null;
}
public IndicatorPanel[] getIndicatorPanels()
{
IndicatorPanel[] indicatorPanels = new IndicatorPanel[getComponentCount()];
for (int i = 0; i < indicatorPanels.length; i++)
{
Component component = getComponent(i);
if (component instanceof IndicatorPanel)
indicatorPanels[i] = (IndicatorPanel) component;
}
return indicatorPanels;
}
public int getPanelHeight()
{
IndicatorPanel[] panels = getIndicatorPanels();
if (panels.length > 0)
{
int height = 0;
for (IndicatorPanel panel : panels)
height += panel.getPanelHeight();
return height;
} else
{
return 0;
}
}
public int getPanelY(int index)
{
IndicatorPanel[] panels = getIndicatorPanels();
if (panels.length > 0)
{
int height = 0;
for (int i = 0; i < index; i++)
height += panels[i].getPanelHeight();
return height;
} else
{
return 0;
}
}
public AnnotationPanel[] getAnnotationPanels()
{
IndicatorPanel[] indicatorPanels = getIndicatorPanels();
AnnotationPanel[] annotationPanels = new AnnotationPanel[indicatorPanels.length];
for (int i = 0; i < indicatorPanels.length; i++)
annotationPanels[i] = indicatorPanels[i].getAnnotationPanel();
return annotationPanels;
}
public IndicatorPanel getIndicatorPanel(AnnotationPanel panel)
{
IndicatorPanel[] indicatorPanels = getIndicatorPanels();
for (int i = 0; i < indicatorPanels.length; i++)
if (indicatorPanels[i].getAnnotationPanel() == panel)
return indicatorPanels[i];
return null;
}
public boolean allMinimized()
{
for (IndicatorPanel ip : getIndicatorPanels())
if (ip.isMaximized())
return true;
return false;
}
public int getMaximizedHeight()
{
for (IndicatorPanel ip : getIndicatorPanels())
if (ip.isMaximized())
return ip.getPanelHeight();
return 24;
}
public void updateIndicatorsToolbar()
{
for (IndicatorPanel ip : getIndicatorPanels())
ip.updateToolbox();
}
public void calculateHeight()
{
int count = getIndicatorsCount();
if (count != 0)
{
int height = (int) (chartFrame.getSplitPanel().getHeight() - ChartData.dataOffset.bottom);
height = (int) (0.60 * height);
height = height / count;
if (height > Indicator.DEFAULT_HEIGHT || height < 0)
height = Indicator.DEFAULT_HEIGHT;
for (IndicatorPanel panel : getIndicatorPanels())
panel.setMaximizedHeight(height);
}
}
public Indicator[] getIndicators()
{
IndicatorPanel[] indicatorPanels = getIndicatorPanels();
Indicator[] indicators = new Indicator[indicatorPanels.length];
for (int i = 0; i < indicatorPanels.length; i++)
indicators[i] = indicatorPanels[i].getIndicator();
return indicators;
}
public List<Indicator> getIndicatorsList()
{
Indicator[] inds = getIndicators();
List<Indicator> list = new ArrayList<Indicator>();
list.addAll(Arrays.asList(inds));
return list;
}
public void addIndicator(Indicator indicator)
{
int count = getIndicatorsCount();
IndicatorPanel indicatorPanel = new IndicatorPanel(chartFrame, indicator);
indicatorPanel.updateToolbox();
int height = Indicator.DEFAULT_HEIGHT != indicator.getMaximizedHeight()
? indicator.getMaximizedHeight()
: Indicator.DEFAULT_HEIGHT;
indicatorPanel.setMaximizedHeight(height);
add(indicatorPanel, count);
calculateHeight();
}
public int getIndicatorIndex(IndicatorPanel panel)
{
int result = -1;
IndicatorPanel[] indicatorPanels = getIndicatorPanels();
for (int i = 0; i < indicatorPanels.length; i++)
{
if (indicatorPanels[i] == panel)
{
result = i;
break;
}
}
return result;
}
public void moveUp(IndicatorPanel panel)
{
int index = getIndicatorIndex(panel);
int count = getIndicatorsCount();
int dest = index - 1;
if (dest < 0) dest = count - 1;
if (dest != index)
{
remove(panel);
add(panel, dest);
}
}
public void moveDown(IndicatorPanel panel)
{
int index = getIndicatorIndex(panel);
int count = getIndicatorsCount();
int dest = index + 1;
if (dest >= count) dest = 0;
if (dest != index)
{
remove(panel);
add(panel, dest);
}
}
public void removeIndicator(IndicatorPanel panel)
{
remove(panel);
calculateHeight();
updateIndicatorsToolbar();
}
public void removeAllIndicators()
{
removeAll();
}
public static class Resizeable extends MouseAdapter implements MouseMotionListener
{
int fix_pt_x = -1;
int fix_pt_y = -1;
IndicatorsPanel cResizeable;
Cursor oldCursor;
public Resizeable(IndicatorsPanel comp)
{
cResizeable = comp;
}
private void setCursorType(Point p)
{
boolean n = p.y <= 4;
if (n)
{
cResizeable.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
return;
}
else
{
cResizeable.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
return;
}
}
@Override
public void mouseEntered(MouseEvent e)
{
cResizeable.requestFocus();
if (cResizeable.allMinimized())
setCursorType(e.getPoint());
}
@Override
public void mouseExited(MouseEvent e)
{
if (oldCursor != null)
((Component)e.getSource()).setCursor(oldCursor);
oldCursor = null;
}
@Override
public void mousePressed(MouseEvent e)
{
cResizeable.requestFocus();
Cursor c = cResizeable.getCursor();
if (c.equals(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)))
{
fix_pt_y = e.getY();
return;
}
else
{
fix_pt_y = -1;
return;
}
}
@Override
public void mouseReleased(MouseEvent e)
{
fix_pt_y = -1;
cResizeable.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
cResizeable.doLayout();
cResizeable.getChartFrame().getSplitPanel().doLayout();
cResizeable.getChartFrame().validate();
cResizeable.getChartFrame().repaint();
}
@Override
public void mouseMoved(MouseEvent e)
{
if (cResizeable.allMinimized())
setCursorType(e.getPoint());
}
@Override
public void mouseDragged(MouseEvent e)
{
if (cResizeable.allMinimized())
{
Cursor c = cResizeable.getCursor();
int y = e.getY();
int count = cResizeable.getIndicatorsCount();
int maxHeight = (int) ((cResizeable.getChartFrame().getMainPanel().getHeight() - ChartData.dataOffset.bottom) / (count + 1.5)) * count;
int height = cResizeable.getMaximizedHeight() * count;
if (fix_pt_y != -1)
{
int dy = 0;
if (c.equals(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)))
{
dy = fix_pt_y - y;
}
height += dy;
}
if (height >= maxHeight)
height = maxHeight;
int indicatorH = height / count;
if (indicatorH < 50)
indicatorH = 50;
for (IndicatorPanel panel : cResizeable.getIndicatorPanels())
panel.setMaximizedHeight(indicatorH);
cResizeable.doLayout();
cResizeable.getChartFrame().getSplitPanel().doLayout();
cResizeable.getChartFrame().validate();
cResizeable.getChartFrame().repaint();
}
}
}
}