package javacodebook.gui.keystroke;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

/**
 * @author Benjamin Rusch
 * 
 * Die einzelnen Buttons können über CTRL + A, F2 und SHIFT + F2 für "Hinzufügen" 
 * und über CTRL + D, F3 und SHIFT F3 für "Löschen" aufgerufen werden. 
 * Ist einer der Buttons im Focus, funktioniert das Auslösen auch über ENTER.
 */

public class KeyStrokesSwing  extends JFrame {
	
	
	// Tasten(bzw. Tastenkombinationen) werden durch Objekte der KeyStroke-Klasse 
	// repräsentiert. Durch die Methode:
	//  	getKeyStroke(int keyCode, int modifier, boolean onKeyRelease)
	// bekommt man entsprechendes KeyStroke-Objekt.
	// keyCode: definiert die Taste(Konstanten der Klasse KeyEvent können verwendet werden)
	// modifier: bei normalen Tasten Druck == 0
	//			 bei Shift == 1 
	//			 bei Strg == 2
	// onKeyRelease: bei true wird Event erst beim loslassen der Taste ausgelöst 
	//				 bei false schon beim drücken
	public static final KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,false);
	
	public static final KeyStroke f2 = KeyStroke.getKeyStroke(KeyEvent.VK_F2,0,false);
	public static final KeyStroke shiftF2 = KeyStroke.getKeyStroke(KeyEvent.VK_F2,1,false);
	public static final KeyStroke controlA = KeyStroke.getKeyStroke(KeyEvent.VK_A,2,false);
	
	public static final KeyStroke f3 = KeyStroke.getKeyStroke(KeyEvent.VK_F3,0,false);
	public static final KeyStroke shiftF3 = KeyStroke.getKeyStroke(KeyEvent.VK_F3,1,false);
	public static final KeyStroke controlD = KeyStroke.getKeyStroke(KeyEvent.VK_D,2,false);

	private JButton addButton		= new JButton("Hinzufügen");
	private JButton deleteButton	= new JButton("Löschen");
	private JTextField field 		= new JTextField(15);
	private JPanel north			= new JPanel(); 
	private JTextArea editor		= new JTextArea(9,20);
	
	private Container content		= null;

	/**
 	*	Konstruktor von KeyStrokes.  
 	*/	
	public KeyStrokesSwing(String title) {
		
		super(title);

		content = this.getContentPane();
		// Focus aufs Textfeld setzen, und Programm-Beenden-Funktionalität 
		// implementieren
		addWindowListener(new WindowAdapter() {
            public void windowOpened(WindowEvent e) {
                field.requestFocus(); // Focus wird gesetzt
            }
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
		

		// Anmelden eines ActionListeners an den addButton, die AbstractAction 
		// erfüllt auch das ActionListener interface.
		addButton.addActionListener(new AddAction());
		
		// Anmelden eines ActionListeners an den deleteButton		
		deleteButton.addActionListener(new DeleteAction());

		 // Keystrokes werden mit zugehöriger Action-Schlüssel an den addButton 
		 // angemeldet.
		addButton.getInputMap().put(f2,"add");
    	addButton.getInputMap().put(shiftF2,"add");
	    addButton.getInputMap().put(controlA,"add");
		addButton.getInputMap().put(f3,"delete");
    	addButton.getInputMap().put(shiftF3,"delete");
	    addButton.getInputMap().put(controlD,"delete");
	    addButton.getInputMap().put(enter,"add");
	    
	    // Beide Möglichen Aktionen die ausgeführt werden sollen, wenn die 
	    // Komponente im Focus ist, müssen über den entsprechenden Schlüssel 
	    // an seiner ActionMap angemeldet werden. 
	    // (Anmerkung: Delete soll über "Strg + D" natürlich auch ausgeführt werden, 
	    // wenn der addButton im Focus ist.) 
	    addButton.getActionMap().put("add", new AddAction());
	    addButton.getActionMap().put("delete", new DeleteAction());
	    
	    // Keystrokes und Actions werden an den deleteButton angemeldet.
		deleteButton.getInputMap().put(f2,"add");
    	deleteButton.getInputMap().put(shiftF2,"add");
	    deleteButton.getInputMap().put(controlA,"add");
		deleteButton.getInputMap().put(f3,"delete");
    	deleteButton.getInputMap().put(shiftF3,"delete");
	    deleteButton.getInputMap().put(controlD,"delete");
	    deleteButton.getInputMap().put(enter,"delete");
	    
	    deleteButton.getActionMap().put("add", new AddAction());
	    deleteButton.getActionMap().put("delete", new DeleteAction());
	    
	    // Keystrokes und Action werden an das field angemeldet.
		field.getInputMap().put(f2,"add");
    	field.getInputMap().put(shiftF2,"add");
	    field.getInputMap().put(controlA,"add");
		field.getInputMap().put(f3,"delete");
    	field.getInputMap().put(shiftF3,"delete");
	    field.getInputMap().put(controlD,"delete");
	    
	    field.getActionMap().put("add", new AddAction());
	    field.getActionMap().put("delete", new DeleteAction());

		// Editor soll nicht focusierbar sein
		editor.setFocusable(false);

		// Platzieren der Komponenten
		north.add(addButton);
		north.add(deleteButton);
		north.add(field);

		content.add(north, BorderLayout.NORTH);
		content.add(editor);
	}
	
	private class AddAction extends AbstractAction {
		 public void actionPerformed(ActionEvent evt) {
	                editor.append(field.getText());
	            }
	}
	private class DeleteAction extends AbstractAction {
		 public void actionPerformed(ActionEvent evt) {
	                editor.setText("");
	            }
	}
}
