private void createKeyBindings(ChunkReader reader, ChunkModel model,
			FVEventListener eventListener) {

		// Use input maps to handle keystrokes. Don't use the old KeyListener interface for these;
		// we want to provide our own behavior and not be confused with any default keystroke
		// handlers.
		InputMap im_table = getInputMap();
		ActionMap am_table = getActionMap();
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "DownArrow");
		am_table.put("DownArrow", new ArrowDownAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "UpArrow");
		am_table.put("UpArrow", new ArrowUpAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), "PageDown");
		am_table.put("PageDown", new PageDownAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), "PageUp");
		am_table.put("PageUp", new PageUpAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0), "Home");
		am_table.put("Home", new HomeAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), "End");
		am_table.put("End", new EndAction(eventListener));

		// Handle arrow up and arrow down when the shift key is pressed, meaning we need to 
		// move the viewport AND maintain selection.
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.SHIFT_DOWN_MASK),
			"DownArrowSelection");
		am_table.put("DownArrowSelection", new ArrowDownSelectionAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_DOWN_MASK),
			"UpArrowSelection");
		am_table.put("UpArrowSelection", new ArrowUpSelectionAction(eventListener));

		// Handle Page up and Page down when the shift key is pressed, meaning we need to 
		// move the viewport AND maintain selection.
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, InputEvent.SHIFT_DOWN_MASK),
			"PageDownSelection");
		am_table.put("PageDownSelection", new PageDownSelectionAction(eventListener));
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, InputEvent.SHIFT_DOWN_MASK),
			"PageUpSelection");
		am_table.put("PageUpSelection", new PageUpSelectionAction(eventListener));

		// Set up a key binding for copying selected rows to the clipboard.
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK), "copyText");
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.META_DOWN_MASK), "copyText");
		am_table.put("copyText", new AbstractAction() {

			@Override
			public void actionPerformed(ActionEvent e) {
				FVEvent copyEvt = new FVEvent(EventType.COPY_SELECTION, null);
				eventListener.send(copyEvt);
			}

		});

		// Recognize when the shift key has been pressed and released, so we know how to handle 
		// selection.
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, InputEvent.SHIFT_DOWN_MASK, false),
			"ShiftPressed");
		am_table.put("ShiftPressed", new AbstractAction() {

			@Override
			public void actionPerformed(ActionEvent e) {
				shiftDown = true;
			}
		});
		im_table.put(KeyStroke.getKeyStroke("released SHIFT"), "ShiftReleased");
		am_table.put("ShiftReleased", new AbstractAction() {

			@Override
			public void actionPerformed(ActionEvent e) {
				shiftDown = false;
			}
		});

		// Now create a binding for the CTRL-A, select all action.
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK, false),
			"SelectAll");
		im_table.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.META_DOWN_MASK, false),
			"SelectAll");
		am_table.put("SelectAll", new AbstractAction() {

			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					model.selectedByteStart = 0;
					model.selectedByteEnd = reader.getFileSize() - 1;

					FVEvent copyEvt = new FVEvent(EventType.COPY_SELECTION, null);
					eventListener.send(copyEvt);

					restoreSelection();
				}
				catch (IOException e1) {
					Msg.error(this, "error reading file size: " + e);
				}
			}
		});
	}
Create key bindings for the table. We have to capture the following:
  - arrow down
  - arrow up
  - page down
  - page up
  - home
  - end
  - Ctrl-C (Command-C for mac) for copy
  - Ctrl-A (Command-A for mac) for select all
  - Shift pressed 
  - Shift released

@param reader
@param model
@param eventListener
Ghidra/Framework/Project/src/main/java/ghidra/framework/main/logviewer/ui/FVTable.java