📄 plotpanel.java
字号:
/*====================================================================*\PlotPanel.javaPlot panel class.------------------------------------------------------------------------This file is part of FuncPlotter, a combined Java application and appletfor plotting explicit functions in one variable.Copyright 2005-2007 Andy Morgan-Richards.FuncPlotter is free software: you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation, either version 3 of the License, or (at youroption) any later version.This program is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith this program. If not, see <http://www.gnu.org/licenses/>.\*====================================================================*/// IMPORTSimport gui.GuiUtilities;import java.awt.Cursor;import java.awt.Dimension;import java.awt.FontMetrics;import java.awt.Graphics;import java.awt.Insets;import java.awt.Point;import java.awt.Rectangle;import java.awt.event.FocusEvent;import java.awt.event.FocusListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.geom.Point2D;import java.util.ArrayList;import java.util.List;import javax.swing.BorderFactory;import javax.swing.JComponent;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;import util.IntegerRange;import util.TextUtilities;//----------------------------------------------------------------------// PLOT PANEL CLASSclass PlotPanel extends JComponent implements FocusListener, MouseListener{////////////////////////////////////////////////////////////////////////// Constants//////////////////////////////////////////////////////////////////////// public static final int MIN_PLOT_WIDTH = 128; public static final int MAX_PLOT_WIDTH = 2048; public static final int MIN_PLOT_HEIGHT = MIN_PLOT_WIDTH; public static final int MAX_PLOT_HEIGHT = MAX_PLOT_WIDTH; private static final int LEFT_MARGIN = 4; private static final int RIGHT_MARGIN = 4; private static final int TOP_MARGIN = 8; private static final int BOTTOM_MARGIN = 4; private static final int SCALE_LINE_LENGTH = 4; private static final int X_SCALE_TOP_MARGIN = 1; private static final int X_SCALE_LEFT_MARGIN = 3; private static final int Y_SCALE_LEFT_MARGIN = 3; private static final int MIN_PIXELS_PER_DIVISION = 32; private static final double SCROLL_FACTOR = 0.5; private static final double ONE_OVER_LOG_10 = 1.0 / Math.log( 10.0 ); private static final String ZERO_STR = "0"; private static final String BASE_STR = "-.E-000";////////////////////////////////////////////////////////////////////////// Member classes : non-inner classes//////////////////////////////////////////////////////////////////////// // PLOT PARAMETERS CLASS private static class PlotParams { //////////////////////////////////////////////////////////////////// // Constructors //////////////////////////////////////////////////////////////////// private PlotParams( PlotInterval interval, int dimension ) { final double TOLERANCE = 0.25 / (double)MIN_PIXELS_PER_DIVISION; final double UPPER_LIMIT_1 = 1.0 + TOLERANCE; final double UPPER_LIMIT_2 = 2.0 + TOLERANCE; final double UPPER_LIMIT_5 = 5.0 + TOLERANCE; pixelDelta = interval.getInterval( ) / (double)dimension; divisionDelta = pixelDelta * MIN_PIXELS_PER_DIVISION; int exponent = (int)Math.floor( Math.log( divisionDelta ) * ONE_OVER_LOG_10 ); divisionDelta *= Math.pow( 10.0, -exponent ); int divIncrement = 1; if ( divisionDelta > UPPER_LIMIT_1 ) { if ( divisionDelta <= UPPER_LIMIT_2 ) divIncrement = 2; else if ( divisionDelta <= UPPER_LIMIT_5 ) divIncrement = 5; else ++exponent; } divisionDelta = (double)divIncrement * Math.pow( 10.0, exponent ); pixelsPerDivision = (int)(divisionDelta / pixelDelta); pixelDelta = divisionDelta / (double)pixelsPerDivision; start = Math.floor( interval.getLowerEndpoint( ) / pixelDelta ); divisionOffset = pixelsPerDivision - (int)start % pixelsPerDivision; if ( divisionOffset >= pixelsPerDivision ) divisionOffset -= pixelsPerDivision; start *= pixelDelta; intervalExponent = interval.getExponent( );/* // Debugging: print values System.out.println( "dimension = " + dimension ); System.out.println( "interval.lowerEndpoint = " + interval.lowerEndpoint ); System.out.println( "interval.upperEndpoint = " + interval.upperEndpoint ); System.out.println( "interval = " + interval ); System.out.println( "start = " + start ); System.out.println( "pixelDelta = " + pixelDelta ); System.out.println( "pixelsPerDivision = " + pixelsPerDivision ); System.out.println( "divisionOffset = " + divisionOffset ); System.out.println( "divisionDelta = " + divisionDelta ); System.out.println( "intervalExponent = " + intervalExponent ); System.out.println( "-----------------------" );*/ } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance methods //////////////////////////////////////////////////////////////////// public boolean equals( PlotParams params ) { return ( (params != null) && (start == params.start) && (pixelDelta == params.pixelDelta) && (pixelsPerDivision == params.pixelsPerDivision) && (divisionOffset == params.divisionOffset) && (divisionDelta == params.divisionDelta) && (intervalExponent == params.intervalExponent) ); } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance variables //////////////////////////////////////////////////////////////////// private double start; private double pixelDelta; private int pixelsPerDivision; private int divisionOffset; private double divisionDelta; private int intervalExponent; } //==================================================================////////////////////////////////////////////////////////////////////////// Constructors//////////////////////////////////////////////////////////////////////// public PlotPanel( FunctionDocument document, int plotWidth, int plotHeight ) { // Set border and font setBorder( false ); borderInsets = getBorder( ).getBorderInsets( this ); AppFont.PLOT.setFont( this ); // Initialise instance variables this.document = document; FontMetrics fontMetrics = getFontMetrics( getFont( ) ); char[] zeros = Util.createCharArray( '0', 8 ); maxYScaleStrWidth = fontMetrics.stringWidth( BASE_STR ) + fontMetrics.charsWidth( zeros, 0, zeros.length ); int yScaleWidth = Y_SCALE_LEFT_MARGIN + maxYScaleStrWidth + SCALE_LINE_LENGTH; int xScaleHeight = SCALE_LINE_LENGTH + X_SCALE_TOP_MARGIN + fontMetrics.getHeight( ); plotRect = new Rectangle( borderInsets.left + LEFT_MARGIN + yScaleWidth, borderInsets.top + TOP_MARGIN, plotWidth, plotHeight ); panelWidth = borderInsets.left + LEFT_MARGIN + yScaleWidth + plotWidth + maxYScaleStrWidth / 2 + RIGHT_MARGIN + borderInsets.right; panelHeight = borderInsets.top + TOP_MARGIN + plotHeight + xScaleHeight + BOTTOM_MARGIN + borderInsets.bottom; xParams = new PlotParams( document.getXInterval( ), plotWidth ); yParams = new PlotParams( document.getYInterval( ), plotHeight ); changeListeners = new ArrayList<ChangeListener>( ); // Set component attributes setOpaque( true ); setFocusable( true ); setCursor( false ); // Add listeners addFocusListener( this ); addMouseListener( this ); } //------------------------------------------------------------------////////////////////////////////////////////////////////////////////////// Instance methods : FocusListener interface//////////////////////////////////////////////////////////////////////// public void focusGained( FocusEvent event ) { setBorder( true ); } //------------------------------------------------------------------ public void focusLost( FocusEvent event ) { setBorder( false ); } //------------------------------------------------------------------////////////////////////////////////////////////////////////////////////// Instance methods : MouseListener interface//////////////////////////////////////////////////////////////////////// public void mouseClicked( MouseEvent event ) { // do nothing } //------------------------------------------------------------------ public void mouseEntered( MouseEvent event ) { // do nothing } //------------------------------------------------------------------ public void mouseExited( MouseEvent event ) { // do nothing } //------------------------------------------------------------------ public void mousePressed( MouseEvent event ) { requestFocusInWindow( ); } //------------------------------------------------------------------ public void mouseReleased( MouseEvent event ) { // do nothing } //------------------------------------------------------------------////////////////////////////////////////////////////////////////////////// Instance methods : overriding methods//////////////////////////////////////////////////////////////////////// public Dimension getMinimumSize( ) { return new Dimension( panelWidth, panelHeight ); } //------------------------------------------------------------------ public Dimension getPreferredSize( ) { return getMinimumSize( ); } //------------------------------------------------------------------ protected void paintComponent( Graphics gr ) { // Draw component background Rectangle rect = gr.getClipBounds( ); AppConfig config = AppConfig.getInstance( ); gr.setColor( drawingImage ? config.getPlotImageMarginColour( ) : getBackground( ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -