package Test; import ChartDirector.*; import java.util.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ZoomScrollDemo3 extends JFrame { // Data arrays for the scrollable / zoomable chart. private Date[] timeStamps; private double[] highData; private double[] lowData; private double[] openData; private double[] closeData; private double[] volData; // The current visible duration of the view port is 100 sessions private double initialViewPortWidth = 100; // In this demo, the maximum zoom-in is set to 10 sessions private double minDuration = 10; // Will set to true at the end of initialization private boolean hasFinishedInitialization; // // Controls in the JFrame // private ChartViewer chartViewer1; private JScrollBar hScrollBar1; private JButton pointerPB; private JButton zoomInPB; private JButton zoomOutPB; /// /// The main method to allow this demo to run as a standalone program. /// public static void main(String args[]) { ZoomScrollDemo3 d = new ZoomScrollDemo3(); d.initComponents(true); d.setVisible(true); } /// /// Create the JFrame and put controls in it. /// private void initComponents(final boolean closeOnExit) { // Do nothing if already initialized if (hasFinishedInitialization) return; setTitle("ChartDirector Zooming and Scrolling Demonstration"); setResizable(false); // End application upon closing main window if (closeOnExit) { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }}); } // Top label bar JLabel topLabel = new JLabel("Advanced Software Engineering"); topLabel.setForeground(new java.awt.Color(255, 255, 51)); topLabel.setBackground(new java.awt.Color(0, 0, 128)); topLabel.setBorder(new javax.swing.border.EmptyBorder(2, 0, 2, 5)); topLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); topLabel.setOpaque(true); getContentPane().add(topLabel, java.awt.BorderLayout.NORTH); // Left panel JPanel leftPanel = new JPanel(null); leftPanel.setBorder(javax.swing.BorderFactory.createRaisedBevelBorder()); // Pointer push button pointerPB = new JButton("Pointer", loadImageIcon("pointer.gif")); pointerPB.setHorizontalAlignment(SwingConstants.LEFT); pointerPB.setMargin(new Insets(5, 5, 5, 5)); pointerPB.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pointerPB_Clicked(); }}); leftPanel.add(pointerPB).setBounds(1, 0, 148, 24); // Zoom In push button zoomInPB = new JButton("Zoom In", loadImageIcon("zoomin.gif")); zoomInPB.setHorizontalAlignment(SwingConstants.LEFT); zoomInPB.setMargin(new Insets(5, 5, 5, 5)); zoomInPB.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomInPB_Clicked(); }}); leftPanel.add(zoomInPB).setBounds(1, 24, 148, 24); // Zoom out push button zoomOutPB = new JButton("Zoom Out", loadImageIcon("zoomout.gif")); zoomOutPB.setHorizontalAlignment(SwingConstants.LEFT); zoomOutPB.setMargin(new Insets(5, 5, 5, 5)); zoomOutPB.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomOutPB_Clicked(); }}); leftPanel.add(zoomOutPB).setBounds(1, 48, 148, 24); // Total expected panel size leftPanel.setPreferredSize(new Dimension(150, 264)); // Chart Viewer chartViewer1 = new ChartViewer(); chartViewer1.setBackground(new java.awt.Color(255, 255, 255)); chartViewer1.setOpaque(true); chartViewer1.setPreferredSize(new Dimension(616, 500)); chartViewer1.setHorizontalAlignment(SwingConstants.CENTER); chartViewer1.addViewPortListener(new ViewPortAdapter() { public void viewPortChanged(ViewPortChangedEvent e) { chartViewer1_ViewPortChanged(e); } }); chartViewer1.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { chartViewer1_onMouseClick(e); } }); // Horizontal Scroll bar hScrollBar1 = new JScrollBar(JScrollBar.HORIZONTAL, 0, 100000000, 0, 1000000000); hScrollBar1.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { hScrollBar1_ValueChanged(); } }); // Put the ChartViewer and the scroll bars in the right panel JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.add(chartViewer1, java.awt.BorderLayout.CENTER); rightPanel.add(hScrollBar1, java.awt.BorderLayout.SOUTH); // Put the leftPanel and rightPanel on the JFrame getContentPane().add(leftPanel, java.awt.BorderLayout.WEST); getContentPane().add(rightPanel, java.awt.BorderLayout.CENTER); // Set all UI fonts (except labels) Font uiFont = new Font("Dialog", Font.PLAIN, 11); for (int i = 0; i < leftPanel.getComponentCount(); ++i) { Component c = leftPanel.getComponent(i); if (!(c instanceof JLabel)) c.setFont(uiFont); } // Load the data loadData(); // Set ChartViewer to reflect the visible and minimum duration chartViewer1.setFullRange("x", 0, timeStamps.length - 1); chartViewer1.setMouseWheelZoomRatio(1.1); chartViewer1.setZoomInWidthLimit(minDuration / (timeStamps.length - 1)); chartViewer1.setViewPortWidth(initialViewPortWidth / (timeStamps.length - 1)); chartViewer1.setViewPortLeft(1 - chartViewer1.getViewPortWidth()); // Initially choose the pointer mode (draw to scroll mode) pointerPB.doClick(); // Can update the chart now pack(); hasFinishedInitialization = true; chartViewer1.updateViewPort(true, true); } /// /// A utility to load an image icon from the Java class path /// private ImageIcon loadImageIcon(String path) { try { return new ImageIcon(getClass().getClassLoader().getResource(path)); } catch (Exception e) { return null; } } /// /// Load the data /// private void loadData() { // In this demo, we allow scrolling the chart for the last 5 years GregorianCalendar lastDate = new GregorianCalendar(); lastDate.set(lastDate.get(Calendar.YEAR), lastDate.get(Calendar.MONTH), lastDate.get(Calendar.DAY_OF_MONTH), 0, 0, 0); GregorianCalendar firstDate = (GregorianCalendar)lastDate.clone(); firstDate.add(Calendar.YEAR, -1); FinanceSimulator s = new FinanceSimulator("ABCD", firstDate.getTime(), lastDate.getTime(), 86400); timeStamps = s.getTimeStamps(); highData = s.getHighData(); lowData = s.getLowData(); openData = s.getOpenData(); closeData = s.getCloseData(); volData = s.getVolData(); } /// /// Click event for the pointerPB. /// private void pointerPB_Clicked() { pointerPB.setBackground(new Color(0x80, 0xff, 0x80)); zoomInPB.setBackground(null); zoomOutPB.setBackground(null); chartViewer1.setMouseUsage(Chart.MouseUsageScrollOnDrag); } /// /// Click event for the zoomInPB. /// private void zoomInPB_Clicked() { pointerPB.setBackground(null); zoomInPB.setBackground(new Color(0x80, 0xff, 0x80)); zoomOutPB.setBackground(null); chartViewer1.setMouseUsage(Chart.MouseUsageZoomIn); } /// /// Click event for the zoomOutPB. /// private void zoomOutPB_Clicked() { pointerPB.setBackground(null); zoomInPB.setBackground(null); zoomOutPB.setBackground(new Color(0x80, 0xff, 0x80)); chartViewer1.setMouseUsage(Chart.MouseUsageZoomOut); } /// /// Horizontal ScrollBar ValueChanged event handler /// private void hScrollBar1_ValueChanged() { if (hasFinishedInitialization && !chartViewer1.isInViewPortChangedEvent()) { // Get the view port left as according to the scroll bar double newViewPortLeft = ((double)(hScrollBar1.getValue() - hScrollBar1.getMinimum())) / (hScrollBar1.getMaximum() - hScrollBar1.getMinimum()); // Check if view port has really changed - sometimes the scroll bar may issue redundant // value changed events when value has not actually changed. if (Math.abs(chartViewer1.getViewPortLeft() - newViewPortLeft) > 0.00001 * chartViewer1.getViewPortWidth()) { // Set the view port based on the scroll bar chartViewer1.setViewPortLeft(newViewPortLeft); // Update the chart display without updating the image maps. We delay updating // the image map because the chart may still be unstable (still scrolling). chartViewer1.updateViewPort(true, false); } } } /// /// The ViewPortChanged event handler. This event occurs when the user changes the ChartViewer /// view port by dragging scrolling, or by zoom in/out, or the ChartViewer.updateViewPort method /// is being called. /// private void chartViewer1_ViewPortChanged(ViewPortChangedEvent e) { // Synchronize the horizontal scroll bar with the ChartViewer hScrollBar1.setEnabled(chartViewer1.getViewPortWidth() < 1); hScrollBar1.setVisibleAmount((int)Math.ceil(chartViewer1.getViewPortWidth() * (hScrollBar1.getMaximum() - hScrollBar1.getMinimum()))); hScrollBar1.setBlockIncrement(hScrollBar1.getVisibleAmount()); hScrollBar1.setUnitIncrement((int)Math.ceil(hScrollBar1.getVisibleAmount() * 0.1)); hScrollBar1.setValue((int)Math.round(chartViewer1.getViewPortLeft() * (hScrollBar1.getMaximum() - hScrollBar1.getMinimum())) + hScrollBar1.getMinimum()); // Update chart and image map if necessary if (e.needUpdateChart()) drawChart(chartViewer1); } /// /// Draw the chart. /// private void drawChart(ChartViewer viewer) { // Get the starting index of the array using the start date int startIndex = (int)Math.floor(viewer.getValueAtViewPort("x", viewer.getViewPortLeft())); int extraPoints = Math.min(30, startIndex); startIndex -= extraPoints; // Get the ending index of the array using the end date int endIndex = (int)Math.ceil(viewer.getValueAtViewPort("x", viewer.getViewPortLeft() + viewer.getViewPortWidth())); endIndex = Math.min(endIndex, timeStamps.length - 1); // Get the length int noOfPoints = endIndex - startIndex + 1; // Now, we can just copy the visible data we need into the view port data series Date[] viewPortTimeStamps = new Date[noOfPoints]; double[] viewPortHighData = new double[noOfPoints]; double[] viewPortLowData = new double[noOfPoints]; double[] viewPortOpenData = new double[noOfPoints]; double[] viewPortCloseData = new double[noOfPoints]; double[] viewPortVolData = new double[noOfPoints]; System.arraycopy(timeStamps, startIndex, viewPortTimeStamps, 0, noOfPoints); System.arraycopy(highData, startIndex, viewPortHighData, 0, noOfPoints); System.arraycopy(lowData, startIndex, viewPortLowData, 0, noOfPoints); System.arraycopy(openData, startIndex, viewPortOpenData, 0, noOfPoints); System.arraycopy(closeData, startIndex, viewPortCloseData, 0, noOfPoints); System.arraycopy(volData, startIndex, viewPortVolData, 0, noOfPoints); // // Now we have obtained the data, we can plot the chart. // FinanceChart c = new FinanceChart(600); c.setData(viewPortTimeStamps, viewPortHighData, viewPortLowData, viewPortOpenData, viewPortCloseData, viewPortVolData, extraPoints); XYChart mainChart = c.addMainChart(250); mainChart.setClipping(); c.addHLOC(0x8000, 0xcc0000); c.addSimpleMovingAvg(20, 0x9900ff); c.addBollingerBand(20, 2, 0x9999ff, 0xc06666ff); c.addVolBars(75, 0x99ff99, 0xff9999, 0x808080); drawCustomLine(chartViewer1, mainChart); chartViewer1.setChart(c); } private double x1 = Chart.NoValue; private double y1; private double x2 = Chart.NoValue; private double y2; private void chartViewer1_onMouseClick(MouseEvent e) { ChartViewer viewer = (ChartViewer)e.getSource(); FinanceChart f = (FinanceChart)viewer.getChart(); if (null == f) return; XYChart mainChart = (XYChart)f.getChart(0); // Convert mouse coordinates to pixel coordinates and save them to (x1, y1) and (x2, y2) int startIndex = (int)Math.floor(viewer.getValueAtViewPort("x", viewer.getViewPortLeft())); if (x1 == Chart.NoValue) { x1 = mainChart.getXValue(viewer.getChartMouseX()) + startIndex; y1 = mainChart.getYValue(viewer.getChartMouseY()); } else if (x2 == Chart.NoValue) { x2 = mainChart.getXValue(viewer.getChartMouseX()) + startIndex; y2 = mainChart.getYValue(viewer.getChartMouseY()); } chartViewer1.updateViewPort(true, true); } private void drawCustomLine(ChartViewer viewer, XYChart mainChart) { if ((x1 == Chart.NoValue) || (x2 == Chart.NoValue)) return; DrawArea d = mainChart.makeChart3(); PlotArea p = mainChart.getPlotArea(); d.setClipRect(p.getLeftX(), p.getTopY(), p.getRightX(), p.getBottomY()); // Convert data coordinates to pixel coordinates int startIndex = (int)Math.floor(viewer.getValueAtViewPort("x", viewer.getViewPortLeft())); int pixelX1 = mainChart.getXCoor(x1 - startIndex); int pixelY1 = mainChart.getYCoor(y1); int pixelX2 = mainChart.getXCoor(x2 - startIndex); int pixelY2 = mainChart.getYCoor(y2); d.line(pixelX1, pixelY1, pixelX2, pixelY2, 0xff0000, 2); d.setClipRect(0, 0, mainChart.getWidth(), mainChart.getHeight()); } }