📄 chartpanel.java
字号:
*
* @param flag <code>true</code> enables trace lines for the mouse
* pointer on the vertical axis.
*/
public void setVerticalAxisTrace(boolean flag) {
this.verticalAxisTrace = flag;
}
/**
* Returns <code>true</code> if file extensions should be enforced, and <code>false</code>
* otherwise.
*
* @return The flag.
*/
public boolean isEnforceFileExtensions() {
return this.enforceFileExtensions;
}
/**
* Sets a flag that controls whether or not file extensions are enforced.
*
* @param enforce the new flag value.
*/
public void setEnforceFileExtensions(boolean enforce) {
this.enforceFileExtensions = enforce;
}
/**
* Switches chart tooltip generation on or off.
*
* @param flag the flag.
*/
public void setDisplayToolTips(boolean flag) {
if (flag) {
ToolTipManager.sharedInstance().registerComponent(this);
}
else {
ToolTipManager.sharedInstance().unregisterComponent(this);
}
}
/**
* Returns a string for the tooltip.
*
* @param e the mouse event.
*
* @return a tool tip or <code>null</code> if no tooltip is available.
*/
public String getToolTipText(MouseEvent e) {
String result = null;
if (this.info != null) {
EntityCollection entities = this.info.getEntityCollection();
if (entities != null) {
Insets insets = getInsets();
ChartEntity entity = entities.getEntity(
(int) ((e.getX() - insets.left) / this.scaleX),
(int) ((e.getY() - insets.top) / this.scaleY)
);
if (entity != null) {
result = entity.getToolTipText();
}
}
}
return result;
}
/**
* Translates a Java2D point on the chart to a screen location.
*
* @param java2DPoint the Java2D point.
*
* @return the screen location.
*/
public Point translateJava2DToScreen(Point2D java2DPoint) {
Insets insets = getInsets();
int x = (int) (java2DPoint.getX() * this.scaleX + insets.left);
int y = (int) (java2DPoint.getY() * this.scaleY + insets.top);
return new Point(x, y);
}
/**
* Translates a screen location to a Java2D point.
*
* @param screenPoint the screen location.
*
* @return the Java2D coordinates.
*/
public Point2D translateScreenToJava2D(Point screenPoint) {
Insets insets = getInsets();
double x = (screenPoint.getX() - insets.left) / this.scaleX;
double y = (screenPoint.getY() - insets.top) / this.scaleY;
return new Point2D.Double(x, y);
}
/**
* Returns the chart entity at a given point.
* <P>
* This method will return null if there is (a) no entity at the given point, or
* (b) no entity collection has been generated.
*
* @param viewX the x-coordinate.
* @param viewY the y-coordinate.
*
* @return the chart entity (possibly null).
*/
public ChartEntity getEntityForPoint(int viewX, int viewY) {
ChartEntity result = null;
if (this.info != null) {
Insets insets = getInsets();
double x = (viewX - insets.left) / this.scaleX;
double y = (viewY - insets.top) / this.scaleY;
EntityCollection entities = this.info.getEntityCollection();
result = entities != null ? entities.getEntity(x, y) : null;
}
return result;
}
/**
* Sets the refresh buffer flag.
*
* @param flag <code>true</code> indicate, that the buffer should be refreshed.
*/
public void setRefreshBuffer(boolean flag) {
this.refreshBuffer = flag;
}
/** Working storage for available panel area after deducting insets. */
private transient Rectangle2D available = new Rectangle2D.Double();
/** Working storage for the chart area. */
private transient Rectangle2D chartArea = new Rectangle2D.Double();
/**
* Paints the component by drawing the chart to fill the entire component,
* but allowing for the insets (which will be non-zero if a border has been
* set for this component). To increase performance (at the expense of
* memory), an off-screen buffer image can be used.
*
* @param g the graphics device for drawing on.
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.chart == null) {
return;
}
Graphics2D g2 = (Graphics2D) g.create();
// first determine the size of the chart rendering area...
Dimension size = getSize();
Insets insets = getInsets();
this.available.setRect(
insets.left, insets.top,
size.getWidth() - insets.left - insets.right,
size.getHeight() - insets.top - insets.bottom
);
// work out if scaling is required...
boolean scale = false;
double drawWidth = this.available.getWidth();
double drawHeight = this.available.getHeight();
this.scaleX = 1.0;
this.scaleY = 1.0;
if (drawWidth < this.minimumDrawWidth) {
this.scaleX = drawWidth / this.minimumDrawWidth;
drawWidth = this.minimumDrawWidth;
scale = true;
}
else if (drawWidth > this.maximumDrawWidth) {
this.scaleX = drawWidth / this.maximumDrawWidth;
drawWidth = this.maximumDrawWidth;
scale = true;
}
if (drawHeight < this.minimumDrawHeight) {
this.scaleY = drawHeight / this.minimumDrawHeight;
drawHeight = this.minimumDrawHeight;
scale = true;
}
else if (drawHeight > this.maximumDrawHeight) {
this.scaleY = drawHeight / this.maximumDrawHeight;
drawHeight = this.maximumDrawHeight;
scale = true;
}
this.chartArea.setRect(0.0, 0.0, drawWidth, drawHeight);
// are we using the chart buffer?
if (this.useBuffer) {
// do we need to resize the buffer?
if ((this.chartBuffer == null) || (this.chartBufferWidth != this.available.getWidth())
|| (this.chartBufferHeight != this.available.getHeight())) {
this.chartBufferWidth = (int) this.available.getWidth();
this.chartBufferHeight = (int) this.available.getHeight();
this.chartBuffer = createImage(this.chartBufferWidth, this.chartBufferHeight);
this.refreshBuffer = true;
}
// do we need to redraw the buffer?
if (this.refreshBuffer) {
Rectangle2D bufferArea =
new Rectangle2D.Double(0, 0, this.chartBufferWidth, this.chartBufferHeight);
Graphics2D bufferG2 = (Graphics2D) this.chartBuffer.getGraphics();
if (scale) {
AffineTransform saved = bufferG2.getTransform();
AffineTransform st = AffineTransform.getScaleInstance(
this.scaleX, this.scaleY
);
bufferG2.transform(st);
this.chart.draw(bufferG2, this.chartArea, this.anchor, this.info);
bufferG2.setTransform(saved);
}
else {
this.chart.draw(bufferG2, bufferArea, this.anchor, this.info);
}
this.refreshBuffer = false;
}
// zap the buffer onto the panel...
g2.drawImage(this.chartBuffer, insets.left, insets.right, this);
}
// or redrawing the chart every time...
else {
AffineTransform saved = g2.getTransform();
g2.translate(insets.left, insets.top);
if (scale) {
AffineTransform st = AffineTransform.getScaleInstance(this.scaleX, this.scaleY);
g2.transform(st);
}
this.chart.draw(g2, this.chartArea, this.anchor, this.info);
g2.setTransform(saved);
}
this.anchor = null;
this.verticalTraceLine = null;
this.horizontalTraceLine = null;
}
/**
* Receives notification of changes to the chart, and redraws the chart.
*
* @param event details of the chart change event.
*/
public void chartChanged(ChartChangeEvent event) {
this.refreshBuffer = true;
repaint();
}
/**
* Receives notification of a chart progress event.
*
* @param event the event.
*/
public void chartProgress(ChartProgressEvent event) {
// does nothing - override if necessary
}
/**
* Handles action events generated by the popup menu.
*
* @param event the event.
*/
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
if (command.equals(PROPERTIES_ACTION_COMMAND)) {
attemptEditChartProperties();
}
else if (command.equals(SAVE_ACTION_COMMAND)) {
try {
doSaveAs();
}
catch (IOException e) {
System.err.println("ChartPanel.doSaveAs: i/o exception = " + e.getMessage());
}
}
else if (command.equals(PRINT_ACTION_COMMAND)) {
createChartPrintJob();
}
else if (command.equals(ZOOM_IN_BOTH_ACTION_COMMAND)) {
zoomInBoth(this.zoomPoint.getX(), this.zoomPoint.getY());
}
else if (command.equals(ZOOM_IN_HORIZONTAL_ACTION_COMMAND)) {
zoomInHorizontal(this.zoomPoint.getX());
}
else if (command.equals(ZOOM_IN_VERTICAL_ACTION_COMMAND)) {
zoomInVertical(this.zoomPoint.getY());
}
else if (command.equals(ZOOM_OUT_BOTH_ACTION_COMMAND)) {
zoomOutBoth(this.zoomPoint.getX(), this.zoomPoint.getY());
}
else if (command.equals(ZOOM_OUT_HORIZONTAL_ACTION_COMMAND)) {
zoomOutHorizontal(this.zoomPoint.getX());
}
else if (command.equals(ZOOM_OUT_VERTICAL_ACTION_COMMAND)) {
zoomOutVertical(this.zoomPoint.getY());
}
else if (command.equals(AUTO_RANGE_BOTH_ACTION_COMMAND)) {
autoRangeBoth();
}
else if (command.equals(AUTO_RANGE_HORIZONTAL_ACTION_COMMAND)) {
autoRangeHorizontal();
}
else if (command.equals(AUTO_RANGE_VERTICAL_ACTION_COMMAND)) {
autoRangeVertical();
}
}
/**
* Handles a 'mouse entered' event. This method changes the tooltip delays of
* ToolTipManager.sharedInstance() to the possibly
* different values set for this chart panel.
*
* @param e the mouse event.
*/
public void mouseEntered(MouseEvent e) {
if (!this.ownToolTipDelaysActive) {
ToolTipManager ttm = ToolTipManager.sharedInstance();
this.originalToolTipInitialDelay = ttm.getInitialDelay();
ttm.setInitialDelay(this.ownToolTipInitialDelay);
this.originalToolTipReshowDelay = ttm.getReshowDelay();
ttm.setReshowDelay(this.ownToolTipReshowDelay);
this.originalToolTipDismissDelay = ttm.getDismissDelay();
ttm.setDismissDelay(this.ownToolTipDismissDelay);
this.ownToolTipDelaysActive = true;
}
}
/**
* Handles a 'mouse exited' event. This method resets the tooltip delays of
* ToolTipManager.sharedInstance() to their
* original values in effect before mouseEntered()
*
* @param e the mouse event.
*/
public void mouseExited(MouseEvent e) {
if (this.ownToolTipDelaysActive) {
// restore original tooltip dealys
ToolTipManager ttm = ToolTipManager.sharedInstance();
ttm.setInitialDelay(this.originalToolTipInitialDelay);
ttm.setReshowDelay(this.originalToolTipReshowDelay);
ttm.setDismissDelay(this.originalToolTipDismissDelay);
this.ownToolTipDelaysActive = false;
}
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -