package edu.princeton.toy; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import edu.princeton.swing.*; import edu.princeton.toy.lang.*; /** * TBaseConvertPanel is a JPanel which acts as a base converter. * * @author btsang * @version 7.1 */ public class TBaseConverterPane extends JPanel { /** * The font which this TBaseConverterPane starts out with. */ public static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); private Document binaryDocument, decimalDocument, hexDocument, pseudoCodeDocument; private boolean ignoreBinaryDocument, ignoreDecimalDocument, ignoreHexDocument; private Listener listener; /** * Creates a new TBaseConverterPane. */ public TBaseConverterPane() { this(TWord.ZERO); } /** * Creates a new TBaseConverterPane. */ public TBaseConverterPane(TWord initialValue) { super(new GridBagLayout(), true); if (initialValue == null) throw new NullPointerException(); setFont(DEFAULT_FONT); add( new JLabel("Base Converter"), new GridBagConstraints( 0, 0, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0 ) ); add( new JLabel("Binary"), new GridBagConstraints( 0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0 ) ); add( new JLabel("Decimal"), new GridBagConstraints( 0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0 ) ); add( new JLabel("Hexadecimal"), new GridBagConstraints( 0, 3, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0 ) ); add( new JLabel("Pseudocode"), new GridBagConstraints( 0, 4, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0 ) ); listener = new Listener(); PTextField textField; textField = new PTextField(17); textField.setFont(null); binaryDocument = textField.getDocument(); binaryDocument.addDocumentListener(listener); add( textField, new GridBagConstraints( 1, 1, 1, 1, 5.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0 ) ); textField = new PTextField(17); textField.setFont(null); decimalDocument = textField.getDocument(); decimalDocument.addDocumentListener(listener); add( textField, new GridBagConstraints( 1, 2, 1, 1, 5.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0 ) ); textField = new PTextField(17); textField.setFont(null); hexDocument = textField.getDocument(); hexDocument.addDocumentListener(listener); add( textField, new GridBagConstraints( 1, 3, 1, 1, 5.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0 ) ); textField = new PTextField(17); textField.setFont(null); textField.setEditable(false); pseudoCodeDocument = textField.getDocument(); add( textField, new GridBagConstraints( 1, 4, 1, 1, 5.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0 ) ); setValue(initialValue, null); } /** * Sets the value currently displayed by the TBaseConverterPane. * * @param value The new value the TBaseConverterPane should display. If the value is * uninitialized, nothing will be displayed. If the value is null, a NullPointerException * will be thrown. */ public void setValue(TWord value) { setValue(value, null); } /** * Sets the value currently displayed by the TBaseConverterPane. * * @param value The new value the TBaseConverterPane should display. If the value is * uninitialized, nothing will be displayed. If the value is null, a NullPointerException * will be thrown. * @param source The source of the change. This source will not be modified. A null value * will indicate that all PTextFields should be updated. */ protected void setValue(TWord value, Document source) { if (value == null) throw new NullPointerException(); if (source != binaryDocument) { ignoreBinaryDocument = true; try { binaryDocument.remove(0, binaryDocument.getLength()); if (value.isInitialized()) binaryDocument.insertString(0, value.toBinaryString(false), null); } catch (Exception e) { e.printStackTrace(); } ignoreBinaryDocument = false; } if (source != decimalDocument) { ignoreDecimalDocument = true; try { decimalDocument.remove(0, decimalDocument.getLength()); if (value.isInitialized()) decimalDocument.insertString(0, String.valueOf(value.getValue()), null); } catch (Exception e) { e.printStackTrace(); } ignoreDecimalDocument = false; } if (source != hexDocument) { ignoreHexDocument = true; try { hexDocument.remove(0, hexDocument.getLength()); if (value.isInitialized()) hexDocument.insertString(0, value.toHexString(false), null); } catch (Exception e) { e.printStackTrace(); } ignoreHexDocument = false; } try { pseudoCodeDocument.remove(0, pseudoCodeDocument.getLength()); if (value.isInitialized()) pseudoCodeDocument.insertString(0, value.toPseudoCodeString(false), null); } catch (Exception e) { e.printStackTrace(); } } /** * Parses the text of a document and passes the data to setValue(). * * @param source The Document which changed. */ private void documentChanged(Document source) { if (source == binaryDocument) { if (!ignoreBinaryDocument) { try { setValue( TWord.parseWord( binaryDocument.getText(0, binaryDocument.getLength()), 2 ), binaryDocument ); } catch (NumberFormatException e) { setValue(TWord.UNINITIALIZED_VALUE, binaryDocument); } catch (Exception e) { e.printStackTrace(); setValue(TWord.UNINITIALIZED_VALUE, binaryDocument); } } } else if (source == decimalDocument) { if (!ignoreDecimalDocument) { try { setValue( TWord.parseWord( decimalDocument.getText(0, decimalDocument.getLength()), 10 ), decimalDocument ); } catch (NumberFormatException e) { setValue(TWord.UNINITIALIZED_VALUE, decimalDocument); } catch (Exception e) { e.printStackTrace(); setValue(TWord.UNINITIALIZED_VALUE, decimalDocument); } } } else if (source == hexDocument) { if (!ignoreHexDocument) { try { setValue( TWord.parseWord( hexDocument.getText(0, hexDocument.getLength()), 16 ), hexDocument ); } catch (NumberFormatException e) { setValue(TWord.UNINITIALIZED_VALUE, hexDocument); } catch (Exception e) { e.printStackTrace(); setValue(TWord.UNINITIALIZED_VALUE, hexDocument); } } } else { throw new IllegalArgumentException(); } } /** * The Listener of a TBaseConverterPane pays attention to the changes in the PTextFields, and * fires off changes to the other PTextFields. * * @author btsang * @version 7.1 */ protected class Listener implements DocumentListener { /** * Implement DocumentListener to pass DocumentEvents to the documentChanged() method. */ public void changedUpdate(DocumentEvent e) { documentChanged(e.getDocument()); } /** * Implement DocumentListener to pass DocumentEvents to the documentChanged() method. */ public void insertUpdate(DocumentEvent e) { documentChanged(e.getDocument()); } /** * Implement DocumentListener to pass DocumentEvents to the documentChanged() method. */ public void removeUpdate(DocumentEvent e) { documentChanged(e.getDocument()); } } }