Sample Window Shortcut Panel Implementation
In this implementation, we provide an attributes shortcut panel for a FK window. This panel only contains two spinners to change the scale and a peel/reveal sub panel.
Extending AbstractViewerWindowAttributesShortcutPanel
The following panel class was created using the Netbeans Matisse editor, then customized to extend com.interactive.intviewerapi.editors.AbstractViewerWindowAttributesShortcutPanel.
XSECTIONWINDOWATTRIBUTESSHORTCUTPANEL.JAVA
/*
* XSectionWindowAttributesShortcutPanel.java
*
* Created on Mar 17, 2011, 4:27:49 PM
*/
package com.interactive.intviewer.seismic.editor.shortcut;
import com.interactive.intviewer.seismic.util.XSectionWindowUtil;
import com.interactive.intviewer.view2d.LayeredViewerWindow;
import com.interactive.intviewer.view2d.ViewerPlotXV;
import com.interactive.intviewer.view2d.XSectionLayeredWindow;
import com.interactive.intviewerapi.editors.AbstractViewerWindowAttributesShortcutPanel;
import com.interactive.intviewerapi.events.EventBroadcaster;
import com.interactive.intviewerapi.events.IEventSubscriber;
import com.interactive.intviewerapi.events.PropertyProviderEvent;
import com.interactive.intviewerapi.events.WindowScaleEvent;
import com.interactive.intviewerapi.layers.ISeismicLayer;
import java.awt.Toolkit;
import javax.swing.JSpinner;
import javax.swing.SwingConstants;
public class XSectionWindowAttributesShortcutPanel extends AbstractViewerWindowAttributesShortcutPanel {
private int pixelsPerInch;
private ViewerPlotXV plot;
private boolean isUnitImperial;
private String verticalUnitLabel;
private IEventSubscriber<WindowScaleEvent> subscriber;
// receives XSectionLayeredWindow so that it can be reused for FK display
public XSectionWindowAttributesShortcutPanel(XSectionLayeredWindow window) {
super(window);
initComponents();
initConstants();
initGUI();
this.setReady(true);
subscriber = new IEventSubscriber<WindowScaleEvent>() {
@Override
public void onEvent(WindowScaleEvent t) {
XSectionWindowAttributesShortcutPanel.this.setReady(false);
XSectionWindowAttributesShortcutPanel.this.initGUI();
XSectionWindowAttributesShortcutPanel.this.setReady(true);
}
};
EventBroadcaster.getInstance().subscribe(WindowScaleEvent.class, subscriber, true);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
xSectionWindowMoviePanel1 = new com.interactive.intviewer.seismic.editor.shortcut.XSectionWindowMoviePanel();
jLayeredPane1 = new javax.swing.JLayeredPane();
horizontalScaleLabel = new javax.swing.JLabel();
horizontalScaleSpinner = new javax.swing.JSpinner();
verticalScaleLabel = new javax.swing.JLabel();
verticalScaleSpinner = new javax.swing.JSpinner();
jLayeredPane1.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(XSectionWindowAttributesShortcutPanel.class, "XSectionWindowAttributesShortcutPanel.jLayeredPane1.border.title"))); // NOI18N
horizontalScaleLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
horizontalScaleLabel.setText(org.openide.util.NbBundle.getMessage(XSectionWindowAttributesShortcutPanel.class, "XSectionWindowAttributesShortcutPanel.horizontalScaleLabel.text_1")); // NOI18N
horizontalScaleLabel.setBounds(0, 20, 70, 20);
jLayeredPane1.add(horizontalScaleLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
horizontalScaleSpinner.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(50.0d), Double.valueOf(0.0010d), null, Double.valueOf(1.0d)));
horizontalScaleSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
horizontalScaleSpinnerStateChanged(evt);
}
});
horizontalScaleSpinner.setBounds(70, 20, 60, 20);
jLayeredPane1.add(horizontalScaleSpinner, javax.swing.JLayeredPane.DEFAULT_LAYER);
verticalScaleLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
verticalScaleLabel.setText(org.openide.util.NbBundle.getMessage(XSectionWindowAttributesShortcutPanel.class, "XSectionWindowAttributesShortcutPanel.verticalScaleLabel.text")); // NOI18N
verticalScaleLabel.setBounds(140, 20, 50, 20);
jLayeredPane1.add(verticalScaleLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
verticalScaleSpinner.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(50.0d), Double.valueOf(0.0010d), null, Double.valueOf(0.1d)));
verticalScaleSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
verticalScaleSpinnerStateChanged(evt);
}
});
verticalScaleSpinner.setBounds(190, 20, 60, 20);
jLayeredPane1.add(verticalScaleSpinner, javax.swing.JLayeredPane.DEFAULT_LAYER);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLayeredPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE)
.addComponent(xSectionWindowMoviePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(xSectionWindowMoviePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>
private void horizontalScaleSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {
if (!isReady()) {
return;
}
if (this.getViewerWindow() == null) {
return;
}
if (evt.getSource() != horizontalScaleSpinner) {
return;
}
ISeismicLayer layer = (ISeismicLayer) plot.getAxisLayer();
if (layer == null) {
return;
}
double userValue = new Double(horizontalScaleSpinner.getValue().toString());
double horizontalScale = XSectionWindowUtil.convertUserToPlotHorizontalScale(userValue, pixelsPerInch, isUnitImperial);
double verticalScale = plot.getVerticalScaleFactor();
EventBroadcaster.getInstance().unsubscribe(WindowScaleEvent.class, subscriber);
XSectionWindowUtil.scalePlot(plot, horizontalScale, verticalScale);
EventBroadcaster.getInstance().subscribe(WindowScaleEvent.class, subscriber);
}
private void verticalScaleSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {
if (!isReady()) {
return;
}
if (this.getViewerWindow() == null) {
return;
}
if (evt.getSource() != verticalScaleSpinner) {
return;
}
ISeismicLayer layer = (ISeismicLayer) plot.getAxisLayer();
if (layer == null) {
return;
}
float sampleRate = layer.getReader().getDataStatistics().getSampleRate();
double userValue = new Double(verticalScaleSpinner.getValue().toString());
double horizontalScale = plot.getHorizontalScaleFactor();
double verticalScale = XSectionWindowUtil.convertUserToPlotVerticalScale(userValue, pixelsPerInch, isUnitImperial,
sampleRate, verticalUnitLabel);
EventBroadcaster.getInstance().unsubscribe(WindowScaleEvent.class, subscriber);
XSectionWindowUtil.scalePlot(plot, horizontalScale, verticalScale);
EventBroadcaster.getInstance().subscribe(WindowScaleEvent.class, subscriber);
}
// Variables declaration - do not modify
private javax.swing.JLabel horizontalScaleLabel;
private javax.swing.JSpinner horizontalScaleSpinner;
private javax.swing.JLayeredPane jLayeredPane1;
private javax.swing.JLabel verticalScaleLabel;
private javax.swing.JSpinner verticalScaleSpinner;
private com.interactive.intviewer.seismic.editor.shortcut.XSectionWindowMoviePanel xSectionWindowMoviePanel1;
// End of variables declaration
private void initGUI() {
ISeismicLayer layer = (ISeismicLayer) plot.getAxisLayer();
if (layer == null) {
return;
}
float sampleRate = layer.getReader().getDataStatistics().getSampleRate();
double horizontalValue = XSectionWindowUtil.convertPlotToUserHorizontalScale(plot.getHorizontalScaleFactor(), pixelsPerInch, isUnitImperial);
double verticalValue = XSectionWindowUtil.convertPlotToUserVerticalScale(plot.getVerticalScaleFactor(), pixelsPerInch, isUnitImperial, sampleRate, verticalUnitLabel);
this.horizontalScaleSpinner.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(50.0d), Double.valueOf(0.0010d), null, horizontalValue / 20d));
this.verticalScaleSpinner.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(50.0d), Double.valueOf(0.0010d), null, verticalValue / 20d));
this.horizontalScaleSpinner.setValue(horizontalValue);
this.verticalScaleSpinner.setValue(verticalValue);
JSpinner.NumberEditor horizontalEditor = (JSpinner.NumberEditor) horizontalScaleSpinner.getEditor();
horizontalEditor.getTextField().setHorizontalAlignment(SwingConstants.CENTER);
JSpinner.NumberEditor verticalEditor = (JSpinner.NumberEditor) verticalScaleSpinner.getEditor();
verticalEditor.getTextField().setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
protected void processEvent(PropertyProviderEvent e) {
// ignore, we only care about scale events
}
private void initConstants() {
this.pixelsPerInch = Toolkit.getDefaultToolkit().getScreenResolution();
this.plot = (ViewerPlotXV) ((LayeredViewerWindow) this.getViewerWindow()).getViewerPlot();
String horizontalScaleUnit = plot.getHorizontalScaleUnit(); // should not change, even when preferences are changed
String verticalScaleUnit = plot.getVerticalScaleUnit(); // should not change, even when preferences are changed
this.horizontalScaleLabel.setToolTipText("in " + horizontalScaleUnit);
this.verticalScaleLabel.setToolTipText("in " + verticalScaleUnit);
this.verticalUnitLabel = plot.getCurrentVerticalUnitLabel();
this.isUnitImperial = plot.isUnitImperial(); // should not change, even when preferences are changed
}
@Override
public void dispose() {
EventBroadcaster.getInstance().unsubscribe(WindowScaleEvent.class, subscriber);
super.dispose();
this.plot = null;
}
}
Extending AbstractViewerWindowAttributesShortcutEditor
The following editor class does a lazy-instantiation of the panel created earlier.
XSECTIONWINDOWATTRIBUTESSHORTCUTEDITOR.JAVA
package com.interactive.intviewer.seismic.editor.shortcut;
import com.interactive.intviewer.view2d.XSectionLayeredWindow;
import com.interactive.intviewer.view2d.actions.XSectionAnnotationAction;
import com.interactive.intviewerapi.editors.AbstractViewerWindowAttributesShortcutEditor;
import javax.swing.JComponent;
public class XSectionWindowAttributesShortcutEditor extends AbstractViewerWindowAttributesShortcutEditor {
private XSectionWindowAttributesShortcutPanel panel;
public XSectionWindowAttributesShortcutEditor(XSectionLayeredWindow window) {
super(window);
}
@Override
public JComponent getComponent() {
if (panel == null) {
panel = new XSectionWindowAttributesShortcutPanel((XSectionLayeredWindow) this.getViewerWindow());
}
return panel;
}
@Override
public void showDialog() {
XSectionAnnotationAction.setObjectEditorNodeVisible((XSectionLayeredWindow) this.getViewerWindow());
}
@Override
public void dispose() {
super.dispose();
panel = null;
}
}
Implementing IAttributesShortcutAdapter
The following adapter class verifies that the object is a FK window, and vends the editor created earlier.
FKWINDOWSHORTCUTADAPTER.JAVA
package com.interactive.intviewer.fk.editor.shortcut;
import com.interactive.intviewer.fk.FKWindow;
import com.interactive.intviewer.seismic.editor.shortcut.XSectionWindowAttributesShortcutEditor;
import com.interactive.intviewerapi.editors.IAttributesShortcutAdapter;
import com.interactive.intviewerapi.editors.IAttributesShortcutProvider;
import com.interactive.intviewerapi.windows.IFKWindow;
public class FKWindowShortcutAdapter implements IAttributesShortcutAdapter {
@Override
public Class<?> getSupportedClass() {
return FKWindow.class;
}
@Override
public boolean canProcess(Object o) {
return (o instanceof FKWindow);
}
@Override
public IAttributesShortcutProvider getProvider(Object o) {
if (o instanceof FKWindow) {
return new FKWindowShortcutProvider((FKWindow) o);
} else {
return null;
}
}
static class FKWindowShortcutProvider implements IAttributesShortcutProvider {
IFKWindow window;
public FKWindowShortcutProvider(IFKWindow window) {
this.window = window;
}
@Override
public IAttributesShortcutEditor[] getEditors() {
return new IAttributesShortcutEditor[]{new XSectionWindowAttributesShortcutEditor((FKWindow) window)};
}
}
}
Important: In the getSupportedClass method, indicate the implementation class, not the interface. To get the implementation class of a window, use window.getClass().
Registering the adapter
The following layer registration adds the adapter created earlier to the INTViewer desktop.
LAYER.XML
<filesystem>
<folder name="ShortcutEditors">
<folder name="WindowShortcut">
<file name="com-interactive-intviewer-fk-editor-shortcut-FKWindowShortcutAdapter.instance"/>
</folder>
</folder>
</filesystem>