package org.chartsy.main;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.io.Serializable;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import org.chartsy.main.chart.Indicator;
import org.chartsy.main.dialogs.SettingsPanel;
import org.chartsy.main.resources.ResourcesUtils;
import org.chartsy.main.utils.ColorGenerator;
import org.chartsy.main.utils.GraphicsUtils;
import org.chartsy.main.utils.SerialVersion;
/**
*
* @author Administrator
*/
public class IndicatorPanel extends JPanel implements Serializable
{
private static final long serialVersionUID = SerialVersion.APPVERSION;
private ChartFrame chartFrame;
private AnnotationPanel annotationPanel;
private IndicatorToolbox toolbox;
private Indicator indicator = null;
public IndicatorPanel(ChartFrame frame, Indicator indicator)
{
this.chartFrame = frame;
this.indicator = indicator;
initializeUIElements();
}
private void initializeUIElements()
{
annotationPanel = new AnnotationPanel(chartFrame);
toolbox = new IndicatorToolbox();
toolbox.setLocation(0, 0);
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)
{
int width = parent.getWidth();
int height = parent.getHeight();
int toolboxWidth = toolbox.getWidth();
int toolboxHeight = toolbox.getHeight();
annotationPanel.setBounds(0, 2, width - 4, height - 4);
toolbox.setBounds(0, 0, toolboxWidth, toolboxHeight);
}
});
add(toolbox);
add(annotationPanel);
doLayout();
}
public ChartFrame getChartFrame()
{
return chartFrame;
}
public void setChartFrame(ChartFrame frame)
{
chartFrame = frame;
}
public AnnotationPanel getAnnotationPanel()
{
return annotationPanel;
}
public void setAnnotationPanel(AnnotationPanel panel)
{
annotationPanel = panel;
}
public Indicator getIndicator()
{
return indicator;
}
public void setIndicator(Indicator ind)
{
indicator = ind;
}
public boolean isMaximized()
{
if (indicator != null)
return indicator.isMaximized();
return true;
}
public void setMaximized(boolean b)
{
if (indicator.isMaximized() != b)
{
indicator.setMaximized(b);
if (toolbox != null)
toolbox.update();
annotationPanel.setVisible(b);
chartFrame.validate();
chartFrame.repaint();
}
}
public void toggleVisible()
{
setMaximized(!isMaximized());
}
public IndicatorToolbox getToolbox()
{
return toolbox;
}
public void updateToolbox()
{
toolbox.update();
}
public void setMaximizedHeight(int height)
{
this.indicator.setMaximizedHeight(height);
}
public int getPanelHeight()
{
if (isMaximized())
{
return indicator.getMaximizedHeight();
}
else
{
return toolbox.getHeight();
}
}
private AbstractAction indicatorSettings(final ChartFrame frame, final IndicatorPanel panel)
{
return new AbstractAction("Indicator Settings", ResourcesUtils.getIcon("settings"))
{
@Override
public void actionPerformed(ActionEvent e)
{
SettingsPanel.getDefault().openSettingsWindow(panel.getIndicator());
}
};
}
private AbstractAction moveUp(final ChartFrame frame, final IndicatorPanel panel)
{
return new AbstractAction("Move Indicator Up", ResourcesUtils.getIcon("up"))
{
@Override
public void actionPerformed(ActionEvent e)
{
frame.getSplitPanel().getIndicatorsPanel().moveUp(panel);
}
};
}
private AbstractAction moveDown(final ChartFrame frame, final IndicatorPanel panel)
{
return new AbstractAction("Move Indicator Down", ResourcesUtils.getIcon("down"))
{
@Override
public void actionPerformed(ActionEvent e)
{
frame.getSplitPanel().getIndicatorsPanel().moveDown(panel);
}
};
}
private AbstractAction minimize(final IndicatorPanel panel)
{
return new AbstractAction("Minimize Indicator", ResourcesUtils.getIcon("minimize"))
{
@Override
public void actionPerformed(ActionEvent e)
{
panel.setMaximized(false);
}
};
}
private AbstractAction maximize(final IndicatorPanel panel)
{
return new AbstractAction("Minimize Indicator", ResourcesUtils.getIcon("maximize"))
{
@Override
public void actionPerformed(ActionEvent e)
{
panel.setMaximized(true);
}
};
}
private AbstractAction removeAction(final ChartFrame frame, final IndicatorPanel panel)
{
return new AbstractAction("Remove Indicator", ResourcesUtils.getIcon("remove"))
{
@Override
public void actionPerformed(ActionEvent e)
{
frame.indicatorRemoved(indicator);
}
};
}
@Override
public void paint(Graphics g)
{
int width = getWidth();
Graphics2D g2 = GraphicsUtils.prepareGraphics(g);
ChartProperties cp = chartFrame.getChartProperties();
g2.setColor(cp.getAxisColor());
g2.setStroke(cp.getAxisStroke());
g2.drawLine(0, 0, width, 0);
Rectangle rect = this.getBounds();
rect.grow(-2, -2);
if (indicator != null)
{
boolean isLog = cp.getAxisLogarithmicFlag();
if ( isLog ) cp.setAxisLogarithmicFlag(false);
indicator.paint(g2, chartFrame, rect);
if ( isLog ) cp.setAxisLogarithmicFlag(true);
}
super.paint(g);
}
@Override
public void update(Graphics g)
{
paint(g);
}
@Override
public Rectangle getBounds()
{
return new Rectangle(0, 0, getWidth(), getPanelHeight());
}
public final class IndicatorToolbox extends JToolBar implements Serializable
{
private static final long serialVersionUID = SerialVersion.APPVERSION;
private JLabel indicatorLabel;
private JComponent container;
public boolean mouseOver = false;
private final Color backColor = ColorGenerator.getTransparentColor(new Color(0x1C2331), 50);
public IndicatorToolbox()
{
super(JToolBar.HORIZONTAL);
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
indicatorLabel = new JLabel(indicator.getLabel());
indicatorLabel.setHorizontalTextPosition(SwingConstants.LEFT);
indicatorLabel.setVerticalTextPosition(SwingConstants.CENTER);
indicatorLabel.setOpaque(false);
add(indicatorLabel);
container = new JPanel();
container.setOpaque(false);
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
add(container);
update();
addMouseListener(new MouseAdapter()
{
public @Override void mouseEntered(MouseEvent e)
{
mouseOver = true;
validate();
repaint();
}
public @Override void mouseExited(MouseEvent e)
{
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
mouseOver = false;
validate();
repaint();
}
});
}
public @Override int getWidth()
{
return this.getLayout().preferredLayoutSize(this).width;
}
public @Override int getHeight()
{
return this.getLayout().preferredLayoutSize(this).height;
}
public void update()
{
// remove all buttons
container.removeAll();
// number of indicators
int count = IndicatorPanel.this.chartFrame.getSplitPanel().getIndicatorsPanel().getIndicatorsCount();
ToolboxButton button;
// Settings
container.add(button = new ToolboxButton(indicatorSettings(IndicatorPanel.this.chartFrame, IndicatorPanel.this)));
button.setText("");
button.setToolTipText("Settings");
if (count > 1)
{
// Move Up
container.add(button = new ToolboxButton(moveUp(IndicatorPanel.this.chartFrame, IndicatorPanel.this)));
button.setText("");
button.setToolTipText("Move Up");
// Move Down
container.add(button = new ToolboxButton(moveDown(IndicatorPanel.this.chartFrame, IndicatorPanel.this)));
button.setText("");
button.setToolTipText("Move Down");
}
// Toggle Maximize/Minimize
container.add(button = new ToolboxButton(isMaximized() ? minimize(IndicatorPanel.this) : maximize(IndicatorPanel.this)));
button.setText("");
button.setToolTipText(isMaximized() ? "Minimize" : "Maximize");
// Remove
container.add(button = new ToolboxButton(removeAction(IndicatorPanel.this.chartFrame, IndicatorPanel.this)));
button.setText("");
button.setToolTipText("Remove");
revalidate();
repaint();
}
public @Override void paint(Graphics g)
{
if (!indicatorLabel.getFont().equals(chartFrame.getChartProperties().getFont()))
indicatorLabel.setFont(chartFrame.getChartProperties().getFont());
if (!indicatorLabel.getForeground().equals(chartFrame.getChartProperties().getFontColor()))
indicatorLabel.setForeground(chartFrame.getChartProperties().getFontColor());
if (!indicatorLabel.getText().equals(indicator.getLabel()))
indicatorLabel.setText(indicator.getLabel());
Rectangle oldClip = g.getClipBounds();
Rectangle newClip = getBounds();
g.setClip(newClip);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2.setPaintMode();
if (mouseOver)
{
g2.setColor(backColor);
RoundRectangle2D roundRectangle = new RoundRectangle2D.Double(getX(), getY(), getWidth(), getHeight(), 10, 10);
g2.fill(roundRectangle);
}
super.paint(g);
g2.dispose();
g.setClip(oldClip);
}
public class ToolboxButton extends JButton implements Serializable
{
private static final long serialVersionUID = SerialVersion.APPVERSION;
public ToolboxButton(Action action)
{
super(action);
setOpaque(false);
setFocusPainted(false);
setBorderPainted(false);
setMargin(new Insets(0, 0, 0, 0));
setBorder(new Border()
{
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
{}
@Override
public Insets getBorderInsets(Component c)
{
return new Insets(0, 2, 0, 2);
}
@Override
public boolean isBorderOpaque()
{
return true;
}
});
addMouseListener(new MouseAdapter()
{
public @Override void mouseExited(MouseEvent e)
{
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
IndicatorToolbox.this.mouseOver = false;
IndicatorToolbox.this.validate();
IndicatorToolbox.this.repaint();
}
public @Override void mouseEntered(MouseEvent e)
{
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
IndicatorToolbox.this.mouseOver = true;
IndicatorToolbox.this.validate();
IndicatorToolbox.this.repaint();
}
public @Override void mousePressed(MouseEvent e)
{
IndicatorToolbox.this.mouseOver = false;
IndicatorToolbox.this.validate();
IndicatorToolbox.this.repaint();
}
});
}
}
}
}