Skip to content

Commit

Permalink
Merge pull request #2 from ius-csg/add-clipboard
Browse files Browse the repository at this point in the history
Add clipboard, Multiline TextBox, and Ctrl + A support in Linux
  • Loading branch information
jasekiw authored Jan 28, 2019
2 parents a45fc32 + 6afea7e commit 2565003
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 68 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.iuscsg.autotyper</groupId>
<artifactId>auto-typer</artifactId>
<version>1.2-SNAPSHOT</version>
<version>1.3-SNAPSHOT</version>

<name>auto-typer</name>
<url>https://github.com/ius-csg/AutoTyper</url>
Expand Down
63 changes: 52 additions & 11 deletions src/main/java/org/iuscsg/autotyper/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package org.iuscsg.autotyper;

import org.iuscsg.autotyper.hotkey.HotKeyListener;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
Expand All @@ -10,15 +14,17 @@
// changing the package or the name of this class will require updating the isRunningInJar method in this class.
public class Application extends Frame
{
private TextField txt = makeTextField();
private TextArea txt = themeControl(new TextArea("", 0, 0, TextArea.SCROLLBARS_NONE), 12);
private HistoryManager historyManager = new HistoryManager();

private Button btn = makeButton();
private HotKeyListener keyListener = makeHotKeyListener();
private Application() {
if(shouldRedirectLogging()) // logging for if anyone runs into issues.
turnOnLogging();
setIcon();
Button btn = makeButton();
historyManager.init(txt, btn);
historyManager.init(txt);
btn.addKeyListener(keyListener);
txt.addKeyListener(keyListener);
add(txt);
add(btn);
setTitle("Auto Typer");
Expand All @@ -29,6 +35,11 @@ private Application() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}

@Override
public void windowDeactivated(WindowEvent e) {
keyListener.onFrameDeactivated();
}
});
}

Expand All @@ -39,7 +50,7 @@ public static void main(String[] args) {
private Button makeButton() {
Button btn = new Button();
btn.setLabel("Type it!");
btn.addActionListener(e ->typeWithDelay(txt.getText()));
btn.addActionListener(e -> onBtn_Click());
return themeControl(btn, 18);
}

Expand All @@ -50,11 +61,6 @@ private <T extends Component> T themeControl(T component, int fontSize) {
return component;
}

private TextField makeTextField() {
TextField txt = new TextField();
return themeControl(txt, 12);
}

private void setIcon() {
try {
InputStream letter = this.getClass().getClassLoader().getResourceAsStream("resources/letter.png");
Expand All @@ -69,6 +75,17 @@ private void setIcon() {
}
}

private void onBtn_Click() {
if(keyListener.getModifierKeyState().isKeyDown()) {
String clipboard = getClipboard();
if(clipboard != null && clipboard.length() > 0) {
typeWithDelay(clipboard);
return;
}
}
typeWithDelay(txt.getText());
}

private void typeWithDelay(String text) {
(new Thread(new Typer(text))).start();
historyManager.addToHistory(text);
Expand All @@ -86,10 +103,34 @@ private boolean isRunningInJar() {

private void turnOnLogging() {
try {
PrintStream out = new PrintStream(new FileOutputStream("AutoTyper.log"));
PrintStream out = new PrintStream(new FileOutputStream("AutoTyper.log", true));
System.setOut(out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

private String getClipboard() {
try {
return (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
return null;
}

private HotKeyListener makeHotKeyListener() {
return new HotKeyListener(
(boolean down) -> { if(down) historyManager.goForward(); },
(boolean down) -> { if(down) historyManager.goBack(); },
(boolean down) -> {
if(down) btn.setLabel("Type from clipboard!");
else btn.setLabel("Type It!");
},
(down) -> { if(txt.hasFocus()) {
txt.selectAll();
} }
);
}

}
47 changes: 22 additions & 25 deletions src/main/java/org/iuscsg/autotyper/HistoryManager.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.iuscsg.autotyper;

import org.iuscsg.autotyper.hotkey.HotKeyListener;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -11,22 +9,18 @@ class HistoryManager
private ArrayList<String> history = new ArrayList<>(Collections.singletonList(""));
private boolean ignoreTextChange = false;
private int historyIndex = 0;
private TextField txt;
private TextArea txt;

void init(TextField txt, Button btn) {
void init(TextArea txt) {
this.txt = txt;
HotKeyListener hotkeyListener = initHotKeyListener();

txt.addTextListener(e -> {
if(ignoreTextChange) {
ignoreTextChange = false;
return;
}
historyIndex = -1;
});

txt.addKeyListener(hotkeyListener);
btn.addKeyListener(hotkeyListener);

}

void addToHistory(String text) {
Expand All @@ -36,23 +30,26 @@ void addToHistory(String text) {
historyIndex = 0;
}

private HotKeyListener initHotKeyListener() {
return new HotKeyListener(() -> {
if(historyIndex > 0){
historyIndex--;
ignoreTextChange = true;
txt.setText(history.get(historyIndex));
}
}, () -> {
if(history.size() > historyIndex + 1) {
if(historyIndex == -1) {
history.add(0, txt.getText());
historyIndex++;
}
public void goBack() {
if(history.size() > historyIndex + 1) {
if(historyIndex == -1) {
history.add(0, txt.getText());
historyIndex++;
ignoreTextChange = true;
txt.setText(history.get(historyIndex));
}
});
historyIndex++;
ignoreTextChange = true;
txt.setText(history.get(historyIndex));
}
}

public void goForward()
{
if (historyIndex > 0) {
historyIndex--;
ignoreTextChange = true;
txt.setText(history.get(historyIndex));
}
}


}
12 changes: 10 additions & 2 deletions src/main/java/org/iuscsg/autotyper/Typer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.security.Key;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -51,6 +52,13 @@ else if(isAlpha(key) && key.toUpperCase().equals(key))
typeKeyWithShift(key, getKeyCode(key));
else if(isAlphaNumeric(key))
typeKeyWithKeyCode(key, getKeyCode(key));
else if(key.equals("\n"))
typeKeyWithKeyCode(key, KeyEvent.VK_ENTER);
else if(key.equals("\r")) {
// ignore this character
}
else
System.out.println("Unknown Key: " + key);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch(NoSuchFieldException e ) {
Expand All @@ -61,8 +69,7 @@ else if(isAlphaNumeric(key))
private void typeKeyWithShift(String key, int keycode) {
try {
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(keycode);
robot.keyRelease(keycode);
typeKeyWithKeyCode(key, keycode);
robot.keyRelease(KeyEvent.VK_SHIFT);
} catch (IllegalArgumentException e) {
System.out.println("Invalid key: " + key + " with Shift key and keycode: " + keycode);
Expand All @@ -73,6 +80,7 @@ private void typeKeyWithKeyCode(String key, int keycode) {
try {
robot.keyPress(keycode);
robot.keyRelease(keycode);
robot.delay(8);
} catch (IllegalArgumentException e) {
System.out.println("Invalid key: " + key + " with keycode: " + keycode);
}
Expand Down
55 changes: 32 additions & 23 deletions src/main/java/org/iuscsg/autotyper/hotkey/HotKeyListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,26 @@

public class HotKeyListener implements KeyListener
{
private boolean backDown = false;
private boolean forwardDown = false;

private OnHistoryChangeListener onForwardListener;
private OnHistoryChangeListener onBackListener;
private KeyState selectAllKeyState;
private KeyState onModifierKeyState;
private KeyState onBackKeyState;
private KeyState onForwardKeyState;

public HotKeyListener(OnKeyChange onForwardListener,
OnKeyChange onBackListener,
OnKeyChange onModifierListener,
OnKeyChange onSelectAllListener) {
this.selectAllKeyState = new KeyState(down -> {
if(this.onModifierKeyState.isKeyDown() && down) onSelectAllListener.onChange(true);
}, KeyEvent.VK_A);
this.onModifierKeyState = new KeyState(onModifierListener, KeyEvent.VK_CONTROL);
this.onBackKeyState = new KeyState(onBackListener, KeyEvent.VK_UP);
this.onForwardKeyState = new KeyState(onForwardListener, KeyEvent.VK_DOWN);
}

public HotKeyListener(OnHistoryChangeListener onForwardListener, OnHistoryChangeListener onBackListener) {
this.onForwardListener = onForwardListener;
this.onBackListener = onBackListener;
public KeyState getModifierKeyState() {
return this.onModifierKeyState;
}

@Override
Expand All @@ -22,28 +33,26 @@ public void keyTyped(KeyEvent e) { /* NOT NEEDED */}
@Override
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode()) {
case KeyEvent.VK_UP: backDown = true; break;
case KeyEvent.VK_DOWN: forwardDown = true; break;
}
executeListenersIfHotKeysPressed();
selectAllKeyState.handleKeyPressed(e);
onModifierKeyState.handleKeyPressed(e);
onBackKeyState.handleKeyPressed(e);
onForwardKeyState.handleKeyPressed(e);
}

@Override
public void keyReleased(KeyEvent e)
{
switch(e.getKeyCode()) {
case KeyEvent.VK_UP: backDown = false; break;
case KeyEvent.VK_DOWN: forwardDown = false; break;
}
selectAllKeyState.handleKeyReleased(e);
onModifierKeyState.handleKeyReleased(e);
onBackKeyState.handleKeyReleased(e);
onForwardKeyState.handleKeyReleased(e);
}


private void executeListenersIfHotKeysPressed() {
if (backDown) {
onBackListener.onChange();
} else if(forwardDown) {
onForwardListener.onChange();
}
public void onFrameDeactivated() {
selectAllKeyState.handleFrameDeactivation();
onModifierKeyState.handleFrameDeactivation();
onBackKeyState.handleFrameDeactivation();
onForwardKeyState.handleFrameDeactivation();
}

}
34 changes: 34 additions & 0 deletions src/main/java/org/iuscsg/autotyper/hotkey/KeyState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.iuscsg.autotyper.hotkey;

import java.awt.event.KeyEvent;

public class KeyState
{
private boolean keyDown = false;
private OnKeyChange onKeyChangeListener;
private int keycode;

public KeyState(OnKeyChange onKeyChangeListener, int keycode) {
this.onKeyChangeListener = onKeyChangeListener;
this.keycode = keycode;
}

public void handleKeyPressed(KeyEvent e) {
if(e.getKeyCode() == keycode && !keyDown) {
keyDown = true;
onKeyChangeListener.onChange(true);
}
}
public void handleKeyReleased(KeyEvent e) {
if(e.getKeyCode() == keycode && keyDown) {
keyDown = false;
onKeyChangeListener.onChange(false);
}
}
public boolean isKeyDown() {
return this.keyDown;
}
public void handleFrameDeactivation() {
keyDown = false;
}
}

This file was deleted.

6 changes: 6 additions & 0 deletions src/main/java/org/iuscsg/autotyper/hotkey/OnKeyChange.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.iuscsg.autotyper.hotkey;

public interface OnKeyChange
{
void onChange(boolean keyDown);
}

0 comments on commit 2565003

Please sign in to comment.