/* -*- Mode: c++ -*-
 * @(#) CryptoGramTool.java 1.0 6/10/97 Ralph Morelli
 *
 * Applet: CryptoGramTool.java
 * Author: Ralph Morelli, Trinity College ([email protected])
 * 
 * Copyright (c) 1996 Ralph Morelli. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and
 * without fee is hereby granted provided that this copyright
 * notice appears in all copies. 
 */

import java.applet.*;
import java.awt.*;

/* -*- Mode: c++ -*-
 * @(#) CryptoGram.java 1.0 6/10/97 Ralph Morelli
 *
 * Classes: CryptoGram  FreqRecord FreqVector
 * Author: Ralph Morelli, Trinity College ([email protected])
 * 
 * Copyright (c) 1996 Ralph Morelli. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and
 * without fee is hereby granted provided that this copyright
 * notice appears in all copies. 
 */

/**
 * A class to store letter frequencies.
 */

class FreqRecord {
  int count;
  char letter;
  
  FreqRecord (int count, char letter) {
    this.count = count;
    this.letter = letter;
  }
} // FreqRecord

class FreqVector {
  private FreqRecord freq[];

  FreqVector() {
    freq = new FreqRecord[26];
    for (int k = 0; k < 26; k++) {
      freq[k] = new FreqRecord(0, (char)('a' + k)) ;
    }
  }

  public void reInitFreq() {
    for (int k = 0; k < 26; k++) {
      freq[k].count = 0;
      freq[k].letter = (char)('a' + k) ;
    }
  }
	
  /**
   * Counts the letters in the current cipher and
   * stores them in the frequency vector. 
   * Calls a sort to sort frequency vector.
   * @param s the cipher string
   */
  public void countLetters( String s ) {
    for (int k = 0; k < s.length(); k++) {
      char ch = s.charAt(k);
      if (ch >= 'A' && ch <= 'Z')
	ch = (char)(ch + 32);
      if (ch >= 'a' && ch <= 'z')
	freq[ ch  - 'a'].count += 1;
    }
    sortFreq(freq,freq.length-1);

  }
	
  /**
   * Returns the top 8 most frequent letters in 
   * the frequency vector.
   * @return a string of letters
   */
  public String getTopFreq() {
    String temp = "";
    for (int k = 0; k < 8; k++ )  {
      temp = temp + (char)(freq[k].letter - 32) + ", ";
      //  System.out.println(freq[k].count);
    }
    return temp;
  }
	
  /**
   * Sorts the frequency array using a recursive
   * selection sort.
   * @param a the frequency array
   * @param n the length of the array
   */
  private void sortFreq (FreqRecord a[], int n) {	// recursive selection sort
    FreqRecord temp;
    if (n == 0)
      return;
    else {		// recursive case
      int min = a[n].count;					// let nth be min so far
      int minL = n;
      for (int k = n-1; k >= 0;  k--) {   // for entire array
	int next = a[k].count;			// get next  
	if (next < min) {				// if greater than max
	  min = next;					//  remember it
	  minL = k;
	}	// if next
      } // for each card
      temp = a[n];					// swap max and nth
      a[n] = a[minL];	
      a[minL] = temp;
      sortFreq(a, n-1);					// sort the rest of the arr
    } // recursive case
  } //  sort
  

} // FreqVector class

/**
 * A class to support making and breaking of simple
 * substitution cryptograms. 
 * @version  1.0 6/10/97
 * @author Ralph Morelli
 */
class CryptoGram {
  public static char NULL_CHAR = '*';
  private int NHINTS = 8;
  
  private char theKey[] = new char[26];	      // key for 'a' to 'z'
  private FreqVector freq = new FreqVector(); // letter frequency vector
  
  private String cipherText;		// remains unchanged 
  private String plainText;
	
  String hint[];			// an array of hints
  int hintPtr;				// pointer to next hint
		
  CryptoGram ( )  {			// Default Constructor
    cipherText = new String("") ;			
    plainText = new String("") ;
    initKey();
    freq.reInitFreq();
    initHints();
  }

  /**
   * Construct the initial cryptogram from a String.
   * @param s the String
   */
  CryptoGram ( String s)  {	
    setCipherText( s ) ;			
    plainText = new String("") ;
    initKey();
    freq.reInitFreq();
    initHints();
  }
		
  /**
   * Resets the cryptogram. 
   */
  public void reset() {
    cipherText = "";
    plainText = "";
    initKey();
    freq.reInitFreq();
  }
	
  /**
   * Initializes the key
   */
  public void initKey() {
    for (int k = 0; k < 26; k++)
      theKey[k] = NULL_CHAR;
  }
	
  /**
   * Initializes an array of canned hints.
   */
  private void initHints() {
    hintPtr = 0;
    hint = new String[NHINTS];
    hint[0] = "Frequent English letters: E, T, A, O, N, R, I, S, H" ;
    hint[1] = "Frequent double letters: LL,EE,SS,OO,TT,FF,RR,NN,PP,CC,MM,GG" ;
    hint[2] = "Frequent 2 letter words: OF,TO,IN,IS,IT,BY,HE,AS,ON,AT,AN,OR" ;   
    hint[3] = "Frequent bigrams: TH,HE,AN,RE,ER,IN,ON,AT,ND,ST,ES,EN "  ;
    hint[4] = "Frequent 3 letter words: THE,AND,FOR,ARE,WAS,BUT,ONE,HIS,HAS,HAD"  ;
    hint[5] = "Frequent trigrams: ING,ION,ENT,ERE,TIO,THA,ATE,AND,EVE,HAT,VER,HER " ;
    hint[6] = "Frequent English initial letters: T,A,O,S,W,I,H,C,B,F,P,M"  ;
    hint[7] = "Frequent English terminal letters: E,S,D,T,N,Y,F,R,O,H,G,A"  ;
  }
	
  /**
   * Returns the next canned hint where hintPtr defines next.
   * @return the next hint in the hint array.
   */
  public String getHint() {
    String temp = hint[hintPtr];
    if (hintPtr == NHINTS-1) {
      hintPtr = 0;
      return "Most frequent letters in this cryptogram: " + freq.getTopFreq()  ;
    }
    else hintPtr++;
    return temp;
  }
  
  /**
   * Determines if the cryptogram key is consistent -- i.e.,
   * maintains a 1-1 mapping from {'A'..'Z'} to {'A'.. 'Z'}
   * @param key an integer array storing the key
   * @return true if the key is consistent and false otherwise
   */
  public boolean isValidKey( int key ) {     // works just for 'a' to 'z' 
    
    if (key >= 'a' && key <= 'z') {			// if key is a letter
      int k;
      for (k = 0; k < 26 && theKey[k] != (char)key; k++) ;	// bodyless loop
      if ( k < 26 )
	return false;
      else
	return true;
    }
    else if ( key == '*' )					// if key is NULL_CART
      return true;
    return false;
  } // isValidKey	
  
  /**
   * Creates a mapping between a cipher and plain character
   * and then applies the entire key to the cryptogram.
   * @param cipherCh is the cipher character
   * @param plainCh is the plaintext character
   */
  public void setKeyChar( int cipherCh, int plainCh) {
    theKey[ cipherCh ] = (char) plainCh ;
    translate();
  }
  
  /**
   * Generates an entire key from a keyword where the keyword
   * has been installed in the first k locations of theKey[].
   * This assumes that the first NULL_CHAR marks the end of 
   * the keyword.
   * @return the keyword
   */
  public String generateKey() {
    String keyWd = "";		  // initialize the KEYWORD

    for (int k = 0; k < 26; k++)  // find the end of the KEYWORD
      if (theKey[k] != NULL_CHAR)		
	keyWd = keyWd + theKey[k];
      else break; 
    int k = keyWd.length();
                                // fill in the rest of the KEY
    for (int ch = 'a'; ch <= 'z'; ch++ ) { 
      if (keyWd.indexOf(ch) == -1) 
	theKey[k++] = (char) ch;
    }
    return keyWd;
  }
  
  /**
   * Returns the mapping for a given character in theKey.
   * @param ch the character to be mapped
   * @return the character's mapping.
   */
  public char getPlainCh( int ch ) {
    return theKey[ch];
  }

  /**
   * Sets the ciphertext from a given string.
   * @param s the String
   */
  public void setCipherText( String s ) {
    cipherText = s;
    freq.countLetters( s );
  }
	
  /**
   * Gets the current plaintext for this cryptogram.
   * The key is first applied to generate an up-to-date
   * plaintext.
   * @return  the updated plaintext.
   */
  public String getPlainText( ) {
    translate();
    return plainText;	
  }

  /**
   * Gets the current ciphertext for this cryptogram.
   * @return  the current cipherText.
   */
  public String getCipherText( ) {
    return cipherText;	
  }

  /**
   * Translates ciphertext to plaintext using theKey[]
   */
  private void translate() {
    plainText = "";
    for (int k = 0; k < cipherText.length(); k++) {
      plainText = plainText + enCode( cipherText.charAt(k) ) ;
    }
  } // translate()


  /*----------------------------------------------*/
  // If the character's key is not NULL_CHAR, return its key,
  // otherwise return the original character.
  
  /**
   * Encodes a single character if it is in {a..z}.
   * Case insensitive. The mapping is performed by
   * lookup in theKey.
   * NULL_CHAR's are not encoded
   * @param inChar the character to be encoded.
   * @return the encoded character.
   */
  private char enCode(char inChar){
    char outChar = inChar;
    if (inChar == NULL_CHAR) return inChar;  // just return if NULL_CHAR
    
    if (inChar >= 'A' && inChar <= 'Z') {       // If UPPERCASE character
      inChar = (char)((int)inChar + 32);        //   convert to lowercase
      outChar = theKey[(int)inChar - (int)'a'];	//   and then encode
      
      if (outChar != NULL_CHAR)					// if not NULL
	outChar = (char) ((int)'A' + (int)outChar - (int)'a');	// convert back to UPPERCASE
    }
    else if (inChar >= 'a' && inChar <= 'z') {	// If LOWERCASE 
      outChar = theKey[(int)inChar - (int)'a']; //   just encode
    }
    return outChar;	
  } // Encode
  
}  // class CryptoGram


/* -*- Mode: c++ -*-
 * @(#) KeyPad.java 1.0 6/10/97 Ralph Morelli
 *
 * Classes: KeyPad Canvas
 * Author: Ralph Morelli, Trinity College ([email protected])
 * 
 * Copyright (c) 1996 Ralph Morelli. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and
 * without fee is hereby granted provided that this copyright
 * notice appears in all copies. 
 */


class KeyPad extends Canvas {
  CryptoGramTool theApplet;			// pointer to the applet
  CryptoGram cryptogram;				// the cryptogram itself
  boolean firstMouseDown;
															// COLOR SCHEME
  final static Color appletbGround = new Color(110,110,155); // new Color(100,30,255); 
  final static Color 
    textColor = Color.darkGray,			
  buttonbGround = Color.white,
  hintColor = Color.white,
  buttonFocusColor = new Color(110,110,155), //Color.darkGray,	
  labelColor = Color.blue;
    					
															// REFERENCE CONSTANTS
  
  final static int kBlockWidth = 30, kBlockHeight = 30, kBlocksWide =13, kBlocksHigh =2;		
  final static int kTopKey 	= 5,	kLeftKey 	= 20;
  final static int hintL = 5, hintT = 100, hintW = 425, hintH = 150;
  final static int newL = 70, newT = 70, newW = 50, newH = 15;
  final static int resetL = 150, resetT = 70, resetW = 50, resetH = 15;
  final static int hintBL = 230, hintBT = 70, hintBW = 60, hintBH = 15;
  final static int makeKeyL = 310, makeKeyT = 70, makeKeyW = 50, makeKeyH = 15;
  final static int kAppWidth 	= 40 + (kBlockWidth * kBlocksWide);			// 430
  final static int kAppHeight = 3 * (kBlockHeight * kBlocksHigh + 30);	// 270
  
  final static Font bigFont = new Font("TimesRoman",0,18); 
  final static Font regularFont = new Font("TimesRoman", 0, 12);
  final static Font hintFont = new Font("TimesRoman", 0, 10);
    
  int gCurX	= 0;			// current mouse locations in terms of block number
    int	gCurY	= 0;
  boolean hintON = false;	       // hints are off initially
  boolean makeKeyON = false;	      // make a key is off initially
	
  public KeyPad (CryptoGramTool a) {  // CONSTRUCTOR
    firstMouseDown = true;
    theApplet = a;
    cryptogram = new CryptoGram( );	  		
  } // keyPad Constructor
	
  private void reset() {
    firstMouseDown = true;
    gCurX = 0;
    gCurY = 0;
    repaint();
  }
	
  public void paint(Graphics g) {
    													// REFERENCE VARIABLES
    int left = 0;	int right = kAppWidth - 1;
    int top = 0;	int bottom = kAppHeight - 1;
    int tempLeft = 0;	int tempRight = 0;           int tempTop = 0;
    int viewWidth;		int viewHeight;
    int buttonWidth = 0;	int buttonHeight = 0;
    int buttonLeft = 0;	        int buttonTop = 0;
    int tileLeft;		int tileTop;
	
    g.draw3DRect(0,0,kAppWidth,kAppHeight,true);		// Paint background
    g.setColor(appletbGround);					// fill outer rectangle
    g.fillRect(0+1,0+1,kAppWidth-1,kAppHeight-1);
    
    g.setColor(buttonFocusColor);				// fill outer rectangle
    paintKeyPad(g);
    
    g.setColor(buttonbGround);					// fill outer rectangle
    g.drawLine(kLeftKey,90,430 - kLeftKey,90);
    
    paintButton(g,newL,newT,newW,newH,"ResetAll");		// paint reset key button    
    paintButton(g,resetL,resetT,resetW,resetH,"ResetKey");	// paint reset button    
    paintButton(g,hintBL,hintBT,hintBW,hintBH,"ToggleHint");	// paint hint button    
    paintButton(g,makeKeyL,makeKeyT,makeKeyW,makeKeyH,"MakeKey"); // paint makekey button    
    paintHint(g);   	        	
  } // paint

    /*----------------------------------------------*/
       
   private void paintButton (Graphics g, int left, int top, int width, int height, String s) {
      g.setColor(buttonbGround);  
      g.draw3DRect(left-1,top-1,width,height,true);
      g.fillRect(left+1,top+1,width-2,height-2);			// Paint the  button
      g.setColor(labelColor);
   	  g.drawString(s,left+2, top + 11);
    }

   private void paintButtonClicked (Graphics g, int left, int top, int width, int height, String s) {
      g.setColor(labelColor);
      g.draw3DRect(left-1,top-1,width,height,true);
      g.fillRect(left+1,top+1,width-2,height-2);			// Paint the  button
      g.setColor(buttonbGround);  
      g.drawString(s,left+2, top + 11);
    }
    
  private void paintKeyPad(Graphics g) {
    gCurX = 0;
    gCurY = 0;
    for (int j = 0 ; j < kBlocksHigh ; j++) 			// draw the keymap
      for (int i = 0 ; i < kBlocksWide ; i++) {
	PaintCell(g,i,j);
      } // for i
  }
	
  private void PaintCell(Graphics g, int x, int y) {  // x is col, y is row 
    g.setFont(regularFont);
    int tempLeft = kLeftKey + (x * kBlockWidth);	// Compute coordinates
    int tempTop = kTopKey + (y * kBlockHeight);
    
    if (InActiveBlock(x,y))						// Set Cell's color
      g.setColor(buttonFocusColor);
    else
      g.setColor(buttonbGround);
    
    g.fillRect(tempLeft+1, tempTop+1, kBlockWidth-1, kBlockHeight-1);	// Paint cell
    g.setColor(appletbGround);		
    g.draw3DRect(tempLeft,tempTop,kBlockWidth, kBlockHeight,true);
      
    Character chobj = new Character( getCellLabel(x,y) );			// Draw cell's label
    g.setColor(labelColor);
    g.drawString(chobj.toString(), tempLeft + 2, tempTop + 11);	
      
    g.setColor(textColor);						       			// Draw cell's letter
    chobj = new Character( getCellContents(x,y) );
    g.drawString(chobj.toString(), tempLeft + 12, tempTop + 20);				
  } // PaintCell
    
  private void paintHint(Graphics g) {
    Color tempColor = g.getColor();
    g.setColor(appletbGround);
    g.fillRect(hintL,hintT,hintW, hintH);
    if (hintON) {
      g.setColor(hintColor);
      g.setFont(regularFont);
      g.drawString( cryptogram.getHint(), hintL+2, hintT+11);
      g.setColor(tempColor);
    }
    else {
      g.setColor(tempColor);
    }
  }

  private void makeKey(Graphics g) {
    makeKeyON = !makeKeyON;
    if (makeKeyON) {
      cryptogram.initKey();
      paintKeyPad(g);
      g.setFont(regularFont);
      Color tempColor = g.getColor();
      g.setColor(appletbGround);
      g.fillRect(hintL,hintT,hintW, hintH);
      g.setColor(buttonbGround);
      g.drawString( "Type a KEYWORD with no repeating letters into the first few ", hintL, hintT+11);
      g.drawString( "cells of the keypad -- i.e., from 'A'.. -- and then press", hintL, hintT+26);
      g.drawString( "the MakeKey button again.", hintL, hintT+41);
      g.setColor(tempColor);
    }
    else {
      String keyString = cryptogram.generateKey();
      paintKeyPad(g);
      Color tempColor = g.getColor();
      
      g.setColor(appletbGround);
      g.fillRect(hintL,hintT,hintW, hintH);
      g.setColor(buttonbGround);
      //  g.drawString( "The KEYWORD is " + keyString, hintL, hintT+11);
      theApplet.setDisplay( cryptogram.getCipherText() +"\n\n"+ cryptogram.getPlainText() ) ;
      g.setColor(tempColor);
    }
  }


  private char getCellLabel(int x, int y) {
    return((char) ((int)'A' + getCellNum(x,y)) );	// and return the corresponding letter	
  }
 
  private char getCellContents(int x, int y) {			// x is col y is the row
    return( cryptogram.getPlainCh( getCellNum(x,y) ));	// and return its key
  }	

  private int getCellNum(int x, int y) {
    return x + 13 * y;
  }


  public boolean handleEvent(Event evt) {
    
    				// The cryptoText is read on the first event.
    if (evt.id == evt.MOUSE_DOWN || evt.id == evt.KEY_PRESS || evt.id == evt.KEY_ACTION)
      if ( firstMouseDown ) {
	cryptogram.setCipherText( theApplet.getCipherText() ) ;
	firstMouseDown = false;
      }
      	
    switch(evt.id) {
         case evt.MOUSE_DOWN: mouseDown(evt.x,evt.y);          return(true);
	 case evt.MOUSE_UP:   mouseUp(evt.x,evt.y);            return(true);
	 case evt.KEY_PRESS:  keyDown(evt.key, gCurX,gCurY);   return(true);
	 case evt.KEY_ACTION: moveFocus(evt.key, gCurX,gCurY); return(true);
	 default: return super.handleEvent(evt);
    }
  } // handleEvent


  private boolean InActiveBlock(int x, int y) {
    if (x == gCurX && y == gCurY)
      return(true);
    return(false);
  } // InActiveBlock

  private void setActiveBlock(int x, int y) {
    gCurX	= x;		// reset current mouse locations
    gCurY	= y;
  } //setActiveBlock

  public void mouseDown(int x, int y) {
           
    requestFocus();
      
    if ( buttonPressed(x,y) ) return;
      								// WAS THE RESET BUTTON CLICKED
    if (x < kLeftKey)			// return if the click was not in the key area		
      return;					
    if (y < kTopKey)
      return;
      
    int j = y - kTopKey;		// get row and column indexes of the block
    j /= kBlockHeight;
    
    int i = x - kLeftKey;
    i /= kBlockWidth;
      
    if (i >= 0 && i < kBlocksWide && j >= 0 && j < kBlocksHigh) {
      if (!InActiveBlock(i,j)) { 
	int old_i = gCurX, old_j = gCurY;
	setActiveBlock(i, j);
	PaintCell(getGraphics(), i,j);
	PaintCell(getGraphics(), old_i,old_j);
	paintHint(getGraphics());
      } 
      return;
    }
  }
    
  private boolean buttonPressed(int x, int y) {
    // RESET BUTTON
    if (x >= newL && x <= newL+newW && y >= newT && y <= newT+newH){ 
      //  paintButtonClicked (getGraphics(), newL,newT, newW, newH, "ResetAll");   		
      theApplet.reset();
      cryptogram.reset();
      this.reset();
      return true;
    }
													// RESET KEY BUTTON    		
    if (x >= resetL && x <= resetL+resetW && y >= resetT && y <= resetT+resetH){ 
      cryptogram.initKey();
      repaint();
      theApplet.setDisplay( cryptogram.getCipherText() +"\n\n"+ cryptogram.getPlainText() ) ;	
      return true;
    }
													// HINT BUTTON
    if (x >= hintBL && x <= hintBL+hintBW && y >= hintBT && y <= hintBT+hintBH){ 
      hintON = !hintON;
      paintHint(getGraphics());
      return true;
    }
      	
    if (x >= makeKeyL && x <= makeKeyL+makeKeyW && y >= makeKeyT && y <= makeKeyT+makeKeyH){ 
      makeKey(getGraphics());
      return true;
    }
    return false;
    
    }

  public void mouseUp(int x, int y) {
    requestFocus();
  }

  
  public void keyDown(int key, int x, int y) {
     
    if (key >= 'A' && key <= 'Z')
      key = key + 32;							// convert to lower case
    
    if (cryptogram.isValidKey( key )) {
      int m = x + 13 * y;						// Use x and y to find what key this is
      cryptogram.setKeyChar( m, key );		// and store the lower case version of letter
      PaintCell(getGraphics(), x, y);
      if (!makeKeyON) { 
	paintHint(getGraphics());
	theApplet.setDisplay( cryptogram.getCipherText() +"\n\n"+ cryptogram.getPlainText() ) ;
      }	
      return;
    } //if valid
  } // keyDown
    
  private void moveFocus (int key, int x, int y ) {	// x is column, y is row
    int oldx = x, oldy = y;
    int m = getCellNum(x,y);						// cells are numbered 0..25
    // 	System.out.println("col " + x + " row " + y + " cell " + m );
    switch (key) {
    	case Event.UP: {
	  if (m >= 13 && m <= 25) { y--; } break;
	}
    	case Event.DOWN: {
	  if (m >= 0 && m <= 12) { y++; } break;
	}
    	case Event.LEFT: {
	  if ( (m > 0 && m <= 12) || (m > 13 && m <= 25) ) { x--; }
	  if (m == 0) { x = 12; y = 1;}
	  if (m == 13) { x = 12; y = 0; }
	  break;
	}
    	case Event.RIGHT: {
	  if ( (m >= 0 && m < 12) || (m >= 13 && m < 25) ) { x++; }
	  if (m == 12) { x = 0; y = 1; }
	  if (m == 25) { x = 0; y = 0; }
	  break;
	}
     } // switch
    setActiveBlock(x,y);
    PaintCell(getGraphics(), x,y);
    PaintCell(getGraphics(), oldx,oldy);
    if (!makeKeyON) paintHint(getGraphics());
  } 

 } // keyPad Canvas

/**
 * The main applet class for the cryptogram tool.
 * @version  1.0 6/10/97
 * @author Ralph Morelli
 */

public class CryptoGramTool extends Applet {
  public TextArea cryptoText = new TextArea (12,30);
  KeyPad keyPad;
	
  public void init() {	
    keyPad = new KeyPad(this);				// set up the keyPad canvas
    		
    setLayout( new GridLayout(2,1) );
    add(cryptoText);
    cryptoText.setBackground(Color.white);
    cryptoText.setForeground(new Color(30,30,155)) ; // (Color.blue);
    cryptoText.setFont( new Font( "Courier",0,12) );
    cryptoText.setText( initialMessage() );
    add(keyPad);
    resize(430,400);
  } // init()
    
  public boolean action (Event e, Object o ) {
    return true;
  }

  public String initialMessage( ) {
    return 	
      "                 Welcome to CRYPTOGRAM TOOL !"  +
      "\n          Replace this text with your cryptogram." + 
      "\n       Then click on the keypad below and create a key." +
      "\n         The keypad accepts letters and arrow keys." +
      "\n       Use the '*' character to reset a letter's code." +
      "\n        The keypad guards against inconsistent keys." ;
  }


  /**
   * Resets the applet.
   */
  public void reset() {
    cryptoText.setText( initialMessage() );
  }
    
  /**
   * Displays a string in the text area.
   */
  public void setDisplay( String s ) {
    cryptoText.setText(s);
  } 
  
  /**
   * Gets the text in the text area.
   */
  public String getCipherText(  ) {
    return cryptoText.getText();
  } 
  
} // CryptoGramTool class
 

Java online compiler

Write, Run & Share Java code online using OneCompiler's Java online compiler for free. It's one of the robust, feature-rich online compilers for Java language, running the Java LTS version 17. Getting started with the OneCompiler's Java editor is easy and fast. The editor shows sample boilerplate code when you choose language as Java and start coding.

Taking inputs (stdin)

OneCompiler's Java online editor supports stdin and users can give inputs to the programs using the STDIN textbox under the I/O tab. Using Scanner class in Java program, you can read the inputs. Following is a sample program that shows reading STDIN ( A string in this case ).

import java.util.Scanner;
class Input {
    public static void main(String[] args) {
    	Scanner input = new Scanner(System.in);
    	System.out.println("Enter your name: ");
    	String inp = input.next();
    	System.out.println("Hello, " + inp);
    }
}

Adding dependencies

OneCompiler supports Gradle for dependency management. Users can add dependencies in the build.gradle file and use them in their programs. When you add the dependencies for the first time, the first run might be a little slow as we download the dependencies, but the subsequent runs will be faster. Following sample Gradle configuration shows how to add dependencies

apply plugin:'application'
mainClassName = 'HelloWorld'

run { standardInput = System.in }
sourceSets { main { java { srcDir './' } } }

repositories {
    jcenter()
}

dependencies {
    // add dependencies here as below
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
}

About Java

Java is a very popular general-purpose programming language, it is class-based and object-oriented. Java was developed by James Gosling at Sun Microsystems ( later acquired by Oracle) the initial release of Java was in 1995. Java 17 is the latest long-term supported version (LTS). As of today, Java is the world's number one server programming language with a 12 million developer community, 5 million students studying worldwide and it's #1 choice for the cloud development.

Syntax help

Variables

short x = 999; 			// -32768 to 32767
int   x = 99999; 		// -2147483648 to 2147483647
long  x = 99999999999L; // -9223372036854775808 to 9223372036854775807

float x = 1.2;
double x = 99.99d;

byte x = 99; // -128 to 127
char x = 'A';
boolean x = true;

Loops

1. If Else:

When ever you want to perform a set of operations based on a condition If-Else is used.

if(conditional-expression) {
  // code
} else {
  // code
}

Example:

int i = 10;
if(i % 2 == 0) {
  System.out.println("i is even number");
} else {
  System.out.println("i is odd number");
}

2. Switch:

Switch is an alternative to If-Else-If ladder and to select one among many blocks of code.

switch(<conditional-expression>) {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 //code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition. Usually for loop is preferred when number of iterations is known in advance.

for(Initialization; Condition; Increment/decrement){  
    //code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(<condition>){  
 // code 
}  

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {
  // code 
} while (<condition>); 

Classes and Objects

Class is the blueprint of an object, which is also referred as user-defined data type with variables and functions. Object is a basic unit in OOP, and is an instance of the class.

How to create a Class:

class keyword is required to create a class.

Example:

class Mobile {
    public:    // access specifier which specifies that accessibility of class members 
    string name; // string variable (attribute)
    int price; // int variable (attribute)
};

How to create a Object:

Mobile m1 = new Mobile();

How to define methods in a class:

public class Greeting {
    static void hello() {
        System.out.println("Hello.. Happy learning!");
    }

    public static void main(String[] args) {
        hello();
    }
}

Collections

Collection is a group of objects which can be represented as a single unit. Collections are introduced to bring a unified common interface to all the objects.

Collection Framework was introduced since JDK 1.2 which is used to represent and manage Collections and it contains:

  1. Interfaces
  2. Classes
  3. Algorithms

This framework also defines map interfaces and several classes in addition to Collections.

Advantages:

  • High performance
  • Reduces developer's effort
  • Unified architecture which has common methods for all objects.
CollectionDescription
SetSet is a collection of elements which can not contain duplicate values. Set is implemented in HashSets, LinkedHashSets, TreeSet etc
ListList is a ordered collection of elements which can have duplicates. Lists are classified into ArrayList, LinkedList, Vectors
QueueFIFO approach, while instantiating Queue interface you can either choose LinkedList or PriorityQueue.
DequeDeque(Double Ended Queue) is used to add or remove elements from both the ends of the Queue(both head and tail)
MapMap contains key-values pairs which don't have any duplicates. Map is implemented in HashMap, TreeMap etc.