# Scrollbar



## maexchen (17. Jan 2007)

Hallo!

Hab hier ein Programm das eigentlich ganz gut läuft,bis auf zwei Fehler:
1. Man muss zuerst einmal die y achse zoomen, damit der scrollbalken sichtbar wird
2. der scrollbalken wird beim ersten mal zoomen nicht in der mitte dargestellt, sondern am beginn

Bin über jeden Tipp froh!!


```
import java.awt.BorderLayout;
import java.awt.Color;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.net.MalformedURLException;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableModel;


import javax.swing.AbstractButton;
import javax.swing.BoundedRangeModel;
import javax.swing.ButtonGroup;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;

import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;

import org.jfree.chart.renderer.xy.AbstractXYItemRenderer.*;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.IntervalMarker;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer.*;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.Range;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.Layer;
import org.jfree.ui.LengthAdjustmentType;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;



import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;

/**
 * A demo for panning, scrolling and zooming.
 */
public class ttest extends JFrame
                               implements ActionListener, 
                                          ChangeListener, 
                                          ChartChangeListener 
                                          
                                          {
   static List lll;
   static List markers;
    /** The panel that displays the chart. */
    public ChartPanel chartPanel;
    
    /** The scroll factor. */
    private double xscrollFactor = 10;
    private double yscrollFactor = 10;
    
    /** The scroll bar. */
    private JScrollBar xscrollBar;
    
    private JScrollBar yscrollBar;
    
  
    /** The min/max values for the range axis. */
    private double[] primYMinMax = new double[2];
    
    /** The min/max values for the domain axis. */
    private double[] primXMinMax = new double[2];
     
    /** Action command for the zoom box button. */
    private static final String ACTION_CMD_ZOOM_BOX = "zoomBox";
    
    /** Action command for the zoom fit button. */
    private static final String ACTION_CMD_ZOOM_TO_FIT = "zoomFit";
    
    /** Action command for the '+' button. */
    private static final String ACTION_CMD_ZOOM_IN = "zoomIn";
    
    private static final String ACTION_CMD_ZOOM_IN_Y = "yzoomIn";
       
    /** Action command for the '-' button. */
    private static final String ACTION_CMD_ZOOM_OUT = "zoomOut";

    private static final String ACTION_CMD_ZOOM_OUT_Y = "yzoomOut";

    private static final String ACTION_CMD_ZOOM_BOTH = "bothzoom";
    
    /** The zoom factor. */
    private static final double ZOOM_FACTOR = 0.6;

    /** The toolbar. */
    private JToolBar toolBar;
       
    /** The zoom button. */
    private AbstractButton zoomButton;
     
    /** The zoom in button. */
    private AbstractButton zoomInButton;
    
    private AbstractButton yzoomInButton;
    
    /** The zoom out button. */
    private AbstractButton zoomOutButton;
    
    private AbstractButton yzoomOutButton;
    
    /** The fit button. */
    private AbstractButton fitButton;
    
    private AbstractButton bothzoomButton;
    
    /**
     * Creates a new demo instance.
     * 
     * @param frameTitle  the frame title.
     */
    public ttest(String frameTitle) {

        super(frameTitle);

        this.toolBar = createToolbar();
 
        JFreeChart chart = createChart();
 
        recalcScrollBar(chart.getPlot());

        chartPanel = new ChartPanel(chart) {
        }
        ;

        chart.addChangeListener(this);

        // enable zoom
        actionPerformed(new ActionEvent(this, 0, ACTION_CMD_ZOOM_BOX));

   
        this.chartPanel.setPopupMenu(null);
        getContentPane().add(this.chartPanel);
    }
    
    /**
     * einlesen einer textdatei
     * @param filename
     * @throws IOException
     */
    public static void einlesen(String filename) throws IOException {
        List l = new ArrayList(); 
        BufferedReader br = new BufferedReader(new FileReader("eingabe1.txt")); 
        String line; 

        while ((line = br.readLine()) != null){ 
          l.add(line); 
        } 
        br.close();
        System.out.println ("Liste: " + l);
        //br.close(); 
        lll = l;
        
        List m = new ArrayList();
        BufferedReader mbr = new BufferedReader(new FileReader("markers.txt")); 
        while ((line = mbr.readLine()) != null){ 
            m.add(line); 
          } 
          br.close();
          System.out.println ("Liste: " + m);
          br.close(); 
          markers = m;

    }

    /**
     * Creates a sample chart.
     * 
     * @return a sample chart.
     */
    private JFreeChart createChart() {
   
            XYSeriesCollection secondaryJFreeColl = new XYSeriesCollection();
            XYSeries right1 = new XYSeries("EKG");
                  
            for (int i = 0; i<300; i++){
                
                    String strRepresentation = lll.get(i).toString();
                    Double.parseDouble(strRepresentation);
                    double wert = Double.parseDouble(strRepresentation);
                    right1.add(i, wert);
           
            }

            secondaryJFreeColl.addSeries(right1);
            
            NumberAxis xAxis = new NumberAxis("Time");
            xAxis.setAutoRangeIncludesZero(false);
            xAxis.setAutoRangeStickyZero(false);
            
          
            NumberAxis yAxis = new NumberAxis("Voltage");
            yAxis.setAutoRangeIncludesZero(false);
            yAxis.setAutoRangeStickyZero(false);


        // create plot
        XYItemRenderer y1Renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);
        y1Renderer.setSeriesPaint(0, Color.green);
        XYPlot xyPlot = new XYPlot(secondaryJFreeColl, xAxis, yAxis, y1Renderer);
        
        ValueAxis yaxis = xyPlot.getRangeAxis();
        this.primYMinMax[0] = -3;
        this.primYMinMax[1] = 3;
        yaxis.setLowerBound(this.primYMinMax[0]);
        yaxis.setUpperBound(this.primYMinMax[1]);
        
        
        ValueAxis xaxis = xyPlot.getDomainAxis();
        this.primXMinMax[0] = 0;
        this.primXMinMax[1] = 350;
        xaxis.setLowerBound(this.primXMinMax[0]);
        xaxis.setUpperBound(this.primXMinMax[1]);


        // Title + legend

        String title = "ECG-VIEWER";
        JFreeChart ret = new JFreeChart(title, null, xyPlot, true);
        TextTitle textTitle = new TextTitle(
            "(Austrian Research Centers)"
        );
        ret.addSubtitle(textTitle);
            
        return ret;
                    
    }
  
    /**
     * Creates the toolbar.
     * 
     * @return the toolbar.
     */
    private JToolBar createToolbar() {
        JToolBar xtoolbar = new JToolBar();
        JToolBar ytoolbar = new JToolBar();
        
        
        getContentPane().add(xtoolbar, BorderLayout.SOUTH);
        getContentPane().add(ytoolbar, BorderLayout.EAST);
        ButtonGroup groupedButtons = new ButtonGroup();
     
        // ACTION_CMD_ZOOM_BOX
        this.zoomButton = new JToggleButton();
        prepareButton(this.zoomButton, ACTION_CMD_ZOOM_BOX, " Zoom ", "Zoom mode");
        groupedButtons.add(this.zoomButton);
        this.zoomButton.setSelected(true); 
        xtoolbar.add(this.zoomButton);

 
        // ACTION_CMD_ZOOM_IN
        this.zoomInButton = new JButton();
        prepareButton(this.zoomInButton, ACTION_CMD_ZOOM_IN, " + ", "Zoom in");
        xtoolbar.add(this.zoomInButton);
        
//      ACTION_CMD_ZOOM_IN
        this.yzoomInButton = new JButton();
        prepareButton(this.yzoomInButton, ACTION_CMD_ZOOM_IN_Y, " + ", "y Zoom in");
        ytoolbar.add(this.yzoomInButton);

        // ACTION_CMD_ZOOM_OUT
        this.zoomOutButton = new JButton();
        prepareButton(this.zoomOutButton, ACTION_CMD_ZOOM_OUT, " - ", "Zoom out");
        xtoolbar.add(this.zoomOutButton);

//      ACTION_CMD_ZOOM_OUT
        this.yzoomOutButton = new JButton();
        prepareButton(this.yzoomOutButton, ACTION_CMD_ZOOM_OUT_Y, " - ", "y Zoom out");
        ytoolbar.add(this.yzoomOutButton);
        
        // ACTION_CMD_ZOOM_TO_FIT
        this.fitButton = new JButton();
        prepareButton(this.fitButton, ACTION_CMD_ZOOM_TO_FIT, " Fit ", "Fit all");
        //xtoolbar.add(this.fitButton);

//      ACTION_CMD_ZOOM_BOTH
        this.bothzoomButton = new JButton();
        prepareButton(this.bothzoomButton, ACTION_CMD_ZOOM_BOTH, " Both ", "zoom both");
        xtoolbar.add(this.bothzoomButton);
        
        xtoolbar.addSeparator();

        xscrollBar = new JScrollBar(JScrollBar.HORIZONTAL);
        xscrollBar.setModel(new DefaultBoundedRangeModel());
        
        yscrollBar = new JScrollBar (JScrollBar.VERTICAL);
        yscrollBar.setModel(new DefaultBoundedRangeModel());

        xtoolbar.add(xscrollBar);
        ytoolbar.add(yscrollBar);
        
        this.zoomOutButton.setEnabled(false);
        this.fitButton.setEnabled(false);
        this.xscrollBar.setEnabled(true);
        this.yscrollBar.setEnabled (true);

        xtoolbar.setFloatable(false);
        ytoolbar.setFloatable(false);
        return xtoolbar;
    }

    /**
     * Prepares a button.
     * 
     * @param button  the button.
     * @param actionKey  the action key.
     * @param buttonLabelText  the button label.
     * @param toolTipText  the tooltip text.
     */
    private void prepareButton(AbstractButton button, 
                               String actionKey, 
                               String buttonLabelText,
                               String toolTipText) {

        button.setActionCommand(actionKey);
        button.setText(buttonLabelText);
        button.setToolTipText(toolTipText);
        button.addActionListener(this);
    }

  
    
    /**
     * Handles an action event.
     * 
     * @param evt
     *            the event.
     */
    public void actionPerformed(ActionEvent evt) {
        try {
            String acmd = evt.getActionCommand();

            if (acmd.equals(ACTION_CMD_ZOOM_BOX)) {
                
            } 
 
  
            else if (acmd.equals(ACTION_CMD_ZOOM_IN)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomHorizontal(rect.getCenterX(), ZOOM_FACTOR);
            } 
            else if (acmd.equals(ACTION_CMD_ZOOM_OUT)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomHorizontal(rect.getCenterX(), 1 / ZOOM_FACTOR);
            } 
            else if (acmd.equals(ACTION_CMD_ZOOM_IN_Y)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomVertical(rect.getCenterY(), ZOOM_FACTOR);
            } 
            else if (acmd.equals(ACTION_CMD_ZOOM_OUT_Y)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomVertical(rect.getCenterY(), 1 / ZOOM_FACTOR);
            } 
            else if (acmd.equals(ACTION_CMD_ZOOM_BOTH)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomBoth(rect.getCenterX(), rect.getCenterY(), ZOOM_FACTOR);
            } 
            
            else if (acmd.equals(ACTION_CMD_ZOOM_TO_FIT)) {

                Plot plot = this.chartPanel.getChart().getPlot();
                if (plot instanceof ValueAxisPlot) {

                    XYPlot vvPlot = (XYPlot) plot;
                    ValueAxis yaxis = vvPlot.getRangeAxis();
                    if (yaxis != null) {
                        yaxis.setLowerBound(this.primYMinMax[0]);
                        yaxis.setUpperBound(this.primYMinMax[1]);
                    }
                    if (plot instanceof XYPlot) {
                        XYPlot xyPlot = (XYPlot) plot;
                        yaxis = xyPlot.getRangeAxis(0);

                    }
                }
            }
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Handles a {@link ChangeEvent} (in this case, coming from the scrollbar).
     * 
     * @param event  the event.
     */
    public void stateChanged(ChangeEvent event) {
        
        try {

            Object src = event.getSource();
            BoundedRangeModel scrollBarModel = this.xscrollBar.getModel();
   
            if (src == scrollBarModel) {
                int val = scrollBarModel.getValue();
                int ext = scrollBarModel.getExtent();
                
                Plot plot = this.chartPanel.getChart().getPlot();
                if (plot instanceof XYPlot) {
                    XYPlot hvp = (XYPlot) plot;
                    ValueAxis axis = hvp.getDomainAxis();

                    // avoid problems
         
                    this.chartPanel.getChart().removeChangeListener(this);
                    axis.setRange(val / this.xscrollFactor, (val + ext) / this.xscrollFactor);
                    
                    // restore chart listener
                    this.chartPanel.getChart().addChangeListener(this);
                }
            }
        }
            catch (Exception e) {
                e.printStackTrace();
            }
            try{
                Object src = event.getSource();
                BoundedRangeModel yscrollBarModel = this.yscrollBar.getModel();
                if (src == yscrollBarModel) {
                    
                    int val = yscrollBarModel.getValue();
                    int ext = yscrollBarModel.getExtent();
                   
                    Plot plot = this.chartPanel.getChart().getPlot();
                    if (plot instanceof XYPlot) {
                        XYPlot vvp = (XYPlot) plot;
                        ValueAxis yaxis = vvp.getRangeAxis();
                        this.chartPanel.getChart().removeChangeListener(this);
                        yaxis.setRange( (val + ext) / this.yscrollFactor*-1, (val) / this.yscrollFactor*-1);
                        this.chartPanel.getChart().addChangeListener(this);
                        
                    }     
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    /**
     * Handles a {@link ChartChangeEvent}.
     * 
     * @param event  the event.
     */
    public void chartChanged(ChartChangeEvent event) {
          try {
            BoundedRangeModel xscrollBarModel = xscrollBar.getModel();
            
              if (event.getChart() == null) {
                  return;
              }  
              if (xscrollBarModel == null) {
                  return;
              }

              boolean chartIsZoomed = false;
              
              Plot plot = event.getChart().getPlot();
              if (plot instanceof XYPlot) {
                  XYPlot hvp = (XYPlot) plot;
                  ValueAxis xAxis = hvp.getDomainAxis();
                  Range xAxisRange = xAxis.getRange();

                  // avoid recursion
                  xscrollBarModel.removeChangeListener(this);

                  int low = (int) (xAxisRange.getLowerBound() * this.xscrollFactor);
                  xscrollBarModel.setValue(low);
                 
                  int ext = (int) (xAxisRange.getUpperBound() * this.xscrollFactor - low);
                  xscrollBarModel.setExtent(ext);
                 
                  // restore
                  xscrollBarModel.addChangeListener(this);

                  Range hdr = hvp.getDataRange(xAxis);

                  double len = hdr == null ? 0 : hdr.getLength();
                  chartIsZoomed |= xAxisRange.getLength() < len;
              }

              if (!chartIsZoomed && plot instanceof XYPlot) {
                  // check if zoomed horizontally
                  XYPlot hvp = (XYPlot) plot;
                  ValueAxis yAxis = hvp.getRangeAxis();
                  if (yAxis != null) {
                      chartIsZoomed = yAxis.getLowerBound() > this.primYMinMax[0]
                          || yAxis.getUpperBound() < this.primYMinMax[1];
                  }
              }

          } 
          catch (Exception e) {
              e.printStackTrace();
          }      
        
        try {
            BoundedRangeModel yscrollBarModel = yscrollBar.getModel();
            
            if (event.getChart() == null) {
                return;
            }  

            
            if (yscrollBarModel == null) {
                return;
            }

            boolean chartIsZoomed = false;
            
            Plot plot = event.getChart().getPlot();
            if (plot instanceof XYPlot) {
                XYPlot vvp = (XYPlot) plot;
                ValueAxis yAxis = vvp.getRangeAxis();
                Range yAxisRange = yAxis.getRange();

                // avoid recursion
                yscrollBarModel.removeChangeListener(this);

                int low = (int) (yAxisRange.getLowerBound() * this.yscrollFactor);
                yscrollBarModel.setValue(low);
                int ext = (int) (yAxisRange.getUpperBound() * this.yscrollFactor - low);
                yscrollBarModel.setExtent(ext);
      
                // restore
                yscrollBarModel.addChangeListener(this);
                Range hdr = vvp.getDataRange(yAxis);

                double len = hdr == null ? 0 : hdr.getLength();
                chartIsZoomed |= yAxisRange.getLength() < len;
            }

            if (!chartIsZoomed && plot instanceof XYPlot) {
                // check if zoomed horizontally
                XYPlot hvp = (XYPlot) plot;
                ValueAxis yAxis = hvp.getRangeAxis();
                if (yAxis != null) {
                    chartIsZoomed = yAxis.getLowerBound() > this.primYMinMax[0]
                        || yAxis.getUpperBound() < this.primYMinMax[1];
                }
            }
 
        } 
        catch (Exception e) {
            e.printStackTrace();
        }      
    }

    /**
     * Starting point for the demo.
     * 
     * @param args  the command line arguments (ignored).
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        
        try {
            final String lookAndFeelClassName = WindowsLookAndFeel.class.getName();
            UIManager.setLookAndFeel(lookAndFeelClassName);
        } 
        catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        einlesen ("eingabe1.txt");
    
        ttest demo = new ttest("ECG-VIEWER");
        demo.pack();
        demo.setVisible(true);
    
    }

    // PRIVATE 
    
    /**
     * Recalculates the scrollbar settings.
     * 
     * @param plot  the plot.
     */
    private void recalcScrollBar(Plot plot) {
        
        if (plot instanceof XYPlot) {
            XYPlot hvp = (XYPlot) plot;
            ValueAxis axis = hvp.getDomainAxis();

            XYPlot vvp = (XYPlot) plot;
            ValueAxis yaxis = vvp.getRangeAxis();
            
            axis.setLowerMargin(0);
            axis.setUpperMargin(0);
            
            yaxis.setLowerMargin(0);
            yaxis.setUpperMargin(0);

            Range rng = axis.getRange();
            Range yrng = yaxis.getRange();

            BoundedRangeModel scrollBarModel = this.xscrollBar.getModel();
            int len = scrollBarModel.getMaximum() - scrollBarModel.getMinimum();
            if (rng.getLength() > 0) {
                this.xscrollFactor = len / rng.getLength();
                
            }
            
            double dblow = rng.getLowerBound();
            int ilow = (int) (dblow * this.xscrollFactor);
            scrollBarModel.setMinimum(ilow);
            int val = ilow;
            scrollBarModel.setValue(val);

            double dbup = rng.getUpperBound();
            int iup = (int) (dbup * this.xscrollFactor);
            scrollBarModel.setMaximum(iup);
            int ext = iup - ilow;
            scrollBarModel.setExtent(ext);

            
            
            BoundedRangeModel yscrollBarModel = this.yscrollBar.getModel();
            int ylen = yscrollBarModel.getMaximum() - yscrollBarModel.getMinimum();
            if (yrng.getLength() > 0) {
                this.yscrollFactor = ylen / yrng.getLength();
            }
            
            double ydblow = yrng.getLowerBound();
            int yilow = (int) (ydblow * this.yscrollFactor);
            yscrollBarModel.setMinimum(yilow);
            int yval = yilow;
            yscrollBarModel.setValue(yval);

            double ydbup = yrng.getUpperBound();
            int yiup = (int) (ydbup * this.yscrollFactor);
            yscrollBarModel.setMaximum(yiup);
            int yext = yiup - yilow;
            yscrollBarModel.setExtent(yext);

            System.out.println ("y val " +yval);
            System.out.println ("y ext " +yext);
        
            scrollBarModel.addChangeListener(this);
        }
    }

    /**
     * Zooms in on an anchor point (measured in Java2D coordinates).
     * 
     * @param x  the x value.
     * @param y  the y value.
     * @param zoomFactor  the zoomFactor < 1 == zoom in; else out.
     */
    private void zoomBoth(double x, double y, double zoomFactor) {
        zoomHorizontal(x, zoomFactor);
        zoomVertical(y, zoomFactor);            //nur x-Achse zoomen!
    }

    /**
     * Decreases the range on the horizontal axis, centered about a Java2D x coordinate.
     * 


     * The range on the x axis is multiplied by zoomFactor
     * 
     * @param x  the x coordinate in Java2D space.
     * @param zoomFactor  the zoomFactor < 1 == zoom in; else out.
     */
    private void zoomHorizontal(double x, double zoomFactor) {

        JFreeChart chart = this.chartPanel.getChart();
        ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
        if (chart.getPlot() instanceof XYPlot) {
            XYPlot hvp = (XYPlot) chart.getPlot();
            ValueAxis axis = hvp.getDomainAxis();
            if (axis != null) {
                double anchorValue = axis.java2DToValue(
                    (float) x, info.getPlotInfo().getDataArea(), hvp.getDomainAxisEdge()
                );
                if (zoomFactor < 1.0) {
                    axis.resizeRange(zoomFactor, anchorValue);
                } 
                else if (zoomFactor > 1.0) {
                    Range range = hvp.getDataRange(axis);
                    adjustRange(axis, range, zoomFactor, anchorValue);
                }
            }
        }
    }

    /**
     * Decreases the range on the vertical axis, centered about a Java2D y coordinate.
     * 


     * The range on the y axis is multiplied by zoomFactor
     * 
     * @param y  the y coordinate in Java2D space.
     * @param zoomFactor  the zoomFactor < 1 == zoom in; else out.
     */
    private void zoomVertical(double y, double zoomFactor) {

        JFreeChart chart = this.chartPanel.getChart();
        ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();

        // 1. (left) Y-Axis

        if (chart.getPlot() instanceof XYPlot) {
            XYPlot vvp = (XYPlot) chart.getPlot();
            ValueAxis yaxis = vvp.getRangeAxis();
            if (yaxis != null) {
                double anchorValue =
                    yaxis.java2DToValue(
                        (float) y, info.getPlotInfo().getDataArea(), vvp.getRangeAxisEdge()
                    );
                if (zoomFactor < 1.0) {
                    // zoom in
                    yaxis.resizeRange(zoomFactor, anchorValue);

                } 
                else if (zoomFactor > 1.0) {
                    // zoom out
                    Range range = new Range(this.primYMinMax[0], this.primYMinMax[1]);
                    adjustRange(yaxis, range, zoomFactor, anchorValue);
                }
            }

 
           }
        }

    /**
     * used for zooming
     * 
     * @param axis  the axis.
     * @param range  the range.
     * @param zoomFactor  the zoom factor.
     * @param anchorValue  the anchor value.
     */
    private void adjustRange(ValueAxis axis, Range range, double zoomFactor, double anchorValue) {

        if (axis == null || range == null) {
            return;
        }

        double rangeMinVal = range.getLowerBound() - range.getLength() * axis.getLowerMargin();
        double rangeMaxVal = range.getUpperBound() + range.getLength() * axis.getUpperMargin();
        double halfLength = axis.getRange().getLength() * zoomFactor / 2;
        double zoomedMinVal = anchorValue - halfLength;
        double zoomedMaxVal = anchorValue + halfLength;
        double adjMinVal = zoomedMinVal;
        if (zoomedMinVal < rangeMinVal) {
            adjMinVal = rangeMinVal;
            zoomedMaxVal += rangeMinVal - zoomedMinVal;
        }
        double adjMaxVal = zoomedMaxVal;
        if (zoomedMaxVal > rangeMaxVal) {
            adjMaxVal = rangeMaxVal;
            zoomedMinVal -= zoomedMaxVal - rangeMaxVal;
            adjMinVal = Math.max(zoomedMinVal, rangeMinVal);
        }

        Range adjusted = new Range(adjMinVal, adjMaxVal);
        axis.setRange(adjusted);
    }
  }
```


----------



## André Uhres (19. Jan 2007)

So müsste die Scrollbar zumindest synchron zur Grafik laufen:

```
...
public class ttest extends JFrame
        implements ActionListener,
        ChangeListener,
        ChartChangeListener
        
{
...
    public ttest(String frameTitle) {
...
        doStateChanged(xscrollBar.getModel()); 
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
...
    public void actionPerformed(ActionEvent evt) {
        try {
            String acmd = evt.getActionCommand();
            if (acmd.equals(ACTION_CMD_ZOOM_BOX)) {
                
            } else if (acmd.equals(ACTION_CMD_ZOOM_IN)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomHorizontal(rect.getCenterX(), ZOOM_FACTOR);
                doStateChanged(xscrollBar.getModel());
            } else if (acmd.equals(ACTION_CMD_ZOOM_OUT)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomHorizontal(rect.getCenterX(), 1 / ZOOM_FACTOR);
                doStateChanged(xscrollBar.getModel());
            } else if (acmd.equals(ACTION_CMD_ZOOM_IN_Y)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomVertical(rect.getCenterY(), ZOOM_FACTOR);
                doStateChanged(yscrollBar.getModel());
            } else if (acmd.equals(ACTION_CMD_ZOOM_OUT_Y)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomVertical(rect.getCenterY(), 1 / ZOOM_FACTOR);
                doStateChanged(yscrollBar.getModel());
            } else if (acmd.equals(ACTION_CMD_ZOOM_BOTH)) {
                ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo();
                Rectangle2D rect = info.getPlotInfo().getDataArea();
                zoomBoth(rect.getCenterX(), rect.getCenterY(), ZOOM_FACTOR);
                doStateChanged(xscrollBar.getModel());
                doStateChanged(yscrollBar.getModel());
            }
...
    }
    public void stateChanged(ChangeEvent event) {
        doStateChanged(event.getSource()); 
    }
...
    private void doStateChanged(Object src) {
        try {
            BoundedRangeModel scrollBarModel = this.xscrollBar.getModel();
            if (src == scrollBarModel) {
                int val = scrollBarModel.getValue();
                int ext = scrollBarModel.getExtent();
                Plot plot = this.chartPanel.getChart().getPlot();
                if (plot instanceof XYPlot) {
                    XYPlot hvp = (XYPlot) plot;
                    ValueAxis axis = hvp.getDomainAxis();
                    // avoid problems
                    this.chartPanel.getChart().removeChangeListener(this);
                    axis.setRange(val / this.xscrollFactor, (val + ext) / this.xscrollFactor);
                    // restore chart listener
                    this.chartPanel.getChart().addChangeListener(this);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try{
            BoundedRangeModel yscrollBarModel = this.yscrollBar.getModel();
            if (src == yscrollBarModel) {
                int val = yscrollBarModel.getValue();
                int ext = yscrollBarModel.getExtent();
                Plot plot = this.chartPanel.getChart().getPlot();
                if (plot instanceof XYPlot) {
                    XYPlot vvp = (XYPlot) plot;
                    ValueAxis yaxis = vvp.getRangeAxis();
                    this.chartPanel.getChart().removeChangeListener(this);
                    yaxis.setRange( (val + ext) / this.yscrollFactor*-1, (val) / this.yscrollFactor*-1);
                    this.chartPanel.getChart().addChangeListener(this);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
```


----------

