diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..ea7f567
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f547dc2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/.gradle/
+/bin/
diff --git a/.project b/.project
new file mode 100644
index 0000000..b970bf3
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ ClickMyText
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 0000000..e479558
--- /dev/null
+++ b/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+arguments=
+auto.sync=false
+build.scans.enabled=false
+connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
+connection.project.dir=
+eclipse.preferences.version=1
+gradle.user.home=
+java.home=
+jvm.arguments=
+offline.mode=false
+override.workspace.settings=false
+show.console.view=false
+show.executions.view=false
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..626e0e1
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.source=17
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..b7e2ffc
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,39 @@
+plugins {
+ id 'java'
+ id 'eclipse'
+ id 'application'
+}
+
+group 'de.jottyfan.guitools'
+version '0.0.1'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'org.swinglabs.swingx:swingx-core:1.6.5-1'
+ implementation 'org.apache.commons:commons-lang3:3.12.0'
+ testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0'
+}
+
+application {
+ mainClass = 'Main'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+jar {
+ manifest {
+ attributes (
+ 'Main-Class': 'Main',
+ 'Implementation-Version': version
+ )
+ }
+ archiveBaseName = project.name
+ from {
+ configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+ }
+}
diff --git a/src/main/java/de/jottyfan/guitools/Gui.java b/src/main/java/de/jottyfan/guitools/Gui.java
new file mode 100644
index 0000000..1a9bd93
--- /dev/null
+++ b/src/main/java/de/jottyfan/guitools/Gui.java
@@ -0,0 +1,239 @@
+package de.jottyfan.guitools;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.HeadlessException;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+/**
+ *
+ * @author jotty
+ *
+ */
+public class Gui extends JFrame {
+ private static final long serialVersionUID = 1L;
+
+ private JTextArea clipboardContent;
+
+ /**
+ * for the first call
+ *
+ * @param args the args; the first one might contain a file path
+ */
+ public Gui(String[] args) {
+ Set list = new HashSet<>();
+ if (args != null && args.length > 0) {
+ String filename = args[1];
+ try {
+ list.addAll(readFileLines(filename));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ setup(list);
+ }
+
+ /**
+ * for the recreation after a new search term has been added
+ *
+ * @param list the list of search terms
+ */
+ private Gui(Set list) {
+ setup(list);
+ }
+
+ /**
+ * reads the lines of the file; filename is expected to be a text file with one
+ * word a line
+ *
+ * @param filename the file name to the text file
+ * @return the list of search terms
+ * @throws IOException on file reading errors
+ */
+ private List readFileLines(String filename) throws IOException {
+ List list = new ArrayList<>();
+ try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (!line.isBlank()) {
+ list.add(line);
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * setup the window
+ *
+ * @param clickables the list of search terms
+ */
+ public void setup(Set clickables) {
+ this.getContentPane().removeAll();
+
+ Gui thisWindow = this;
+
+ setTitle("ClickMyText");
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setSize(600, 400);
+ setLayout(new BorderLayout());
+
+ JPanel menubar = new JPanel();
+ menubar.setLayout(new FlowLayout());
+
+ JTextField textline = new JTextField();
+ textline.setSize(20, 20);
+ Dimension d = new Dimension(200, 25);
+ textline.setMinimumSize(d);
+ textline.setPreferredSize(d);
+ textline.setMaximumSize(d);
+
+ menubar.add(textline);
+
+ JButton plusBtn = new JButton("Add");
+ plusBtn.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ clickables.add(textline.getText());
+ SwingUtilities.invokeLater(() -> {
+ dispose();
+ Gui gui = new Gui(clickables);
+ gui.setVisible(true);
+ });
+ }
+ });
+ menubar.add(plusBtn);
+
+ JButton saveBtn = new JButton("Save");
+ saveBtn.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ JFileChooser fileChooser = new JFileChooser();
+ int result = fileChooser.showSaveDialog(thisWindow);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ String filename = fileChooser.getSelectedFile().getAbsolutePath();
+ try {
+ FileWriter writer = new FileWriter(filename);
+ for (String term : clickables) {
+ writer.write(term);
+ writer.write("\n");
+ }
+ writer.close();
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ }
+ }
+ });
+ menubar.add(saveBtn);
+
+ JButton loadBtn = new JButton("Load");
+ loadBtn.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ JFileChooser fileChooser = new JFileChooser();
+ int result = fileChooser.showOpenDialog(thisWindow);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ String filename = fileChooser.getSelectedFile().getAbsolutePath();
+ SwingUtilities.invokeLater(() -> {
+ dispose();
+ Gui gui = new Gui(new String[] { null, filename });
+ gui.setVisible(true);
+ });
+ }
+ }
+ });
+ menubar.add(loadBtn);
+
+ JButton exitBtn = new JButton("Exit");
+ exitBtn.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ System.exit(0);
+ }
+ });
+ menubar.add(exitBtn);
+
+ JPanel linksPanel = new JPanel();
+ linksPanel.setLayout(new GridLayout(6, 2, 2, 2));
+
+ for (String clickable : clickables) {
+ JButton btn = new JButton(clickable);
+ btn.addMouseListener(new MouseAdapter() {
+ public void mouseClicked(MouseEvent e) {
+ copyToClipboard(clickable);
+ }
+ });
+ linksPanel.add(btn);
+ }
+
+ clipboardContent = new JTextArea(3, 30);
+ clipboardContent.setEditable(false);
+ clipboardContent.setBorder(BorderFactory.createTitledBorder("Clipboard content"));
+ copyFromClipboard();
+
+ JScrollPane scrollPane = new JScrollPane(clipboardContent);
+ add(menubar, BorderLayout.NORTH);
+ add(linksPanel, BorderLayout.CENTER);
+ add(scrollPane, BorderLayout.SOUTH);
+ }
+
+ /**
+ * copy the clipboard content to the preview field
+ *
+ */
+ private void copyFromClipboard() {
+ Object content;
+ try {
+ content = Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
+ if (content != null) {
+ clipboardContent.setText(content.toString());
+ }
+ } catch (HeadlessException | IOException e) {
+ e.printStackTrace();
+ } catch (UnsupportedFlavorException e) {
+ // ignore; this might be only an empty clipboard
+ System.out.println("no clipboard content found");
+ }
+ }
+
+ /**
+ * the text might be copied to the clipboard immediately
+ *
+ * @param text the text to copy
+ */
+ private void copyToClipboard(String text) {
+ StringSelection selection = new StringSelection(text);
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ clipboard.setContents(selection, null); // update the clipboard from the selection
+
+ clipboardContent.setText(text); // update the preview from the clipboard
+ }
+
+}
diff --git a/src/main/java/de/jottyfan/guitools/Main.java b/src/main/java/de/jottyfan/guitools/Main.java
new file mode 100644
index 0000000..4d4b3e3
--- /dev/null
+++ b/src/main/java/de/jottyfan/guitools/Main.java
@@ -0,0 +1,24 @@
+package de.jottyfan.guitools;
+
+import javax.swing.SwingUtilities;
+
+/**
+ *
+ * @author jotty
+ *
+ */
+public class Main {
+
+ /**
+ * start the application; if args is given, the first argument is a filename for
+ * a list of strings
+ *
+ * @param args the args
+ */
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(() -> {
+ Gui gui = new Gui(args);
+ gui.setVisible(true);
+ });
+ }
+}