读书人

jfreechart 对于鼠标事件响应的扩张

发布时间: 2012-12-18 12:43:41 作者: rapoo

jfreechart 对于鼠标事件响应的扩展

??? jfreechart是一个优秀的开源chart软件。利用jfreechart可以绘制出各种丰富和优美的图形。但是在jfreechart的图上对于鼠标的支持不很充分,对于鼠标的clicked、moved、pressed、released、entered、exited的事件只支持了两个clicked和moved(不知道为什么?),幸运的是jfreechart是一个开源的软件,可以对于它的实现进行升级,在它传统的功能基础上,实现自己的功能需求。

?? jfreechart中的鼠标事件实现机制为:一是扩展java.util.EventListener接口为ChartMouseListener,在其中定义了chartMouseClicked和chartMouseMoved两个事件响应函数;而是继承java.util.EventObject类生成ChartMouseEvent,在ChartMouseEvent中封装了鼠标事件和Jfreechart的对象,供事件处理函数中应用;三是在jfreechart的ChartPanel中定义了事件监听器队列,当外部程序注册了事件监听器后,在chartpanel中发生定义的事件后,监听器响应响应的事件。

?? 在jfreechart默认的实现中,对于鼠标事件,只有clicked和moved可以供外部监听,其他事件提供了默认的监听实现,这样就阻碍了外部对jfreechart的更深入的鼠标操作。

?? 为了实现其它事件能够被外部监听器监听,首先需要对ChartPanel中的事件监听机制进行调整,这里我利用MyChartPanel继承ChartPanel,重载其中所需要被外部监听器监听的事件的实现函数,把事件发给外部的监听器,类定义如下所示:

import java.awt.Insets;import java.awt.event.MouseEvent;import java.awt.geom.Point2D;import org.jfree.chart.ChartMouseEvent;import org.jfree.chart.ChartMouseListener;import org.jfree.chart.ChartPanel;import org.jfree.chart.JFreeChart;import org.jfree.chart.entity.ChartEntity;import org.jfree.chart.entity.EntityCollection;@SuppressWarnings("serial")public class MyChartPanel extends ChartPanel {public MyChartPanel(JFreeChart chart) {super(chart);// TODO Auto-generated constructor stub}/* (non-Javadoc) * @see org.jfree.chart.ChartPanel#mousePressed(java.awt.event.MouseEvent) */@Overridepublic void mousePressed(MouseEvent event) {// TODO Auto-generated method stub       Insets insets = getInsets();        int x = (int) ((event.getX() - insets.left) /this.scaleX);        int y = (int) ((event.getY() - insets.top) / this.scaleY);        this.anchor = new Point2D.Double(x, y);        if (this.chart == null) {            return;        }        this.chart.setNotify(true);  // force a redraw        // new entity code...        Object[] listeners = this.chartMouseListeners.getListeners(                ChartMouseListener.class);        if (listeners.length == 0) {            return;        }        ChartEntity entity = null;        if (this.info != null) {            EntityCollection entities = this.info.getEntityCollection();            if (entities != null) {                entity = entities.getEntity(x, y);            }        }        ChartMouseEvent chartEvent = new ChartMouseEvent(getChart(), event,                entity);        for (int i = listeners.length - 1; i >= 0; i -= 1) {            ((MyChartMouseListener) listeners[i]).chartMousePressed(chartEvent);        }}/* (non-Javadoc) * @see org.jfree.chart.ChartPanel#mouseReleased(java.awt.event.MouseEvent) */@Overridepublic void mouseReleased(MouseEvent event) {// TODO Auto-generated method stub       Insets insets = getInsets();        int x = (int) ((event.getX() - insets.left) /this.scaleX);        int y = (int) ((event.getY() - insets.top) / this.scaleY);        this.anchor = new Point2D.Double(x, y);        if (this.chart == null) {            return;        }        this.chart.setNotify(true);  // force a redraw        // new entity code...        Object[] listeners = this.chartMouseListeners.getListeners(                ChartMouseListener.class);        if (listeners.length == 0) {            return;        }        ChartEntity entity = null;        if (this.info != null) {            EntityCollection entities = this.info.getEntityCollection();            if (entities != null) {                entity = entities.getEntity(x, y);            }        }        ChartMouseEvent chartEvent = new ChartMouseEvent(getChart(), event,                entity);        for (int i = listeners.length - 1; i >= 0; i -= 1) {            ((MyChartMouseListener) listeners[i]).chartMouseReleased(chartEvent);        }}}

?

把mousePressed和mouseReleased事件转发出来。

?扩展ChartMouseListener,增加这两个事件的出来接口:

import org.jfree.chart.ChartMouseEvent;import org.jfree.chart.ChartMouseListener;public interface MyChartMouseListener extends ChartMouseListener {public void chartMousePressed(ChartMouseEvent event);public void chartMouseReleased(ChartMouseEvent event);}

?实现自定义的MouseListener:

import java.awt.Cursor;import java.awt.Shape;import javax.swing.JPanel;import org.jfree.chart.ChartMouseEvent;import org.jfree.chart.JFreeChart;import org.jfree.chart.entity.XYItemEntity;import org.jfree.data.xy.XYIntervalDataItem;import org.jfree.data.xy.XYIntervalSeries;import org.jfree.data.xy.XYIntervalSeriesCollection;public class MyBarChartListener implements MyChartMouseListener {@Overridepublic void chartMouseClicked(ChartMouseEvent event) {// TODO Auto-generated method stub/*JFreeChart chart = event.getChart();if (chart == null)return;XYItemEntity ce = (XYItemEntity) event.getEntity();if (ce == null)return;IntervalXYDataset my = (IntervalXYDataset) ce.getDataset();int sindex = ce.getSeriesIndex();int iindex = ce.getItem();System.out.println("x = " + my.getXValue(sindex, iindex));System.out.println("y = " + my.getYValue(sindex, iindex));*/}@Overridepublic void chartMouseMoved(ChartMouseEvent event) {// TODO Auto-generated method stub}XYItemEntity ce;XYIntervalSeriesCollection my;@Overridepublic void chartMousePressed(ChartMouseEvent event) {// TODO Auto-generated method stubSystem.out.println("mouse chartMousePressed");JPanel src = (JPanel) event.getTrigger().getSource();src.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));JFreeChart chart = event.getChart();if (chart == null)return;ce = (XYItemEntity) event.getEntity();if (ce == null)return; my = (XYIntervalSeriesCollection) ce.getDataset();int sindex = ce.getSeriesIndex();int iindex = ce.getItem();Shape shape = ce.getArea();System.out.println("sindex = " + sindex);System.out.println("iindex = " + iindex);System.out.println("x = " + my.getXValue(sindex, iindex));System.out.println("y = " + my.getYValue(sindex, iindex));XYIntervalSeries series = (XYIntervalSeries) my.getSeries(ce.getSeriesIndex());System.out.println("y1 = " + shape.getBounds2D().getCenterY());/*series.remove(my.getXValue(sindex, iindex));Day day1 = new Day(13, 6, 2007);        Day day2 = new Day(14, 6, 2007);XYBarChartDemo7.addItem(series,day1,day2,sindex);*/}@Overridepublic void chartMouseReleased(ChartMouseEvent event) {// TODO Auto-generated method stubSystem.out.println("mouse chartMouseReleased");MyChartPanel src = (MyChartPanel) event.getTrigger().getSource();src.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));double cursorY = event.getTrigger().getY();System.out.println("y = "+ cursorY);int seriesIndex = my.getSeriesCount();double maxY = src.getScreenDataArea().getMaxY();double minY = src.getScreenDataArea().getMinY();double heightY = (maxY-minY)/seriesIndex;for(int i=0;i<seriesIndex;i++){if(cursorY >= minY && cursorY<=(i+1)*heightY){XYIntervalSeries srcSeries =((XYIntervalSeriesCollection) (this.ce.getDataset())).getSeries(seriesIndex-i-1);XYIntervalSeriesCollection destSeriesCollection = (XYIntervalSeriesCollection) (this.ce.getDataset());XYIntervalSeries destSeries =destSeriesCollection.getSeries(this.ce.getSeriesIndex());XYIntervalDataItem item = (XYIntervalDataItem) destSeries.getDataItem(this.ce.getItem());srcSeries.add(item.getX(), item.getXLowValue(), item.getXHighValue(), seriesIndex-i-1, seriesIndex-i-1-0.1, seriesIndex-i-1+0.3);destSeries.remove(destSeriesCollection.getXValue(this.ce.getSeriesIndex(), this.ce.getItem()));/*Day day1 = new Day(13, 6, 2007);        Day day2 = new Day(14, 6, 2007);        XYBarChartDemo7.addItem(series,day1,day2,seriesIndex-i-1);*/                break;}}}

?

就可以实现在jfreechart中的图形的拖拽了。

?

???

读书人网 >编程

热点推荐