Java tutorial
/* * Conditions Of Use * * This software was developed by employees of the National Institute of * Standards and Technology (NIST), and others. * This software has been contributed to the public domain. * Pursuant to title 15 Untied States Code Section 105, works of NIST * employees are not subject to copyright protection in the United States * and are considered to be in the public domain. * As a result, a formal license is not needed to use this software. * * This software is provided "AS IS." * NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT * AND DATA ACCURACY. NIST does not warrant or make any representations * regarding the use of the software or the results thereof, including but * not limited to the correctness, accuracy, reliability or usefulness of * this software. */ package gov.nist.spectrumbrowser.client; import gov.nist.spectrumbrowser.common.AbstractSpectrumBrowserScreen; import gov.nist.spectrumbrowser.common.SpectrumBrowserCallback; import gov.nist.spectrumbrowser.common.SpectrumBrowserScreen; import java.util.List; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.core.client.Duration; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.ImageElement; import com.google.gwt.dom.client.Style.Cursor; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.ErrorEvent; import com.google.gwt.event.dom.client.ErrorHandler; import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.MenuBar; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TabLayoutPanel; import com.google.gwt.user.client.ui.TabPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.googlecode.gwt.charts.client.ChartLoader; import com.googlecode.gwt.charts.client.ChartPackage; import com.googlecode.gwt.charts.client.ColumnType; import com.googlecode.gwt.charts.client.DataTable; import com.googlecode.gwt.charts.client.Selection; import com.googlecode.gwt.charts.client.corechart.ScatterChart; import com.googlecode.gwt.charts.client.corechart.ScatterChartOptions; import com.googlecode.gwt.charts.client.event.SelectEvent; import com.googlecode.gwt.charts.client.event.SelectHandler; import com.googlecode.gwt.charts.client.options.HAxis; import com.googlecode.gwt.charts.client.options.Legend; import com.googlecode.gwt.charts.client.options.LegendPosition; import com.googlecode.gwt.charts.client.options.VAxis; import com.kiouri.sliderbar.client.event.BarValueChangedEvent; import com.kiouri.sliderbar.client.event.BarValueChangedHandler; import com.kiouri.sliderbar.client.solution.simplevertical.SliderBarSimpleVertical; import com.reveregroup.gwt.imagepreloader.FitImage; import com.reveregroup.gwt.imagepreloader.ImageLoadEvent; import com.reveregroup.gwt.imagepreloader.ImageLoadHandler; import com.reveregroup.gwt.imagepreloader.ImagePreloader; public class SweptFrequencyOneDaySpectrogramChart extends AbstractSpectrumBrowserScreen implements SpectrumBrowserCallback<String> { private static final String END_LABEL = "Single Day Spectrogram"; String mSensorId; SpectrumBrowser mSpectrumBrowser; long mSelectionTime; JSONValue jsonValue; private double currentTime; private float currentFreq; private VerticalPanel spectrumAndOccupancyPanel; int cutoff; int maxPower; int occupancyMinPower; Label infoLabel = new Label("Click on spectrogram for power spectrum."); HorizontalPanel hpanel; // = new HorizontalPanel(); VerticalPanel vpanel;// = new VerticalPanel(); long maxTime; double minFreqMhz; double maxFreqMhz; int timeDelta; private double yPixelsPerMegahertz; private int canvasPixelWidth; private int canvasPixelHeight; private Label maxPowerLabel; private Label minPowerLabel; private VerticalPanel spectrogramPanel; private VerticalPanel freqPanel; private HorizontalPanel powerMapPanel; private Canvas spectrogramCanvas; private HorizontalPanel xaxisPanel; private Image powerMapImage; private Image spectrogramImage; private String localDateOfAcquisition; private String cmapUrl; private String spectrogramUrl; private VerticalPanel occupancyPanel; private SliderBarSimpleVertical occupancyMinPowerSliderBar; private Label occupancyMinPowerLabel; private VerticalPanel occupancyMinPowerVpanel; private int minPower; private int noiseFloor; private long prevAcquisitionTime; private long nextAcquisitionTime; private ArrayList<Double> timeArray; private ArrayList<Double> occupancyArray; private List<String> tabSArray = new ArrayList<String>(); private List<String> tabOArray = new ArrayList<String>(); private ScatterChart occupancyChart; private TabPanel tabPanel; private VerticalPanel spectrogramVerticalPanel; private ArrayList<Double> tabSelection; private long tStartTimeUtc; private Grid grid; private long mMinFreq; private long mMaxFreq; private long mSubBandMinFreq; private long mSubBandMaxFreq; private int acquisitionCount; private float maxOccupancy; private float minOccupancy; private float meanOccupancy; private float medianOccupancy; private float enbw; private float rbw; private String mSys2detect; private Timer timer; private ArrayList<SpectrumBrowserScreen> navigation; private double mLat; private double mLon; private double mAlt; private static final String COMPUTING_PLEASE_WAIT = "Computing Spectrogram. Please wait."; private static Logger logger = Logger.getLogger("SpectrumBrowser"); /** * Update the time and frequency readings on top of the plot if the user * moves the mouse around in the canvas area. * */ public class SurfaceMouseMoveHandlerImpl implements MouseMoveHandler { @Override public void onMouseMove(MouseMoveEvent event) { int timeCoord = event.getRelativeX(event.getRelativeElement()); int freqCoord = event.getRelativeY(event.getRelativeElement()); double xratio = ((double) timeCoord / (double) canvasPixelWidth); double yratio = 1.0 - ((double) freqCoord / (double) canvasPixelHeight); currentFreq = (float) (((maxFreqMhz - minFreqMhz) * yratio) + minFreqMhz); currentTime = (((double) (maxTime * xratio))); NumberFormat nf = NumberFormat.getFormat("00.00"); infoLabel.setText( "Hours Since Start of Day= " + nf.format(currentTime) + " ; Freq = " + currentFreq + " MHz"); } } /* * Callback for the selector that controls the cutoff power. */ public class OccupancyMinPowerSliderHandler implements BarValueChangedHandler { Label occupancyMinPowerLabel; int initValue; boolean firstUpdate = true; public OccupancyMinPowerSliderHandler(Label occupancyMinPowerLabel, int initValue) { occupancyMinPowerSliderBar.setValue(100); this.occupancyMinPowerLabel = occupancyMinPowerLabel; occupancyMinPowerLabel.setText(minPower + " dBm"); this.occupancyMinPowerLabel.setTitle("Power Cutoff for Occupancy Graph"); this.initValue = initValue; } @Override public void onBarValueChanged(BarValueChangedEvent event) { try { if (!firstUpdate) { int occupancyBarValue = occupancyMinPowerSliderBar.getValue(); logger.log(Level.FINEST, "bar value changed new value is " + occupancyBarValue); occupancyMinPower = (int) ((1 - (double) occupancyBarValue / 100.0) * (maxPower - minPower) + minPower); occupancyMinPowerLabel.setText(Integer.toString((int) occupancyMinPower) + " dBm"); } else { firstUpdate = false; occupancyMinPower = initValue; occupancyMinPowerLabel.setText(Integer.toString(initValue) + " dBm"); } } catch (Exception ex) { logger.log(Level.SEVERE, " Exception ", ex); } } } public SweptFrequencyOneDaySpectrogramChart(String sensorId, double lat, double lon, double alt, long selectionTime, String sys2detect, long minFreq, long maxFreq, long subBandMinFreq, long subBandMaxFreq, VerticalPanel verticalPanel, SpectrumBrowser spectrumBrowser, ArrayList<SpectrumBrowserScreen> navigation) { super.setNavigation(verticalPanel, navigation, spectrumBrowser, END_LABEL); this.navigation = new ArrayList<SpectrumBrowserScreen>(navigation); this.navigation.add(this); logger.finer("SweptFrequencyOneDaySpectrogramChart: sensorId : " + sensorId); mSensorId = sensorId; mLat = lat; mLon = lon; mAlt = alt; mSelectionTime = selectionTime; vpanel = verticalPanel; mSpectrumBrowser = spectrumBrowser; mMinFreq = minFreq; mMaxFreq = maxFreq; mSys2detect = sys2detect; mSubBandMinFreq = subBandMinFreq; mSubBandMaxFreq = subBandMaxFreq; minFreqMhz = (double) (mSubBandMinFreq) / 1E6; maxFreqMhz = (double) (mSubBandMaxFreq) / 1E6; logger.finer("minFreq = " + minFreq + " minFreqMhz " + minFreqMhz + " maxFeq " + maxFreq + " maxFreqMhz " + maxFreqMhz); mSpectrumBrowser.getSpectrumBrowserService().generateSingleDaySpectrogramAndOccupancy(sensorId, mLat, mLon, mAlt, mSelectionTime, mSys2detect, mMinFreq, mMaxFreq, mSubBandMinFreq, mSubBandMaxFreq, this); } @Override public void onSuccess(String result) { try { Duration duration = new Duration(); // logger.finer("result = " + result); jsonValue = JSONParser.parseLenient(result); timeDelta = (int) jsonValue.isObject().get("timeDelta").isNumber().doubleValue(); spectrogramUrl = jsonValue.isObject().get("spectrogram").isString().stringValue(); canvasPixelWidth = (int) jsonValue.isObject().get("image_width").isNumber().doubleValue(); canvasPixelHeight = (int) jsonValue.isObject().get("image_height").isNumber().doubleValue(); cmapUrl = jsonValue.isObject().get("cbar").isString().stringValue(); maxPower = (int) jsonValue.isObject().get("maxPower").isNumber().doubleValue(); cutoff = (int) jsonValue.isObject().get("cutoff").isNumber().doubleValue(); minPower = (int) jsonValue.isObject().get("minPower").isNumber().doubleValue(); localDateOfAcquisition = jsonValue.isObject().get("formattedDate").isString().stringValue(); prevAcquisitionTime = (long) jsonValue.isObject().get("prevAcquisition").isNumber().doubleValue(); nextAcquisitionTime = (long) jsonValue.isObject().get("nextAcquisition").isNumber().doubleValue(); tStartTimeUtc = (long) jsonValue.isObject().get("tStartTimeUtc").isNumber().doubleValue(); acquisitionCount = (int) jsonValue.isObject().get("aquisitionCount").isNumber().doubleValue(); minOccupancy = round(jsonValue.isObject().get("minOccupancy").isNumber().doubleValue() * 100); maxOccupancy = round(jsonValue.isObject().get("maxOccupancy").isNumber().doubleValue() * 100); meanOccupancy = round(jsonValue.isObject().get("meanOccupancy").isNumber().doubleValue() * 100); medianOccupancy = round(jsonValue.isObject().get("medianOccupancy").isNumber().doubleValue() * 100); enbw = round(jsonValue.isObject().get("ENBW").isNumber().doubleValue()); rbw = round(jsonValue.isObject().get("RBW").isNumber().doubleValue()); maxTime = timeDelta; timeArray = new ArrayList<Double>(); occupancyArray = new ArrayList<Double>(); int nvalues = jsonValue.isObject().get("timeArray").isArray().size(); for (int i = 0; i < nvalues; i++) { timeArray.add(jsonValue.isObject().get("timeArray").isArray().get(i).isNumber().doubleValue()); occupancyArray .add(jsonValue.isObject().get("occupancyArray").isArray().get(i).isNumber().doubleValue()); } long elapsedTime = duration.elapsedMillis(); logger.finer("Unpacking json object took " + elapsedTime); } catch (Throwable throwable) { logger.log(Level.SEVERE, result); logger.log(Level.SEVERE, "Error parsing json result from server", throwable); mSpectrumBrowser.displayError("Error parsing JSON"); } draw(); } /** * This is called after the spectrogram has loaded from the server. Also * gets called when we want to redraw the spectrogram. * */ private void handleSpectrogramLoadEvent() { RootPanel.get().remove(spectrogramImage); spectrogramImage.setVisible(true); ImageElement imageElement = ImageElement.as(spectrogramImage.getElement()); Canvas canvas = Canvas.createIfSupported(); canvas.getElement().getStyle().setCursor(Cursor.CROSSHAIR); if (spectrogramCanvas != null) { spectrogramPanel.remove(spectrogramCanvas); spectrogramPanel.remove(xaxisPanel); } spectrogramCanvas = canvas; spectrogramCanvas.setCoordinateSpaceHeight(canvasPixelHeight); spectrogramCanvas.setCoordinateSpaceWidth(canvasPixelWidth); spectrogramCanvas.addMouseMoveHandler(new SurfaceMouseMoveHandlerImpl()); spectrogramCanvas.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { logger.finer("OneAcquisitionSpegrogramChart: clickHandler"); if (currentFreq <= 0) { logger.finer("Freq is 0 -- doing nothing"); return; } VerticalPanel powerVsTimeHpanel = new VerticalPanel(); new PowerSpectrum(mSpectrumBrowser, powerVsTimeHpanel, mSensorId, tStartTimeUtc, currentTime, mSubBandMinFreq, mSubBandMaxFreq, canvasPixelWidth, canvasPixelHeight); new PowerVsTime(mSpectrumBrowser, powerVsTimeHpanel, mSensorId, tStartTimeUtc, (long) (currentFreq * 1E6), canvasPixelWidth, canvasPixelHeight); String ct = NumberFormat.getFormat("00.00").format(currentTime) + " Hours"; if (tabSArray.isEmpty() || !tabSArray.contains(ct)) { tabSArray.add(ct); tabPanel.add(powerVsTimeHpanel, NumberFormat.getFormat("00.00").format(currentTime) + " Hours"); } } }); spectrogramCanvas.getContext2d().drawImage(imageElement, 0, 0); spectrogramCanvas.getContext2d().rect(0, 0, canvasPixelWidth, canvasPixelHeight); spectrogramPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); spectrogramPanel.clear(); spectrogramPanel.setHeight(canvasPixelHeight + "px"); spectrogramPanel.add(spectrogramCanvas); spectrogramPanel.add(xaxisPanel); freqPanel.setHeight(canvasPixelHeight + "px"); logger.log(Level.FINER, "Image Height " + canvasPixelHeight); yPixelsPerMegahertz = (double) (canvasPixelHeight) / (double) (maxFreqMhz - minFreqMhz); logger.finer("yPixelsPerMegaherz = " + yPixelsPerMegahertz + "canvasPixelHeight " + canvasPixelHeight); if (cmapUrl != null) { ImagePreloader.load(cmapUrl, new ImageLoadHandler() { @Override public void imageLoaded(ImageLoadEvent event) { FitImage image = new FitImage(); // TODO -- make this width part of CSS //image.setFixedWidth(30); image.setHeight(canvasPixelHeight + "px"); image.setUrl(event.getImageUrl()); image.setPixelSize(40, canvasPixelHeight); ImageElement imageElement = ImageElement.as(image.getElement()); imageElement.setAttribute("HEIGHT", canvasPixelHeight + "px"); image.setVisible(true); if (powerMapImage != null) { powerMapPanel.remove(powerMapImage); } powerMapPanel.add(image); powerMapImage = image; powerMapPanel.setHeight(canvasPixelHeight + "px"); } }); } mSpectrumBrowser.hideWaitImage(); } private void setSpectrogramImage() { try { spectrogramImage = new FitImage(); // spectrogramImage.setWidth(canvasPixelWidth + "px"); spectrogramImage.setPixelSize(canvasPixelWidth, canvasPixelHeight); // spectrogramImage.setFixedWidth(canvasPixelWidth); spectrogramImage.addLoadHandler(new LoadHandler() { @Override public void onLoad(LoadEvent event) { logger.fine("Image loaded"); handleSpectrogramLoadEvent(); } }); spectrogramImage.setVisible(false); ImageElement imageElement = ImageElement.as(spectrogramImage.getElement()); imageElement.setAttribute("HEIGHT", canvasPixelHeight + "px"); spectrogramImage.setHeight(canvasPixelHeight + "px"); logger.log(Level.FINER, "Setting URL " + spectrogramUrl); spectrogramImage.addErrorHandler(new ErrorHandler() { @Override public void onError(ErrorEvent event) { logger.log(Level.SEVERE, "Error loading image"); Window.alert("Error loading image"); } }); spectrogramImage.setUrl(spectrogramUrl); RootPanel.get().add(spectrogramImage); } catch (Exception ex) { logger.log(Level.SEVERE, "Error retrieving image", ex); } } private void drawOccupancyChart() { final DataTable dataTable = DataTable.create(); dataTable.addColumn(ColumnType.NUMBER, " Hours since start of day."); dataTable.addColumn(ColumnType.NUMBER, " Occupancy %"); dataTable.addRows(timeArray.size()); for (int i = 0; i < timeArray.size(); i++) { dataTable.setCell(i, 0, round2(timeArray.get(i)), round2(timeArray.get(i)) + " hours since start of day "); dataTable.setCell(i, 1, (float) round2(occupancyArray.get(i) * 100), (float) (round2(occupancyArray.get(i) * 100)) + " % occupancy"); } ChartLoader chartLoader = new ChartLoader(ChartPackage.CORECHART); chartLoader.loadApi(new Runnable() { @Override public void run() { occupancyChart = new ScatterChart(); occupancyChart.setWidth(canvasPixelWidth + "px"); occupancyChart.setHeight(canvasPixelHeight + "px"); occupancyChart.setPixelSize(canvasPixelWidth, canvasPixelHeight); ScatterChartOptions options = ScatterChartOptions.create(); options.setBackgroundColor("#f0f0f0"); options.setPointSize(2); options.setWidth(canvasPixelWidth); options.setHeight(canvasPixelHeight); Legend legend = Legend.create(LegendPosition.NONE); options.setLegend(legend); options.setHAxis(HAxis.create("Hours Since Start of day")); options.setVAxis(VAxis.create("Occupancy %")); occupancyChart.setStyleName("lineChart"); occupancyChart.draw(dataTable, options); occupancyChart.setVisible(true); occupancyPanel.add(occupancyChart); occupancyChart.addSelectHandler(new SelectHandler() { @Override public void onSelect(SelectEvent event) { if (timer != null && timer.isRunning()) { return; } timer = new Timer() { @Override public void run() { JsArray<Selection> selection = occupancyChart.getSelection(); if (selection == null) { return; } int row = selection.get(0).getRow(); currentTime = timeArray.get(row); logger.finer("OneAcquisitionSpegrogramChart: clickHandler"); VerticalPanel spectrumHpanel = new VerticalPanel(); new PowerSpectrum(mSpectrumBrowser, spectrumHpanel, mSensorId, tStartTimeUtc, currentTime, mSubBandMinFreq, mSubBandMaxFreq, canvasPixelWidth, canvasPixelHeight); String ct = NumberFormat.getFormat("00.00").format(currentTime) + " Hours"; if (tabOArray.isEmpty() || !tabOArray.contains(ct)) { tabOArray.add(ct); tabPanel.add(spectrumHpanel, ct); } } }; timer.schedule(500); } }); } }); } public void draw() { try { vpanel.clear(); drawNavigation(); HTML pageTitle = new HTML("<h2>" + END_LABEL + "</h2>"); vpanel.add(pageTitle); HTML title = new HTML("<H3>Detected System = " + mSys2detect + "; Start Time = " + localDateOfAcquisition + "; Occupancy Threshold = " + cutoff + " dBm; minPower = " + minPower + " dBm; maxPower = " + maxPower + " dBm</H3>"); vpanel.add(title); HTML title1 = new HTML("<h3>Aquisition Count = " + acquisitionCount + "; max occupancy = " + maxOccupancy + "%; min occupancy = " + minOccupancy + "%; mean occupancy = " + meanOccupancy + "%; median occupancy = " + medianOccupancy + "%</h3>"); vpanel.add(title1); HTML title3 = new HTML("<h3> Equiv. Noise BW = " + enbw + " Hz; Resolution BW = " + rbw + " Hz. </h3>"); vpanel.add(title3); HTML help = new HTML("<p>Click on spectrogram or occupancy plot for detail. " + "Move slider and and click on redraw button to change threshold and redraw.</p>"); vpanel.add(help); grid = new Grid(1, 4); vpanel.add(grid); grid.setStyleName("selectionGrid"); for (int i = 0; i < grid.getRowCount(); i++) { for (int j = 0; j < grid.getColumnCount(); j++) { grid.getCellFormatter().setHorizontalAlignment(i, j, HasHorizontalAlignment.ALIGN_CENTER); grid.getCellFormatter().setVerticalAlignment(i, j, HasVerticalAlignment.ALIGN_MIDDLE); } } spectrogramVerticalPanel = new VerticalPanel(); hpanel = new HorizontalPanel(); hpanel.setSpacing(10); hpanel.setStyleName("spectrogram"); xaxisPanel = new HorizontalPanel(); xaxisPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); HorizontalPanel xaxis = new HorizontalPanel(); xaxis.setWidth(canvasPixelWidth + 30 + "px"); xaxis.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); xaxis.add(new Label("0")); xaxis.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); xaxis.add(new Label("Time (hours) since start of day")); xaxis.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); xaxis.add(new Label(Double.toString(timeDelta))); xaxisPanel.add(xaxis); // Attach the previous reading button. if (prevAcquisitionTime != tStartTimeUtc) { final Button prevDayButton = new Button(); prevDayButton.setEnabled(true); prevDayButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { mSelectionTime = prevAcquisitionTime; mSpectrumBrowser.showWaitImage(); infoLabel.setText(COMPUTING_PLEASE_WAIT); mSpectrumBrowser.getSpectrumBrowserService().generateSingleDaySpectrogramAndOccupancy( mSensorId, mLat, mLon, mAlt, prevAcquisitionTime, mSys2detect, mMinFreq, mMaxFreq, mSubBandMinFreq, mSubBandMaxFreq, cutoff, SweptFrequencyOneDaySpectrogramChart.this); } }); prevDayButton.setText("< Previous Day"); grid.setWidget(0, 0, prevDayButton); } // Attach the labels for the spectrogram power VerticalPanel powerLevelPanel = new VerticalPanel(); powerLevelPanel.setWidth(100 + "px"); this.maxPowerLabel = new Label(); this.minPowerLabel = new Label(); powerLevelPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); powerLevelPanel.add(maxPowerLabel); powerLevelPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); powerLevelPanel.add(new Label("Power (dBm) ")); powerLevelPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); powerLevelPanel.add(minPowerLabel); // Attach labels for the frequency. freqPanel = new VerticalPanel(); freqPanel.setWidth(100 + "px"); powerLevelPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); freqPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); freqPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); freqPanel.add(new Label(Double.toString(maxFreqMhz))); freqPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); freqPanel.add(new Label("Frequency (MHz)")); freqPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); freqPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); freqPanel.add(new Label(Double.toString(minFreqMhz))); logger.finest("minFreq = " + minFreqMhz); powerMapPanel = new HorizontalPanel(); powerMapPanel.setWidth(30 + "px"); hpanel.add(freqPanel); spectrogramPanel = new VerticalPanel(); HorizontalPanel spectrogramAndPowerMapPanel = new HorizontalPanel(); spectrogramAndPowerMapPanel.add(spectrogramPanel); spectrogramAndPowerMapPanel.add(powerMapPanel); hpanel.add(spectrogramAndPowerMapPanel); infoLabel = new Label("Click on spectrogram for power spectrum at selected time."); spectrogramVerticalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); spectrogramVerticalPanel.add(infoLabel); spectrogramVerticalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); spectrogramVerticalPanel.add(hpanel); String helpString = "Single click for power spectrum."; String powerString = "Single click for power occupancy."; // Add the slider bar for min occupancy selection. occupancyMinPowerVpanel = new VerticalPanel(); occupancyMinPowerVpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); occupancyMinPowerVpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); occupancyMinPowerSliderBar = new SliderBarSimpleVertical(100, canvasPixelHeight + "px", true); occupancyMinPowerVpanel.add(occupancyMinPowerSliderBar); occupancyMinPowerSliderBar.setMaxValue(100); this.occupancyMinPowerLabel = new Label(); occupancyMinPowerVpanel.add(occupancyMinPowerLabel); final Button generateSpectrogramButton = new Button("Cutoff and Redraw"); grid.setWidget(0, 1, generateSpectrogramButton); generateSpectrogramButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { generateSpectrogramButton.setEnabled(false); mSpectrumBrowser.showWaitImage(); mSpectrumBrowser.getSpectrumBrowserService().generateSingleDaySpectrogramAndOccupancy(mSensorId, mLat, mLon, mAlt, mSelectionTime, mSys2detect, mMinFreq, mMaxFreq, mSubBandMinFreq, mSubBandMaxFreq, occupancyMinPower, SweptFrequencyOneDaySpectrogramChart.this); } }); // Close all the tabs. final Button closeTabsButton = new Button("Close Tabs"); closeTabsButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { tabPanel.clear(); tabPanel.add(spectrogramVerticalPanel, "[Spectrogram]"); tabPanel.add(occupancyPanel, "[Occupancy]"); tabPanel.selectTab(0); } }); grid.setWidget(0, 2, closeTabsButton); occupancyMinPowerSliderBar .addBarValueChangedHandler(new OccupancyMinPowerSliderHandler(occupancyMinPowerLabel, cutoff)); int initialValue = (int) ((double) (maxPower - cutoff) / (double) (maxPower - minPower) * 100 + 0.5); occupancyMinPowerSliderBar.setValue(initialValue); hpanel.add(occupancyMinPowerVpanel); spectrogramPanel.setTitle(helpString); //powerMapPanel.setTitle(helpString); spectrumAndOccupancyPanel = new VerticalPanel(); spectrumAndOccupancyPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); spectrogramVerticalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); spectrogramVerticalPanel.add(spectrumAndOccupancyPanel); occupancyPanel = new VerticalPanel(); occupancyPanel.setWidth(canvasPixelWidth + "px"); occupancyPanel.setHeight(canvasPixelHeight + "px"); occupancyPanel.setPixelSize(canvasPixelWidth, canvasPixelHeight); occupancyPanel.setTitle(powerString); // Attach the next spectrogram panel. if (nextAcquisitionTime != tStartTimeUtc) { final Button nextDayButton = new Button(); nextDayButton.setEnabled(true); nextDayButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { logger.finer("getting next spectrogram"); try { mSelectionTime = nextAcquisitionTime; nextDayButton.setEnabled(false); mSpectrumBrowser.showWaitImage(); infoLabel.setText(COMPUTING_PLEASE_WAIT); mSpectrumBrowser.getSpectrumBrowserService().generateSingleDaySpectrogramAndOccupancy( mSensorId, mLat, mLon, mAlt, nextAcquisitionTime, mSys2detect, mMinFreq, mMaxFreq, mSubBandMinFreq, mSubBandMaxFreq, cutoff, SweptFrequencyOneDaySpectrogramChart.this); } catch (Throwable th) { logger.log(Level.SEVERE, "Error calling spectrum browser service", th); } } }); nextDayButton.setText("Next Day >"); grid.setWidget(0, 3, nextDayButton); } setSpectrogramImage(); drawOccupancyChart(); tabPanel = new TabPanel(); tabPanel.add(spectrogramVerticalPanel, "[Spectrogram]"); tabPanel.add(occupancyPanel, "[Occupancy]"); tabPanel.selectTab(0); vpanel.add(tabPanel); } catch (Throwable ex) { logger.log(Level.SEVERE, "Problem drawing specgtrogram", ex); } } @Override public void onFailure(Throwable throwable) { logger.log(Level.SEVERE, "Error communicating with server", throwable); mSpectrumBrowser.displayError("Error communicating with server"); } }