/* * RSFrame.java - Frame for RS decoder. * * ------------------------------------------------------------------ * * @begin[license] * Copyright (C) 2003 Kai Chen, Caltech * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * @author: Kai Chen * @email{kchen@cs.caltech.edu} * @end[license] * */ import java.awt.*; import java.awt.event.*; public class RSFrame extends Frame { private static final int WIDTH = 800, HEIGHT = 600; protected Panel mPanel, northPanel, centerPanel, southPanel, functionPanel; protected Button decodeButton, resetButton, clearButton; protected CheckboxGroup domain; protected Checkbox timeBox, freqBox; protected TextArea statusText; protected ScrollPane statusPane; protected Label titleLabel, statusLabel, receivedLabel, decodedLabel, bottomLabel; protected TextField receivedField, decodedField; // Reed-Solomon decoder protected RSDecoder decoder; private static final String DEF_STATUS = "Please enter 'A' - 'Z' for 0 - 25, "+ "'1' - '6' for 26 - 31. Input length should be 31" + "\n Do not include any space."; /* * post: constructs an RSFrame with decoder */ public RSFrame(RSDecoder decoder) { super("Reed-Solomon Decoder"); this.decoder = decoder; setSize(WIDTH, HEIGHT); // close window this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); // custom panel mPanel = new Panel(new BorderLayout()); add(mPanel); // GridBagLayout setup centerPanel = new Panel(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); centerPanel.setLayout(gridbag); gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(0, 10, 0, 10); // Title label titleLabel = new Label("Reed-Solomon Decoder"); titleLabel.setAlignment(Label.CENTER); gbc.weightx = 1.0; gbc.weighty = 0.1; gbc.gridx = 0; gbc.gridy = 0; gridbag.setConstraints(titleLabel, gbc); centerPanel.add(titleLabel); // input area receivedLabel = new Label("Received codeword:"); gbc.weightx = 1.0; gbc.weighty = 0.05; gbc.gridx = 0; gbc.gridy = 1; gridbag.setConstraints(receivedLabel, gbc); centerPanel.add(receivedLabel); receivedField = new TextField(31); gbc.weightx = 1.0; gbc.weighty = 0.02; gbc.gridx = 0; gbc.gridy = 2; gridbag.setConstraints(receivedField, gbc); centerPanel.add(receivedField); decodedLabel = new Label("Decoded codeword:"); gbc.weightx = 1.0; gbc.weighty = 0.05; gbc.gridx = 0; gbc.gridy = 3; gridbag.setConstraints(decodedLabel, gbc); centerPanel.add(decodedLabel); decodedField = new TextField(31); gbc.weightx = 1.0; gbc.weighty = 0.02; gbc.gridx = 0; gbc.gridy = 4; gridbag.setConstraints(decodedField, gbc); centerPanel.add(decodedField); // function panel functionPanel = new Panel(); domain = new CheckboxGroup(); timeBox = new Checkbox("Time Domain", true, domain); freqBox = new Checkbox("Frequency Domain", false, domain); decodeButton = new Button("Decode"); decodeButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(MouseEvent e) { decodeButtonClicked(e); } }); clearButton = new Button("Clear"); clearButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(MouseEvent e) { clearButtonClicked(e); } }); resetButton = new Button("Reset"); resetButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(MouseEvent e) { resetButtonClicked(e); } }); functionPanel.add(decodeButton); functionPanel.add(clearButton); functionPanel.add(resetButton); functionPanel.add(timeBox); functionPanel.add(freqBox); gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.gridx = 0; gbc.gridy = 5; gridbag.setConstraints(functionPanel, gbc); centerPanel.add(functionPanel); // status label statusLabel = new Label("Decoding Status:"); gbc.weightx = 1.0; gbc.weighty = 0.05; gbc.gridx = 0; gbc.gridy = 6; gridbag.setConstraints(statusLabel, gbc); centerPanel.add(statusLabel); // status text statusText = new TextArea(DEF_STATUS); statusText.setEditable(false); statusPane = new ScrollPane(); statusPane.add(statusText); gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.gridwidth = 4; gbc.gridheight = 2; gbc.gridx = 0; gbc.gridy = 7; gbc.insets = new Insets(10, 5, 5, 5); gbc.fill = GridBagConstraints.BOTH; gridbag.setConstraints(statusPane, gbc); centerPanel.add(statusPane); mPanel.add(centerPanel, BorderLayout.CENTER); bottomLabel = new Label("EE/Ma127a Final Project. "+ " (C) Kai Chen, Liang Jiang, Xiaoyu Liu, 2003"); mPanel.add(bottomLabel, BorderLayout.SOUTH); southPanel = new Panel(); show(); } /* MouseEventHandlers */ protected void decodeButtonClicked(MouseEvent e) { // get the input string String s = receivedField.getText(); int received[] = new int[decoder.getGF().orderOfAlpha()]; int errno = RS.parse(s, received); String status = statusText.getText(); // check for parsing errors if(errno < 0){ decodedField.setText("Invalid input"); status += "\nParsing error: input too short."; statusText.setText(status); return; } if(errno < received.length){ decodedField.setText("Invalid input"); status += "\nParsing error: unresolved symbol: " + s.charAt(errno); statusText.setText(status); return; } // decode try{ boolean time = timeBox.getState(); errno = decoder.decode(received, time); }catch(RSException ex){ /* * This should never happen. Something bad happened ... * But this is our last hope before the program crashes ... */ ex.printStackTrace(); status += "\n This should not have happened."+ "Something bad happened." + " \nThe stack frame trace is printed out to standard error stream."; statusText.setText(status); } if(errno<=0){ decodedField.setText("Decoding failed."); switch(errno){ case RSDecoder.NO_ERROR: status += "\nNo error detected."; decodedField.setText("No error"); statusText.setText(status); return; case RSDecoder.TOO_MANY_ERASURES: status += "\nError: too many erasures."; statusText.setText(status); return; case RSDecoder.V_UNNORMALIZABLE: status += "\nError: v not normalizable."; status += "\n gcd(sigma, omega) != 1, v(0) = 0."; statusText.setText(status); return; case RSDecoder.DEGREE_ERROR: status += "\nError: deg(omega) >= degree(sigma)"; statusText.setText(status); return; case RSDecoder.TOO_FEW_ROOTS: status += "\nError: sigma has too few roots."; statusText.setText(status); return; case RSDecoder.MULTIPLE_ROOTS: status += "\nError: sigma has multiple roots."; statusText.setText(status); return; case RSDecoder.UNSPECIFIED_ERROR: if(freqBox.getState()){ status += "\n Sorry, frequency domain decoding not implemented."; status += "\n Please choose time domain decoding."; statusText.setText(status); } else{ status += "\n Unspecified error."; statusText.setText(status); } return; default: status += "\nSomething really weird happened."; decodedField.setText("Oops"); statusText.setText(status); return; } } status += "\n Decoding successful"; status += "\n Received polynomial: "+decoder.getPolyR(); status += "\n Syndrome polynomial: "+decoder.getPolyS(); status += "\n Error polynomial: "+decoder.getPolyE(); status += "\n Corrected polynomial: "+decoder.getPolyC(); statusText.setText(status); /* now output the decoded codeword in a proper form */ decodedField.setText(RS.parseBack(decoder.getPolyC().getCoeff())); } protected void resetButtonClicked(MouseEvent e) { receivedField.setText(""); decodedField.setText(""); } protected void clearButtonClicked(MouseEvent e) { decodedField.setText(""); statusText.setText(DEF_STATUS); } }