diff --git a/.gitignore b/.gitignore index 524f096..ce8e466 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ -# Compiled class file +# Compiled class files *.class -# Log file +# Log files *.log +# IML files +*.iml + # BlueJ files *.ctxt @@ -22,3 +25,13 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* replay_pid* + +# Intellij Idea +out/ + +# Visual Studio Code +.vscode/ + +# Eclipse +*.classpath +*.project \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/artifacts/Indev_1_0.xml b/.idea/artifacts/Indev_1_0.xml new file mode 100644 index 0000000..39ea8f3 --- /dev/null +++ b/.idea/artifacts/Indev_1_0.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/out/artifacts/Indev_1_0 + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..6f29fee --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e9f4691 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..161feed --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: src.ExmlEditor + diff --git a/ReadMe.md b/ReadMe.md index bc1727c..7295e86 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,17 +1,7 @@ -# TextEditor (java) Modifications +# Update V1.0.0 -This is a simple text editor. Using it as a starting point, it needs a bunch of functionality additions. +Updating [ZCW-Java91 project](https://github.com/ZCW-Java91/TextEditor-Java) -## Additions +V1.0.0 -Things to add: - -- find/replace text implementation -- when you exit, you must NOT lose un-saved changes -- add a new window, scrollable, with some editor help documentation in it. -- implement Word Wrap (yeah, look it up) -- add a font panel, so you can change the font you edit in. - - make sure not only new files are in th enew font, but existing windows too. -- add a way to print the current file. -- add a way to set the page in portrait or landscape mode -- Make your About Dialog snazzy! +My very first notepad in java \ No newline at end of file diff --git a/TextEditor-Java.iml b/TextEditor-Java.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/TextEditor-Java.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..74d6c41 --- /dev/null +++ b/changelog.md @@ -0,0 +1,4 @@ +Rewriting code from start + +Adding unachieved features : +- \ No newline at end of file diff --git a/out/production/TextEditor-Java/.gitignore b/out/production/TextEditor-Java/.gitignore new file mode 100644 index 0000000..ce8e466 --- /dev/null +++ b/out/production/TextEditor-Java/.gitignore @@ -0,0 +1,37 @@ +# Compiled class files +*.class + +# Log files +*.log + +# IML files +*.iml + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +# Intellij Idea +out/ + +# Visual Studio Code +.vscode/ + +# Eclipse +*.classpath +*.project \ No newline at end of file diff --git a/out/production/TextEditor-Java/.idea/.gitignore b/out/production/TextEditor-Java/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/out/production/TextEditor-Java/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/out/production/TextEditor-Java/.idea/misc.xml b/out/production/TextEditor-Java/.idea/misc.xml new file mode 100644 index 0000000..6f29fee --- /dev/null +++ b/out/production/TextEditor-Java/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/out/production/TextEditor-Java/.idea/modules.xml b/out/production/TextEditor-Java/.idea/modules.xml new file mode 100644 index 0000000..e9f4691 --- /dev/null +++ b/out/production/TextEditor-Java/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/out/production/TextEditor-Java/.idea/uiDesigner.xml b/out/production/TextEditor-Java/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/out/production/TextEditor-Java/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/out/production/TextEditor-Java/.idea/vcs.xml b/out/production/TextEditor-Java/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/out/production/TextEditor-Java/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/out/production/TextEditor-Java/ReadMe.md b/out/production/TextEditor-Java/ReadMe.md new file mode 100644 index 0000000..1cbda50 --- /dev/null +++ b/out/production/TextEditor-Java/ReadMe.md @@ -0,0 +1,8 @@ +# Update alpha 1.0 + +I modify a lot on your project, the code is kinda... mess but i'll try to update it sometimes. I wrote the code from the beginning by reprogramming the editor you already did. + +I added a lot of features, here a complete list of them : + +- New +- diff --git a/out/production/TextEditor-Java/TextEditor-Java.iml b/out/production/TextEditor-Java/TextEditor-Java.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/out/production/TextEditor-Java/TextEditor-Java.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/CustomKeyListener.java b/src/CustomKeyListener.java new file mode 100644 index 0000000..8852053 --- /dev/null +++ b/src/CustomKeyListener.java @@ -0,0 +1,55 @@ +package src; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +public class CustomKeyListener implements KeyListener { + private final ExmlEditor window; + private boolean flagA = false; + + public CustomKeyListener(ExmlEditor window) { + this.window = window; + } + + @Override + public void keyTyped(KeyEvent e) { + if (!window.isFileSaved()) { + if (!flagA) { + window.setTitle(window.getTitle() + "*"); + flagA = true; + } + } else { + if (window.getOpenedFile() == null) { + window.setTitle("Notepad - Untitled"); + } else { + window.setTitle("Notepad - " + window.getOpenedFile().getName()); + } + flagA = false; + } + } + + @Override + public void keyPressed(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + if (!window.isFileSaved()) { + if (!flagA) { + window.setTitle(window.getTitle() + "*"); + flagA = true; + } + } else { + if (window.getOpenedFile() == null) { + window.setTitle("Notepad - Untitled"); + } else { + window.setTitle("Notepad - " + window.getOpenedFile().getName()); + } + flagA = false; + } + + if (e.getKeyCode() == KeyEvent.VK_SPACE || e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_COMMA || e.getKeyCode() == KeyEvent.VK_PERIOD) { + window.AppendText(); + } + } +} diff --git a/src/CustomMenuBar.java b/src/CustomMenuBar.java new file mode 100644 index 0000000..ac70378 --- /dev/null +++ b/src/CustomMenuBar.java @@ -0,0 +1,412 @@ +package src; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.Objects; + +public class CustomMenuBar extends MenuBar { + public CustomMenuBar(ExmlEditor parent) { + Menu filemenu = new Menu("File"); + MenuComponent[] filemenuitems = {new MenuItem("New", new MenuShortcut(KeyEvent.VK_N, false)), new MenuItem("New window"), new MenuSpace(),new MenuItem("Open", new MenuShortcut(KeyEvent.VK_O, false)), new MenuItem("Save", new MenuShortcut(KeyEvent.VK_S, false)), new MenuItem("Save as", new MenuShortcut(KeyEvent.VK_S, true)), new MenuItem("Print"), new MenuItem("Close window", new MenuShortcut(KeyEvent.VK_F4, true)), new MenuSpace(), new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_F4, false))}; + Menu editmenu = new Menu("Edit"); + MenuComponent[] editmenuitems = {new MenuItem("Undo", new MenuShortcut(KeyEvent.VK_Z, false)), new MenuItem("Redo", new MenuShortcut(KeyEvent.VK_Y, false)), new MenuSpace(),new MenuItem("Copy", new MenuShortcut(KeyEvent.VK_C, false)), new MenuItem("Cut", new MenuShortcut(KeyEvent.VK_X, false)), new MenuItem("Paste", new MenuShortcut(KeyEvent.VK_V, false)), new MenuItem("Delete", new MenuShortcut(KeyEvent.VK_DELETE, false)), new MenuSpace(), new MenuItem("Insert here"), new MenuItem("Insert values"), new MenuSpace(), new MenuItem("Replace", new MenuShortcut(KeyEvent.VK_R, false))}; + Menu selectionmenu = new Menu("Selection"); + MenuComponent[] selectionmenuitems = {new MenuItem("Select All", new MenuShortcut(KeyEvent.VK_A, false)), new MenuSpace(), new MenuItem("Copy line up"), new MenuItem("Copy line down"), new MenuItem("Duplicate line")}; + Menu appearancemenu = new Menu("Appearance"); + MenuComponent[] appearancemenuitems = {new MenuItem("Background color"), new MenuItem("Font color"), new CheckboxMenuItem("Title bar", true)}; + Menu helpmenu = new Menu("Help"); + MenuComponent[] helpmenuitems = {new MenuItem("About creator"), new MenuItem("About the project"), new MenuItem("Report issues")}; + for (MenuComponent menuComponent : filemenuitems) { + if (menuComponent instanceof MenuSpace) { + filemenu.addSeparator(); + } else if (menuComponent instanceof MenuItem) { + filemenu.add((MenuItem) menuComponent); + ((MenuItem) menuComponent).addActionListener(new CustomActionListener(((MenuItem) menuComponent), parent)); + } + } + + for (MenuComponent menuComponent : editmenuitems) { + if (menuComponent instanceof MenuSpace) { + editmenu.addSeparator(); + } else if (menuComponent instanceof MenuItem) { + editmenu.add((MenuItem) menuComponent); + ((MenuItem) menuComponent).addActionListener(new CustomActionListener(((MenuItem) menuComponent), parent)); + } + } + + for (MenuComponent menuComponent : selectionmenuitems) { + if (menuComponent instanceof MenuSpace) { + selectionmenu.addSeparator(); + } else if (menuComponent instanceof MenuItem) { + selectionmenu.add((MenuItem) menuComponent); + ((MenuItem) menuComponent).addActionListener(new CustomActionListener(((MenuItem) menuComponent), parent)); + } + } + + for (MenuComponent menuComponent : appearancemenuitems) { + if (menuComponent instanceof MenuSpace) { + appearancemenu.addSeparator(); + } else if (menuComponent instanceof CheckboxMenuItem) { + appearancemenu.add((CheckboxMenuItem) menuComponent); + ((CheckboxMenuItem) menuComponent).addActionListener(new CustomActionListener(((CheckboxMenuItem) menuComponent), parent)); + } else if (menuComponent instanceof MenuItem) { + appearancemenu.add((MenuItem) menuComponent); + ((MenuItem) menuComponent).addActionListener(new CustomActionListener(((MenuItem) menuComponent), parent)); + } + } + + for (MenuComponent menuComponent : helpmenuitems) { + helpmenu.add((MenuItem) menuComponent); + ((MenuItem) menuComponent).addActionListener(new CustomActionListener(((MenuItem) menuComponent), parent)); + } + + this.add(filemenu); + this.add(editmenu); + this.add(selectionmenu); + this.add(appearancemenu); + this.add(helpmenu); + } +} + +class MenuSpace extends MenuComponent { + public MenuSpace() {} +} + +class CustomActionListener implements ActionListener { + ExmlEditor parent = null; + T menuItem = null; + + public CustomActionListener(T menuItem, ExmlEditor parent) { + this.menuItem = menuItem; + this.parent = parent; + } + + public void actionPerformed(ActionEvent e) { + if (menuItem instanceof CheckboxMenuItem) { + switch (((CheckboxMenuItem) menuItem).getLabel()) { + case "Title bar": + parent.showTitleBar(((CheckboxMenuItem) menuItem).getState()); + } + } else if (menuItem instanceof MenuItem) { + switch (((MenuItem) menuItem).getLabel()) { + case "New": + if (!parent.isFileSaved()) { + switch (JOptionPane.showOptionDialog(parent, "The current file isn't saved, would save it ?", "Save ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null)) { + case JOptionPane.YES_OPTION: + parent.SaveAs(); + parent.textArea.setText(""); + parent.OpenedFile = null; + parent.TextContent = ""; + break; + case JOptionPane.NO_OPTION: + parent.textArea.setText(""); + parent.OpenedFile = null; + parent.TextContent = ""; + break; + case JOptionPane.CANCEL_OPTION: + break; + } + } else { + parent.textArea.setText(""); + } + parent.setTitle("Notepad - Untitled"); + parent.TextContent = ""; + break; + case "New window": + new ExmlEditor(); + break; + case "Open": + if (!parent.isFileSaved()) { + switch (JOptionPane.showOptionDialog(parent, "The current file isn't saved, would save it ?", "Save ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null)) { + case JOptionPane.YES_OPTION: + parent.SaveAs(); + parent.Open(); + break; + case JOptionPane.NO_OPTION: + parent.textArea.setText(""); + parent.OpenedFile = null; + parent.TextContent = ""; + parent.Open(); + break; + case JOptionPane.CANCEL_OPTION: + break; + } + } else { + parent.Open(); + } + + break; + case "Save": + if (parent.OpenedFile == null) { + parent.SaveAs(); + } else { + parent.Save(); + } + break; + case "Save as": + parent.SaveAs(); + break; + case "Print": + if (parent.OpenedFile == null) { + parent.SaveAs(); + } else { + parent.Save(); + } + parent.print(); + break; + case "Close window": + if (!parent.isFileSaved()) { + switch (JOptionPane.showOptionDialog(parent, "The current file isn't saved, would save it ?", "Save ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null)) { + case JOptionPane.YES_OPTION: + parent.SaveAs(); + break; + case JOptionPane.NO_OPTION: + parent.dispose(); + break; + case JOptionPane.CANCEL_OPTION: + break; + } + } else { + parent.dispose(); + } + break; + case "Exit": + if (!parent.isFileSaved()) { + switch (JOptionPane.showOptionDialog(parent, "The current file isn't saved, would save it ?", "Save ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null)) { + case JOptionPane.YES_OPTION: + parent.SaveAs(); + System.exit(0); + break; + case JOptionPane.NO_OPTION: + System.exit(0); + break; + case JOptionPane.CANCEL_OPTION: + break; + } + } else { + System.exit(0); + } + + case "Undo": + parent.Undo(); + break; + case "Redo": + parent.Redo(); + break; + case "Copy": + parent.Copy(); + break; + case "Cut": + parent.Cut(); + break; + case "Paste": + parent.Paste(); + break; + case "Delete": + parent.Delete(); + break; + case "Insert here": + String res = JOptionPane.showInputDialog(parent, "What would you insert ?"); + if (res == null) { + break; + } else { + parent.Insert(res); + } + break; + case "Insert values": + JPanel p = new JPanel(); + p.setLayout(new GridLayout(1, 1)); + String[] options = {"File name", "File size", "File path", "Epoch", "Time stamp", "Year", "Month", "Week", "Day", "Day of the week", "Hour", "Minute", "Second", "Random char", "Username", "Ipv4", "Ipv6"}; + JComboBox comboBox = new JComboBox<>(options); + p.add(comboBox); + + if (JOptionPane.showConfirmDialog(null, p, "Select a value to insert", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { + parent.Insert(parent.getKey((String) Objects.requireNonNull(comboBox.getSelectedItem()))); + } + + + break; + + case "Replace": + JPanel p2 = new JPanel(); + p2.setLayout(new GridLayout(2, 1, 20, 40)); + JTextField oldSequence = new JTextField(); + p2.add(oldSequence); + JTextField newSequence = new JTextField(); + p2.add(newSequence); + if (JOptionPane.showConfirmDialog(null, p2, "Replace", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { + parent.Replace(oldSequence.getText(), newSequence.getText()); + } + break; + case "Select All": + parent.SelectAll(); + break; + case "Copy line up": + parent.CopyLineUp(); + break; + case "Copy line down": + parent.CopyLineDown(); + break; + case "Duplicate line": + parent.DuplicateLine(); + break; + case "Background color": + parent.BGColor(); + break; + case "Font color": + parent.FGColor(); + break; + case "About creator": + Frame aboutcframe = new Frame(); + aboutcframe.setSize(450, 225); + aboutcframe.setResizable(false); + aboutcframe.setLocationRelativeTo(parent); + aboutcframe.setLayout(new GridLayout(4, 1)); + aboutcframe.add(new Label("Created by ZCW-Java91. (https://www.github.com/ZCW-Java91)")); + aboutcframe.add(new Label("Forked by E-xml. (https://www.github.com/E-xml)")); + aboutcframe.add(new Label("Mail : azertypatata8@gmail.com")); + aboutcframe.add(new Label("Youtube : https://www.youtube.com/@TheCpuguy239")); + aboutcframe.setTitle("About creator"); + aboutcframe.addWindowListener(new WindowListener() { + @Override + public void windowOpened(WindowEvent e) { + + } + + @Override + public void windowClosing(WindowEvent e) { + aboutcframe.dispose(); + } + + @Override + public void windowClosed(WindowEvent e) { + + } + + @Override + public void windowIconified(WindowEvent e) { + + } + + @Override + public void windowDeiconified(WindowEvent e) { + + } + + @Override + public void windowActivated(WindowEvent e) { + + } + + @Override + public void windowDeactivated(WindowEvent e) { + + } + }); + aboutcframe.setVisible(true); + break; + case "About the project": + Frame aboutpframe = new Frame(); + aboutpframe.setSize(450, 225); + aboutpframe.setResizable(false); + aboutpframe.setLocationRelativeTo(parent); + aboutpframe.setLayout(new GridLayout(4, 1)); + aboutpframe.add(new Label("Project by ZCW-Java91. (https://www.github.com/ZCW-Java91/TextEditor-Java)")); + aboutpframe.add(new Label("Remake by E-xml (https://www.github.com/E-xml/TextEditor-Java)")); + aboutpframe.add(new Label("Notepad V1.0.0")); + aboutpframe.add(new Label("JDK 21 needed for work on this code")); + aboutpframe.setTitle("About the project"); + aboutpframe.addWindowListener(new WindowListener() { + @Override + public void windowOpened(WindowEvent e) { + + } + + @Override + public void windowClosing(WindowEvent e) { + aboutpframe.dispose(); + } + + @Override + public void windowClosed(WindowEvent e) { + + } + + @Override + public void windowIconified(WindowEvent e) { + + } + + @Override + public void windowDeiconified(WindowEvent e) { + + } + + @Override + public void windowActivated(WindowEvent e) { + + } + + @Override + public void windowDeactivated(WindowEvent e) { + + } + }); + aboutpframe.setVisible(true); + break; + case "Report issues": + Frame report = new Frame(); + report.setSize(450, 225); + report.setResizable(false); + report.setLocationRelativeTo(parent); + report.setLayout(new GridLayout(4, 1)); + report.add(new Label("Issues detected ?")); + report.add(new Label("Original project : https://github.com/ZCW-Java91/TextEditor-Java/issues")); + report.add(new Label("Remake project : https://github.com/E-xml/TextEditor-Java/issues")); + report.setTitle("About the project"); + report.addWindowListener(new WindowListener() { + @Override + public void windowOpened(WindowEvent e) { + + } + + @Override + public void windowClosing(WindowEvent e) { + report.dispose(); + } + + @Override + public void windowClosed(WindowEvent e) { + + } + + @Override + public void windowIconified(WindowEvent e) { + + } + + @Override + public void windowDeiconified(WindowEvent e) { + + } + + @Override + public void windowActivated(WindowEvent e) { + + } + + @Override + public void windowDeactivated(WindowEvent e) { + + } + }); + report.setVisible(true); + break; + + default: + throw new IllegalArgumentException("You might have forget to update this block"); + } + } + } +} \ No newline at end of file diff --git a/src/CustomWindowListener.java b/src/CustomWindowListener.java new file mode 100644 index 0000000..d3d521c --- /dev/null +++ b/src/CustomWindowListener.java @@ -0,0 +1,55 @@ +package src; + +import javax.swing.*; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +public class CustomWindowListener implements WindowListener { + private ExmlEditor window = null; + + public CustomWindowListener(ExmlEditor window) { + this.window = window; + } + + public void windowOpened(WindowEvent e) { + + } + + public void windowClosing(WindowEvent e) { + boolean CancelPressed = false; + + if (!window.isFileSaved()) { + switch (JOptionPane.showOptionDialog(window, "The current file isn't saved, would save it ?", "Save ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null)) { + case JOptionPane.YES_OPTION: window.SaveAs(); window.textArea.setText(""); window.OpenedFile = null; window.TextContent = ""; break; + case JOptionPane.NO_OPTION: window.textArea.setText(""); window.OpenedFile = null; window.TextContent = ""; break; + case JOptionPane.CANCEL_OPTION: CancelPressed = true; break; + } + } + + if (!CancelPressed) { + window.dispose(); + } else { + CancelPressed = false; + } + } + + public void windowClosed(WindowEvent e) { + + } + + public void windowIconified(WindowEvent e) { + + } + + public void windowDeiconified(WindowEvent e) { + + } + + public void windowActivated(WindowEvent e) { + + } + + public void windowDeactivated(WindowEvent e) { + + } +} diff --git a/src/ExmlEditor.java b/src/ExmlEditor.java new file mode 100644 index 0000000..0975854 --- /dev/null +++ b/src/ExmlEditor.java @@ -0,0 +1,357 @@ +package src; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.font.*; +import java.awt.print.*; +import java.io.*; +import java.net.*; +import java.text.*; +import java.time.Instant; +import java.util.*; + +public class ExmlEditor extends Frame { + File OpenedFile = null; + TextArea textArea = new TextArea(); + String TextContent = ""; + public Stack undoStack = new Stack<>(); + public Stack redoStack = new Stack<>(); + public String[] days = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; + public String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + public boolean wordWrap = false; + + public ExmlEditor() { + this.setTitle("Notepad - Untitled"); + this.setSize(800, 600); + this.setBackground(new Color(234, 234, 234)); + this.addWindowListener(new CustomWindowListener(this)); + textArea.addKeyListener(new CustomKeyListener(this)); + this.add(textArea); + this.setMenuBar(new CustomMenuBar(this)); + AppendText(); + this.setVisible(true); + } + + public boolean isFileSaved() { + if (OpenedFile == null) { + return textArea.getText().isEmpty(); + } else { + return textArea.getText().equals(TextContent); + } + } + + public void SaveAs() { + FileDialog fileDialog = new FileDialog(this, "Save", FileDialog.SAVE); + fileDialog.setVisible(true); + if (!(fileDialog.getDirectory() == null || fileDialog.getFile() == null)) { + OpenedFile = new File(fileDialog.getDirectory()+ "\\" + fileDialog.getFile()); + this.setTitle("Notepad - " + OpenedFile.getName()); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(OpenedFile)); + writer.write(textArea.getText()); + writer.close(); + TextContent = textArea.getText(); + } catch (IOException e) { + e.fillInStackTrace(); + } + } + } + + public void Save() { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(OpenedFile)); + writer.write(textArea.getText()); + writer.close(); + TextContent = textArea.getText(); + this.setTitle("Notepad - " + OpenedFile.getName()); + } catch (IOException e) { + e.fillInStackTrace(); + } + } + + public void Open() { + FileDialog fileDialog = new FileDialog(this, "Open", FileDialog.LOAD); + fileDialog.setVisible(true); + if (!(fileDialog.getDirectory() == null || fileDialog.getFile() == null)) { + OpenedFile = new File(fileDialog.getDirectory() + "\\" + fileDialog.getFile()); + this.setTitle("Notepad - " + OpenedFile.getName()); + try { + StringBuilder text = new StringBuilder(); + BufferedReader reader = new BufferedReader(new FileReader(OpenedFile)); + String line = reader.readLine(); + while (line != null) { + text.append(line).append("\n"); + line = reader.readLine(); + } + + reader.close(); + if (!text.toString().isEmpty()) { + textArea.setText(text.substring(0, text.toString().length() - 1)); + } + TextContent = textArea.getText(); + } catch (IOException e) { + e.fillInStackTrace(); + } + } + } + + public String getTextContent() { + return TextContent; + } + + public File getOpenedFile() { + return OpenedFile; + } + + public void print() { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(new Printable() { + @Override + public int print(Graphics g, PageFormat pf, int page) { + if (page > 0) { + return NO_SUCH_PAGE; + } + + Graphics2D g2d = (Graphics2D) g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + + String text = TextContent; + Font font = new Font("Serif", Font.PLAIN, 12); + g2d.setFont(font); + + AttributedString attributedText = new AttributedString(text); + attributedText.addAttribute(TextAttribute.FONT, font); + AttributedCharacterIterator iterator = attributedText.getIterator(); + + int y = 0; + int lineHeight = g2d.getFontMetrics().getHeight(); + LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, g2d.getFontRenderContext()); + + float wrappingWidth = (float) pf.getImageableWidth(); + + while (measurer.getPosition() < iterator.getEndIndex()) { + TextLayout layout = measurer.nextLayout(wrappingWidth); + y += (int) layout.getAscent(); + layout.draw(g2d, 0, y); + y += (int) (layout.getDescent() + layout.getLeading()); + } + + return PAGE_EXISTS; + } + }); + + boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException e) { + e.fillInStackTrace(); + } + } + } + + public void AppendText() { + undoStack.push(textArea.getText()); + redoStack.clear(); + } + + public void Undo() { + if (!undoStack.isEmpty()) { + redoStack.push(textArea.getText()); + textArea.setText(undoStack.pop()); + } + } + + public void Redo() { + if (!redoStack.isEmpty()) { + undoStack.push(textArea.getText()); + textArea.setText(redoStack.pop()); + } + } + + public void Copy() { + if (!textArea.getSelectedText().isEmpty()) { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(textArea.getSelectedText()), null); + } else { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(textArea.getText()), null); + } + } + + public void Cut() { + if (!textArea.getSelectedText().isEmpty()) { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(textArea.getSelectedText()), null); + textArea.setText(textArea.getText().substring(0, textArea.getSelectionStart()) + textArea.getText().substring(textArea.getSelectionEnd())); + } else { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(textArea.getText()), null); + textArea.setText(""); + } + AppendText(); + } + + public void Paste() { + try { + textArea.insert((String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor), textArea.getCaretPosition()); + AppendText(); + } catch (UnsupportedFlavorException | IOException e) { + e.fillInStackTrace(); + } + + } + + public void Delete() { + AppendText(); + if (!textArea.getSelectedText().isEmpty()) { + textArea.setText(textArea.getText().substring(0, textArea.getSelectionStart()) + textArea.getText().substring(textArea.getSelectionEnd())); + } else { + textArea.setText(""); + } + } + + public void Insert(String text) { + int pos = textArea.getCaretPosition(); + textArea.insert(text, pos); + AppendText(); + textArea.setCaretPosition(pos); + } + + public String getKey(String key) { + switch (key) { + case "File name": + try { + return OpenedFile.getName(); + } catch (Exception e) { + return "Unavailable"; + } + case "File size": + return String.valueOf(textArea.getText().getBytes().length); + case "File path": + try { + return OpenedFile.getAbsolutePath(); + } catch (Exception e) { + return "Unavailable"; + } + case "Epoch": + return String.valueOf(Instant.now().getEpochSecond()); + case "Time stamp": + return String.valueOf(Instant.now()).replace('T', ' ').replace('Z', (char) 0); + case "Year": + return String.valueOf(new GregorianCalendar().get(GregorianCalendar.YEAR)); + case "Month": + return months[new GregorianCalendar().get(GregorianCalendar.MONTH)]; + case "Week": + return String.valueOf(new GregorianCalendar().get(GregorianCalendar.WEEK_OF_YEAR)); + case "Day": + return String.valueOf(new GregorianCalendar().get(GregorianCalendar.DAY_OF_MONTH)); + case "Day of the week": + return days[new GregorianCalendar().get(GregorianCalendar.DAY_OF_WEEK)] + ", " + new GregorianCalendar().get(GregorianCalendar.DAY_OF_MONTH); + case "Hour": + return String.valueOf(new GregorianCalendar().get(GregorianCalendar.HOUR_OF_DAY)); + case "Minute": + return String.valueOf(new GregorianCalendar().get(GregorianCalendar.MINUTE)); + case "Second": + return String.valueOf(new GregorianCalendar().get(GregorianCalendar.SECOND)); + case "Random char": + return String.valueOf((char) new Random().nextInt(0, 127)); + case "Username" : + return System.getenv("USERNAME"); + case "Ipv4": + try { + URL url = new URI("https://api.ipify.org").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + + in.close(); + + return response.toString(); + + } catch (Exception e) { + e.fillInStackTrace(); + } + + case "Ipv6": + try { + URL url = new URI("https://api6.ipify.org").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + + in.close(); + + return response.toString(); + + } catch (Exception e) { + e.fillInStackTrace(); + } + + } + return null; + } + + public void Replace(String oldSequence, String newSequence) { + textArea.setText(textArea.getText().replace(oldSequence, newSequence)); + } + + public void SelectAll() { + textArea.setSelectionStart(0); + textArea.setSelectionEnd(textArea.getText().length()); + } + + public void CopyLineUp() { + int start = textArea.getText().lastIndexOf("\n", textArea.getCaretPosition() - 1) + 1; + int end = textArea.getText().indexOf("\n", textArea.getCaretPosition()); + if (end == -1) end = textArea.getText().length(); + if (!textArea.getText().substring(start, end).isEmpty()) { + textArea.insert(textArea.getText().substring(start, end) + "\n", start); + } + } + + public void CopyLineDown() { + int start = textArea.getText().lastIndexOf("\n", textArea.getCaretPosition() - 1) + 1; + int end = textArea.getText().indexOf("\n", textArea.getCaretPosition()); + if (end == -1) end = textArea.getText().length(); + if (!textArea.getText().substring(start, end).isEmpty()) { + textArea.insert("\n" + textArea.getText().substring(start, end), end); + } + } + + public void DuplicateLine() { + int start = textArea.getText().lastIndexOf("\n", textArea.getCaretPosition() - 1) + 1; + int end = textArea.getText().indexOf("\n", textArea.getCaretPosition()); + if (end == -1) end = textArea.getText().length(); + if (!textArea.getText().substring(start, end).isEmpty()) { + textArea.insert("\n" + textArea.getText().substring(start, end), end); + } + } + + public void showTitleBar(boolean state) { + this.setUndecorated(!state); + } + + public void BGColor() { + textArea.setBackground(JColorChooser.showDialog(this, "Select a color", textArea.getBackground())); + } + + public void FGColor() { + textArea.setForeground(JColorChooser.showDialog(this, "Select a color", textArea.getForeground())); + } + + public static void main(String[] args) { + new ExmlEditor(); + } +} \ No newline at end of file