📄 wfpanel.java
字号:
package org.trinet.jiggle;
// WFPanel.java
import java.applet.*;
import java.text.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import org.trinet.jasi.TravelTime;
import org.trinet.jdbc.*;
import org.trinet.jasi.*;
import org.trinet.util.*;
import org.trinet.util.graphics.ColorList;
/**
* This class it the graphical representation of one WView in a panel.
* The size of the WF is scaled to the size of the panel.
* If it is not explicitely set, the panel size is set by the
* layout manager.<p>
*
* Class allows the WFPanel to have an alternateWf. This is a second version
* of the contained waveform and ususally represents a filtered time series.
*
* Has limited mouse support for finding out where you are in the trace.
* You must extend this class and add mouse handelers to make it dynamic.
* @see: ActiveWFPanel()
* @see: ZoomedWFPanel()
*/
public class WFPanel
extends JPanel
implements Scrollable {
/** Keep track of selected status.
* If selected highlight with the selectedColor.
*/
boolean amSelected = false;
// Color attributes
// Static default colors
static final Color selectedColor = new Color (165, 220, 255); // sky blue
static final Color unselectedColor = Color.white;
static final Color alternateUnselectedColor = ColorList.aliceBlue; //slight gray
static final Color highlightColor = Color.yellow;
static final Color dragColor = Color.orange;
// Actual colors
Color WFColor = Color.black; // default colors
Color TextColor = Color.black;
Color backgroundColor = unselectedColor;
Color segEdgeColor = Color.cyan;
Color ScaleColor = Color.black;
/** Allow display of an alternate (filtered) wf. */
boolean showAlternateWf = false;
/** The filter used to produce the alternate waveform. */
FilterIF filter = null;
/** The alternate waveform. */
private Waveform alternateWf = null;
/** The row header for WFPanels in scollers. */
private WFRowHeader rowHeader = new WFRowHeader(this);
/** the waveform view to be painted. */
public WFView wfv; // the waveform view to be painted
/** Master view of the data set*/
MasterView mv ;
/** Initial scale factor */
private double ScaleFacX = 1.0;
/** Initial scale factor */
private double ScaleFacY = 1.0;
/** Show or don't the WFSegment boundaries in the view */
public boolean showSegments = false;
/** Controls if a time scale is plotted in the panel */
boolean showTimeScale = true;
/** Controls if an amp scale is plotted in the panel */
boolean showAmpScale = true;
/** If a time scale is plotted, controls if time labels are printed */
boolean showTimeLabel = true;
/** If true, show pick descriptions on pick marker flags. */
boolean showPhaseDescriptions = true;
/** If true, show channel and dist label. */
boolean showChannelLabel = true;
/** If true show a colored stripe (PhaseCue) where P an S should be. */
boolean showPhaseCues = false;
PhaseCue cue = new PhaseCue();
/** show samples as red |'s if scale is expanded sufficiently */
boolean showSamples = true;
/** Show a red vertical line from median line to sample*/
boolean showSampleBars = true;
// Optional viewport: to let paint() know limits of visible panel. This is used to insure
// that PickMarkers, etc. are visible where WFPanel is expanded
JViewport vport;
// scaling values
double pixelsPerSecond;
double pixelsPerCount;
double transY; // this is needed to convert pixel position to amp
// reduce instatiation overhead...
double pixelInterval, xPosition;
// for dynmic displays of current cursor location
Point cursorLoc = new Point();
public boolean continuousSelection = false;
int initPanelWidth = 300; // default size (just temporary, layout manager
int initPanelHeight = 100; // will adjust this)
// static final Font fontBold = new Font("Monospaced", Font.BOLD, 12);
static final DecimalFormat df1 = new DecimalFormat ( "###0.0" ); // distance format
/** Time and amp bounds of the actual data in the WFView */
WFDataBox dataBox = new WFDataBox();
/** Time and amp bounds of this WFPanel
* (often longer then the dataBox to align traces in the
* MultiPanel or smaller if the trace is zoomed )*/
WFSelectionBox panelBox = new WFSelectionBox();
/* Explanation of view areas used here.
Each "box" defines a 2-D area in time-amp space. Time is in seconds and amp is
in counts. These boxes are used to define and map time-amp areas into graphical
areas defined by 2-D boxes defined in terms of pixels in Height and Width.
We use 3 WFSelectionBox'es:
1) dataBox - defines the extent of the waveform data in time and amp.
If there is no waveform this is null as tested by 'dataBox.isNull()'
2) panelBox - defines the time-amp bounds of this WFPanel. Normally it is
the same as the dataBox for a zoomPanel. For a WFPanel in a
GroupPanel the panelBox time bounds will usually be equal to the
exteme bounds of the ViewList. This insures all data is visable and
time aligned. For dataless WFPanels the amp dimension is problematic
and is arbitrarily set to +100/-100 counts.
3) viewBox - defines the bounds of the view. For example, in a zoomed
panel the viewbox represents the JViewport and the WFPanel expands
to accomodate the scaling of the viewBox to the JViewport. This is
only used by ActiveWFPanels.
panelBox
+===================================================================+
| |
| +-----------------+ |
| |dataBox | |
| | | |
| +-----------------+ |
| |
+===================================================================+
*/
/**
* Constructors
*/
public WFPanel (){
setBackground(unselectedColor);
setForeground(WFColor);
setSize(initPanelWidth, initPanelHeight);
setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
// addWFLoadListener();
}
public WFPanel (WFView wfview) {
this();
setWFView (wfview);
}
/** Return true if this panel is selected. */
public boolean isSelected() {
return amSelected;
}
// -------------------------------------------------------------------
/**
* Set or change the WFView to be displayed in this WFPanel.
*/
public void setWFView (WFView wfview) {
wfv = wfview;
if (wfv == null) {
clear();
return; // signal to GC to erase old view
}
setMasterView(wfv.mv);
// add change listener to waveform object to handle async. load/unloading
addWFLoadListener();
setupWf ();
WFColor = ComponentColor.get(wfv.getChannelObj()); // get proper color for this component
// this seems logical...
repaint();
}
/** Set data and panel box sizes and creates alternate (filtered) waveform if a filter exists.
* Which will actually be displayed is toggled with setShowAlternateWf(). */
public void setupWf() {
createAlternateWf(); // only done if a filter is set and there is timeseries
// set box bounds based on the data
dataBox.set(getWf()); // a null wf is OK here
setPanelBoxSize();
((WFRowHeader)getRowHeader()).setDefaultText();
}
/** Create and setup the alternate (filtered) waveform. */
void createAlternateWf() {
if (filter != null && getRawWf() != null) {
alternateWf = Waveform.copy(getRawWf()); // copy
// filter the time series of the new waveform
alternateWf.filter(filter.getFilter((int) alternateWf.getSampleRate()));
// set max, min, bias values // scan
/* done by filtering
if (alternateWf.hasTimeSeries()) {
alternateWf.scanForAmps();
alternateWf.scanForBias();
}
*/
}
}
/**
* Add the listener that handles waveform load events. This is to support
* asynchronous loading of timeseries in background. */
// private void addWFLoadListener () {
protected void addWFLoadListener () {
if (getRawWf() != null) {
getRawWf().addChangeListener (new WFLoadListener());
}
}
/** INNER CLASS: Change events are expected from Waveform objects when the
* timeseries is loaded. Repaint the WFPanel when timeseries shows up.
* This is to support asynchronous loading of timeseries in background. */
class WFLoadListener implements ChangeListener {
public void stateChanged (ChangeEvent changeEvent) {
setupWf();
// setShowAlternateWf(getShowAlternateWf()); // force selection of proper WF
// repaint();
}
}
/** Set the filter to be used to create the alternate waveform. You only need
* to do this once. */
public void setFilter(FilterIF filter) {
this.filter = filter;
if (filter != null) {
createAlternateWf();
}
}
public void setShowTimeScale (boolean tf) {
if (showTimeScale != tf) {
showTimeScale = tf;
// repaint();
}
}
public boolean getShowTimeScale() {
return showTimeScale;
}
public void setShowSamples (boolean tf) {
showSamples = tf;
}
public boolean getShowSamples() {
return showSamples;
}
public void setShowAmpScale (boolean tf) {
if (showAmpScale != tf) {
showAmpScale = tf;
}
}
public boolean getShowAmpScale() {
return showAmpScale;
}
public void setShowTimeLabel (boolean tf) {
if (showTimeLabel != tf) {
showTimeLabel = tf;
// repaint();
}
}
public boolean getShowTimeLabel() {
return showTimeLabel;
}
public void setShowChannelLabel (boolean tf) {
if (showChannelLabel != tf) {
showChannelLabel = tf;
// repaint();
}
}
public boolean getShowChannelLabel() {
return showChannelLabel;
}
public void setShowSegments (boolean tf) {
if (showSegments != tf) {
showSegments = tf;
// repaint();
}
}
public boolean getShowSegments() {
return showSegments;
}
public void setShowPhaseCues(boolean tf) {
if (showPhaseCues != tf) {
showPhaseCues = tf;
// repaint();
}
}
public boolean getShowPhaseCues() {
return showPhaseCues;
}
/** Show alternate trace if set true. */
public void setShowAlternateWf( boolean tf) {
if (showAlternateWf != tf) { // its a change
showAlternateWf = tf;
// set box bounds based on the current WF
dataBox.set (getWf()); // a null wf is OK here
setPanelBoxSize();
}
}
public boolean getShowAlternateWf() {
return showAlternateWf;
}
public Waveform getRawWf() {
if (wfv == null) return null;
return wfv.wf;
}
public Waveform getAlternateWf() {
return alternateWf;
}
/** Return the time of the sample nearest the pixel with he value of x. */
public double getSampletimeNearX (int x) {
double time = dtOfPixel(x);
// force click to be on a sample, if there's a waveform
if (getWf() != null) time = getWf().closestSampleInterval(time);
return time;
}
/** Returns the currently selected waveform (raw or filtered). All access to
* timeseries should be via this method because it determines which one
* to use. */
public Waveform getWf () {
if (getShowAlternateWf()) return getAlternateWf();
return getRawWf();
}
/** Change this panel's selection state. Just changes the background color to
* indicate the panel is selected then repaints. */
public void setSelected (boolean tf) {
if (tf == isSelected()) return; // no change, don't re-add listeners
amSelected = tf;
repaint();
}
public void setBackgroundColor (Color clr) {
backgroundColor = clr;
}
public Color getBackgroundColor() {
if (amSelected) {
return selectedColor;
} else {
// if (getShowAlternateWf()) return alternateUnselectedColor;
// Use logic to test that WF was ACTUALLY filtered not just that you asked that
// it be. This is because the filter may not work on this type of data.
// For example, WAFilter only works on 20, 80 & 100 sps data.
if (getWf() != null && getWf().isFiltered()) return alternateUnselectedColor;
return unselectedColor;
}
}
/**
* Set the size of the panel box.
*/
public void setPanelBoxSize () {
Waveform wf = getWf();
if (wf != null) {
panelBox.set(wfv.viewSpan, wf.getMaxAmp(), wf.getMinAmp());
} else {
// box must have non-zero dimension else /0 error happen elsewhere
panelBox.set(wfv.viewSpan, 1, 0);
}
}
/** Return a JPanel that acts as a row header in a scroll pane.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -