Java tutorial
/* * Copyright (C) 2009-2013 Oleksandr Natalenko aka post-factum * * This program is free software; you can redistribute it and/or modify * it under the terms of the Universal Program License as published by * Oleksandr Natalenko aka post-factum; see file COPYING for details. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Universal Program * License along with this program; if not, write to * oleksandr@natalenko.name */ package org.pf.midea; import com.jgoodies.forms.layout.CellConstraints; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.chart.axis.LogAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.RectangleEdge; import javax.swing.*; import java.awt.*; import java.util.ArrayList; public class SimulationController implements Runnable { private PlanCell[] planCells; private double hSquareLow, hSquareHigh, hSquareStep; private int iterationsCount; private boolean dBs; private JProgressBar progressBar; private JPanel chartPanel; private JTextArea textAreaNumeric; private boolean showLineNumbers; public SimulationController(ArrayList<PlanCell> _planCells, JSpinner _spinnerHSquareLow, JSpinner _spinnerHSquareHigh, JSpinner _spinnerHSquareStep, JSpinner _spinnerIterations, boolean _dBs, JProgressBar _progressBar, JPanel _chartPanel, JTextArea _textAreaNumeric, boolean _showLineNumbers) { planCells = _planCells.toArray(new PlanCell[_planCells.size()]); hSquareLow = (Double) _spinnerHSquareLow.getValue(); hSquareHigh = (Double) _spinnerHSquareHigh.getValue(); hSquareStep = (Double) _spinnerHSquareStep.getValue(); iterationsCount = (Integer) _spinnerIterations.getValue(); dBs = _dBs; progressBar = _progressBar; chartPanel = _chartPanel; textAreaNumeric = _textAreaNumeric; showLineNumbers = _showLineNumbers; } @Override public void run() { textAreaNumeric.setText(""); XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); double progress = 0; double progressStep = 100.0 / (planCells.length * (hSquareHigh - hSquareLow + hSquareStep) / hSquareStep); progressBar.setValue(0); for (int i = 0; i < planCells.length; i++) { XYSeries xySeries; if (showLineNumbers) xySeries = new XYSeries(String.valueOf(i + 1) + ") " + planCells[i].getShortDescription()); else xySeries = new XYSeries(planCells[i].getShortDescription()); textAreaNumeric.append(planCells[i].getDescription() + "\n"); textAreaNumeric.setCaretPosition(textAreaNumeric.getDocument().getLength()); PlanStates.SourceType currentSourceType = planCells[i].getSourceCell().getSourceType(); PlanStates.CodeType currentCodeType = planCells[i].getCodeCell().getCodeType(); PlanStates.ModulationType currentModulationType = planCells[i].getModulationCell().getModulationType(); PlanStates.ChannelType currentChannelType = planCells[i].getChannelCell().getChannelType(); PlanStates.ErrorsType currentErrorsType = planCells[i].getErrorsCell().getErrorsType(); BinaryNumber[] sourcePoints = null; switch (currentSourceType) { case ST_TEST: sourcePoints = ConstellationPointsGenerator.getTestPoints(currentModulationType, iterationsCount); break; case ST_RANDOM: sourcePoints = ConstellationPointsGenerator.getRandomPoints(currentModulationType, iterationsCount); break; } Coder coder = null; Decoder decoder = null; switch (currentCodeType) { case CT_NONE: coder = new CoderNone(); decoder = new DecoderNone(); break; case CT_HAMMING74: coder = new CoderHamming74(); decoder = new DecoderHamming74(); break; case CT_CYCLIC: coder = new CoderCyclic85(); decoder = new DecoderCyclic85(); break; case CT_BCH155: coder = new CoderBCH155(); decoder = new DecoderBCH155(); break; } Modulator modulator = null; Demodulator demodulator = null; switch (currentModulationType) { case MT_ASK: modulator = new ModulatorASK(); demodulator = new DemodulatorASK(); break; case MT_FSK: modulator = new ModulatorFSK(); demodulator = new DemodulatorFSK(); break; case MT_BPSK: modulator = new ModulatorBPSK(); demodulator = new DemodulatorBPSK(); break; case MT_QPSK: modulator = new ModulatorQPSK(); demodulator = new DemodulatorQPSK(); break; case MT_8PSK: modulator = new Modulator8PSK(); demodulator = new Demodulator8PSK(); break; case MT_16PSK: modulator = new Modulator16PSK(); demodulator = new Demodulator16PSK(); break; case MT_32PSK: modulator = new Modulator32PSK(); demodulator = new Demodulator32PSK(); break; case MT_16QAM: modulator = new Modulator16QAM(); demodulator = new Demodulator16QAM(); break; case MT_32QAM: modulator = new Modulator32QAM(); demodulator = new Demodulator32QAM(); break; case MT_64QAM: modulator = new Modulator64QAM(); demodulator = new Demodulator64QAM(); break; case MT_256QAM: modulator = new Modulator256QAM(); demodulator = new Demodulator256QAM(); break; } Channel channel = null; switch (currentChannelType) { case CHT_AWGN: channel = new ChannelAWGN(); break; case CHT_RAYLEIGH: channel = new ChannelRayleigh(); break; } BinaryNumber[] encoded = coder.encode(sourcePoints); Signal[] modulated = modulator.modulate(encoded); double error = 0; for (double h = hSquareLow; h <= hSquareHigh; h += hSquareStep) { double realH; if (dBs) realH = StatisticsTools.decibelsToTimes(h); else realH = h; Signal[] noised = channel.noise(realH, modulated); BinaryNumber[] demodulated = demodulator.demodulate(noised); noised = null; System.gc(); BinaryNumber[] decoded = decoder.decode(demodulated); demodulated = null; System.gc(); switch (currentErrorsType) { case ET_SER: error = StatisticsTools.getSER(sourcePoints, decoded); break; case ET_BER: error = StatisticsTools.getBER(sourcePoints, decoded); break; } decoded = null; System.gc(); if (error > 0) { xySeries.add(h, error); textAreaNumeric.append(String.valueOf(h) + "\t" + String.valueOf(error) + "\n"); textAreaNumeric.setCaretPosition(textAreaNumeric.getDocument().getLength()); } progress += progressStep; progressBar.setValue((int) Math.round(progress)); } xySeriesCollection.addSeries(xySeries); textAreaNumeric.append("\n"); textAreaNumeric.setCaretPosition(textAreaNumeric.getDocument().getLength()); } JFreeChart chart = ChartFactory.createXYLineChart("", dBs ? "" : "", "?", xySeriesCollection, PlotOrientation.VERTICAL, true, true, false); chart.getLegend().setPosition(RectangleEdge.RIGHT); XYPlot xyPlot = chart.getXYPlot(); for (int i = 0; i < planCells.length; i++) { xyPlot.getRenderer().setSeriesStroke(i, new BasicStroke(planCells[i].getLineWidth())); if (planCells[i].getLineColor() != null) xyPlot.getRenderer().setSeriesPaint(i, planCells[i].getLineColor()); if (showLineNumbers) { XYSeries currentSeries = xySeriesCollection.getSeries(i); double annotationY = currentSeries.getY(0).doubleValue(); double annotationX = currentSeries.getX(0).doubleValue(); for (int j = 1; j < currentSeries.getItemCount(); j++) if (currentSeries.getY(j).doubleValue() == 0) { annotationY = currentSeries.getY(j - 1).doubleValue(); annotationX = currentSeries.getX(j - 1).doubleValue(); break; } else { annotationY = currentSeries.getY(j).doubleValue(); annotationX = currentSeries.getX(j).doubleValue(); } XYTextAnnotation annotation = new XYTextAnnotation(String.valueOf(i + 1), annotationX, annotationY); annotation.setBackgroundPaint(Color.WHITE); annotation.setFont(new Font("Dialog", 0, 14)); xyPlot.addAnnotation(annotation); } } xyPlot.setBackgroundPaint(Color.WHITE); xyPlot.setDomainGridlinePaint(Color.GRAY); xyPlot.setRangeGridlinePaint(Color.GRAY); NumberAxis domainAxis = new NumberAxis("h, " + (dBs ? "" : "")); LogAxis rangeAxis = new LogAxis("?"); rangeAxis.setNumberFormatOverride(new HumanNumberFormat(1)); domainAxis.setTickLabelFont(new Font("Dialog", 0, 14)); rangeAxis.setTickLabelFont(new Font("Dialog", 0, 14)); xyPlot.setDomainAxis(domainAxis); xyPlot.setRangeAxis(rangeAxis); ChartPanel nestedPanel = new ChartPanel(chart); chartPanel.removeAll(); chartPanel.add(nestedPanel, new CellConstraints()); chartPanel.updateUI(); } }