问题描述
我们可以在JfreeChart中将平移功能实现为鼠标拖动事件吗?现在,我按下并拖动鼠标以平移图表.我只想通过拖动鼠标来实现平移功能.有可能吗?
Can we implement the pan functionality as a mouse drag event in JfreeChart? Right now I press and drag my mouse to pan a chart. I want to implement the pan functionality just by dragging the mouse. Is that possible ?
推荐答案
用当前的JFreeChart API更改修改键显然是不可能的,如此处(但它在管道中).
It is apparently impossible to change the modifier key with the current JFreeChart API, as discussed here (but it is in the pipeline).
但是,所有内容都可以通过编程方式平移图表,因此您可以尝试以下操作:
However, everything is there to pan a chart programmatically, so you could try the following:
- 在
ChartPanel
中添加MouseMotionListener
以跟踪mouseDragged()
事件. - 从这些事件中,计算图表的请求移动.
- 直接调用
XYPlot.panDomainAxes()
和XYPlot.panRangeAxis()
(API 此处).
- Add a
MouseMotionListener
to yourChartPanel
to trackmouseDragged()
events. - From these events, compute the requested movement of the chart.
- Call directly
XYPlot.panDomainAxes()
andXYPlot.panRangeAxis()
(API here).
从ChartPanel
中获取灵感源代码:
/**
* Temporary storage for the width and height of the chart
* drawing area during panning.
*/
private double panW, panH;
/** The last mouse position during panning. */
private Point panLast;
/**
* The mask for mouse events to trigger panning.
*
* @since 1.0.13
*/
private int panMask = InputEvent.CTRL_MASK;
...
/**
* Handles a 'mouse pressed' event.
* <P>
* This event is the popup trigger on Unix/Linux. For Windows, the popup
* trigger is the 'mouse released' event.
*
* @param e The mouse event.
*/
@Override
public void mousePressed(MouseEvent e) {
if (this.chart == null) {
return;
}
Plot plot = this.chart.getPlot();
int mods = e.getModifiers();
if ((mods & this.panMask) == this.panMask) {
// can we pan this plot?
if (plot instanceof Pannable) {
Pannable pannable = (Pannable) plot;
if (pannable.isDomainPannable() || pannable.isRangePannable()) {
Rectangle2D screenDataArea = getScreenDataArea(e.getX(),
e.getY());
if (screenDataArea != null && screenDataArea.contains(
e.getPoint())) {
this.panW = screenDataArea.getWidth();
this.panH = screenDataArea.getHeight();
this.panLast = e.getPoint();
setCursor(Cursor.getPredefinedCursor(
Cursor.MOVE_CURSOR));
}
}
// the actual panning occurs later in the mouseDragged()
// method
}
}
else if (this.zoomRectangle == null) {
...
}
}
...
/**
* Handles a 'mouse dragged' event.
*
* @param e the mouse event.
*/
@Override
public void mouseDragged(MouseEvent e) {
// if the popup menu has already been triggered, then ignore dragging...
if (this.popup != null && this.popup.isShowing()) {
return;
}
// handle panning if we have a start point
if (this.panLast != null) {
double dx = e.getX() - this.panLast.getX();
double dy = e.getY() - this.panLast.getY();
if (dx == 0.0 && dy == 0.0) {
return;
}
double wPercent = -dx / this.panW;
double hPercent = dy / this.panH;
boolean old = this.chart.getPlot().isNotify();
this.chart.getPlot().setNotify(false);
Pannable p = (Pannable) this.chart.getPlot();
if (p.getOrientation() == PlotOrientation.VERTICAL) {
p.panDomainAxes(wPercent, this.info.getPlotInfo(),
this.panLast);
p.panRangeAxes(hPercent, this.info.getPlotInfo(),
this.panLast);
}
else {
p.panDomainAxes(hPercent, this.info.getPlotInfo(),
this.panLast);
p.panRangeAxes(wPercent, this.info.getPlotInfo(),
this.panLast);
}
this.panLast = e.getPoint();
this.chart.getPlot().setNotify(old);
return;
}
...
}
...
/**
* Handles a 'mouse released' event. On Windows, we need to check if this
* is a popup trigger, but only if we haven't already been tracking a zoom
* rectangle.
*
* @param e information about the event.
*/
@Override
public void mouseReleased(MouseEvent e) {
// if we've been panning, we need to reset now that the mouse is
// released...
if (this.panLast != null) {
this.panLast = null;
setCursor(Cursor.getDefaultCursor());
}
...
}
编辑:注意到当前API的唯一问题是panMask
是私有的,为什么不尝试通过反射来破解该字段:
Noticing that the only problem with the current API is that panMask
is private, why don't you try to hack the field with reflection:
Field mask = ChartPanel.class.getDeclaredField("panMask");
mask.setAccessible(true);
mask.set(yourChartPanel, Integer.valueOf(0)); // The "0" mask is equivalent to no mask. You could also set a different modifier.
这篇关于使用鼠标平移图表-Jfreechart的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!