Coders Packet

Text Editor using Swing

By Srinjoy Ghosh

A simple text editor with features such as multi-tabbed editing, changing fonts, sizes and colors of text; cut, copy and paste options and more

This Java project is a desktop application that can serve as a simple text editor. The editor will be able to create, open, edit and save any text file and provide several features that can enable ease of typing, such as different fonts, cut-copy-paste and undo-redo functions, multiple tabs, keyboard shortcuts and a dark mode.

The "ui" class is the main class and contains the main() method. It is responible for creating the user interface of the application. The user interface of this application consists of a title, a menu bar, and a tabbed pane. They all have been created using Swing in Java. The menu bar has several menus, namely, "File", "View", "Edit" and "Format", and each come with their corresponding functions. Each menu has their own classes whose instances are present in the "ui" class.

 

                                                       

public class ui implements ActionListener {
    //initializing components for the entire window
    JFrame window;      //the main window
    JTabbedPane tabbedPane;     //tabbed pane for navigation
    JMenuBar mb;        //the menu bar containing the menus
    JMenu fileMenu, viewMenu, editMenu, formatMenu;     //menus on the menu bar

    //items in the "File" menu
    JMenuItem newItem, openItem, saveItem, saveasItem, closeItem;

    //items in the "View" menu
    JMenuItem wordwrapItem;
    JMenu themeMenu;
    JMenuItem lightItem, darkItem;

    //items in the "Edit" menu
    JMenuItem cutItem, copyItem, pasteItem, undoItem, redoItem;

    //items in the "Format" menu
    JMenuItem fontItem, sizeItem, colorItem;

    //items for the tab removal menu
    JPopupMenu popup;
    JMenuItem removeItem;

    //creating the objects for the menu classes
    FileMenuClass file=new FileMenuClass(this);
    ViewMenuClass view=new ViewMenuClass(this);
    EditMenuClass edit=new EditMenuClass(this);
    FormatMenuClass format=new FormatMenuClass(this);

    //the keyhandler object
    keyhandler kHandler=new keyhandler(this);

 

The "New" item on the "File" menu creates a new file and adds it to the tabbed pane as a "sample" object. "sample" is a class that extends JPanel and holds a JTextArea with a scrollpane. It also consists of an UndoManager and two string variables, that hold the file name and file address of the document whose text will be edited. The "ui" class creates an instance of "sample" through it's createComponent() method.

//creating the sample component to write on
    public sample createComponent() {
        sample tab=new sample();
        tab.textArea.addKeyListener(kHandler);
        tab.makeUndosAvailable();
        tab.makeScrollPane();
        tab.wrapUp();
        return tab;
    }

 

 

The "New" JMenuItem has an action listener added to it, and on click, it launches the "newFile()" method of the FileMenuClass object. This method adds a new tab to "ui"'s JTabbedPane object "tabbedPane" with a new instance of "sample" and titled "New File".

//creating the "New" function
    public void newFile() {
        ui.tabbedPane.addTab("New File", ui.createComponent());
    }

 

 

The "Open" JMenuItem also has an action listener to it, to launch the openFile() method of the FileMenuClass object. This methods launches a FileDialog(from java.awt.FileDialog) in "LOAD" mode to choose and select a file to edit. A tab is added to the tabbed pane and in it the selected file is loaded. If no file is selected, ie, the operation is cancelled, it prints a line in the execution prompt. It is to be noted that only text files can be imported to the application in this way.

                   

//from ui object
file.openFile(createComponent());

//from FileMenuClass object
public void openFile(sample tab){
        FileDialog fileDialog=new FileDialog(ui.window,"Open",FileDialog.LOAD);
        fileDialog.setVisible(true);
        if (fileDialog.getFile()!=null) {
            ui.tabbedPane.addTab(fileDialog.getFile(), tab);
            tab.filename=fileDialog.getFile();
            tab.fileaddress=fileDialog.getDirectory();

            try {
                BufferedReader br= new BufferedReader(new FileReader(tab.fileaddress+tab.filename));
                tab.textArea.setText("");
                String line=null;
                while ((line = br.readLine())!=null) {
                    tab.textArea.append(line+"\n");
                }
                br.close();
            } catch (Exception e) {
                //TODO: handle exception
                System.out.println("IO probs");
            }
        }
        else {
            System.out.println("No File Opened");
        }
    }

 

 

 

The action listener associated with the "Save" JMenuItem launches the saveFile() method of the FileMenuClass object. This method takes as paramter the tab that is selected presently and saves the file, if the file is already present. If the file is not present in the computer, it then proceeds to the saveFileAs() method of the FileMenuClass object.

//creating the "Save" function
    public void saveFile(sample tab) {
        if(tab.filename==null)
        {
            saveFileAs(tab);
        }
        else
        {
            try {
                FileWriter fw=new FileWriter(tab.fileaddress+tab.filename);
                fw.write(tab.textArea.getText());
                fw.close();
            } catch (Exception e) {
                //TODO: handle exception
                System.out.println("IO probs");
            }
        }
    }

 

 

The saveFileAs() method takes as input the present tab and saves the text in that tab into a new file. Another FileDialog() is opened, this time in "SAVE" mode. The name of the file is entered, the location is chosen and on click of the "Save" button, the file is created and saved.

//creating the "Save As" function
    public void saveFileAs(sample tab) {
        FileDialog fileDialog=new FileDialog(ui.window,"Save As",FileDialog.SAVE);
        fileDialog.setVisible(true);
        if (fileDialog.getFile()!=null) {
            tab.filename=fileDialog.getFile();
            tab.fileaddress=fileDialog.getDirectory();
        
        try {
            FileWriter fw=new FileWriter(tab.fileaddress+tab.filename);
            fw.write(tab.textArea.getText());
            ui.tabbedPane.setTitleAt(ui.tabbedPane.getSelectedIndex(), tab.filename);
            fw.close();
        } catch (Exception e) {
            //TODO: handle exception
            System.out.println("File Error");
        }
    }
    else
    {
        System.out.println("No file name entered");
    }
    }

 

 

The "Close All Tabs" menu item calls the close() function of the FileMenuClass object to close all tabs open in the application.

The "Word Wrap" item on the "View" menu toggles the value of the "WRAP" boolean variable of the sample object. If the variable is true, the text in the textArea of the present tab is wrapped to fit the size of the window in which it is opened. If it is false, this feature is disabled.

From ViewMenuClass:
//wordwrap function
    public void wordwrap(sample tab) {
        if (tab.WRAP==true) {
            tab.WRAP=false;
            tab.wrapUp();
        } else {
            tab.WRAP=true;
            tab.wrapUp();
        }
    }

From sample class:
public void wrapUp() {
        if (WRAP==true) {
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
        } else {
            textArea.setLineWrap(false);
            textArea.setWrapStyleWord(false);
        }
    }

 

 

The "Theme" menu item sets the background of the file as white or dark grey, on click of the "Light" and "Dark" menu items, respectively.

     

//light theme enabling function
    public void enable_light_theme(sample tab) {
        tab.textArea.setBackground(Color.WHITE);
        if (tab.textArea.getForeground()==Color.ORANGE) {
            tab.textArea.setForeground(Color.BLACK);
        }
    }

    //dark theme enabling function
    public void enable_dark_theme(sample tab) {
        tab.textArea.setBackground(Color.DARK_GRAY);
        if (tab.textArea.getForeground()==Color.BLACK) {
            tab.textArea.setForeground(Color.ORANGE);   
        }
    }

 

The Edit menu consists of the Cut, Copy, Paste, Undo and Redo items. They are responsible for providing the obvious functionalities to enable ease of typing. The cut, copy and paste functions are implemented through the DefaultEditorKit and the undo and redo functions are implemented by an UndoManager object built into the "sample" object which serves as the typing component of the tabs.

//creating the edit menu
    public void createEditMenu() {
        //creating the menu items
        cutItem=new JMenuItem(new DefaultEditorKit.CutAction());
        cutItem.setText("Cut(Ctrl+X)");

        copyItem=new JMenuItem(new DefaultEditorKit.CopyAction());
        copyItem.setText("Copy(Ctrl+C)");

        pasteItem=new JMenuItem(new DefaultEditorKit.PasteAction());
        pasteItem.setText("Paste(Ctrl+V)");

        undoItem=new JMenuItem("Undo(Ctrl+Z)");
        undoItem.addActionListener(this);
        undoItem.setActionCommand("undo");

        redoItem=new JMenuItem("Redo(Ctrl+Y)");
        redoItem.addActionListener(this);
        redoItem.setActionCommand("redo");

        //adding the items to the menu
        editMenu.add(cutItem);
        editMenu.add(copyItem);
        editMenu.add(pasteItem);
        editMenu.add(undoItem);
        editMenu.add(redoItem);
    }

 

 

The Font menu provides the options to select the preferred font, size and color of the text in the selected tab. On click of the "Font" button, the selectFont() method of the FormatMenuClass object is launched, which launches a JOptionPane message dialog box containing a combo box that will show all the fonts present in java for the user's system. Selecting a font and pressing "Ok" will apply the font to the text area of the selected tab only. The "Size" menu item on click launches another JOptionPane message dialog box that displays a JSpinner to select a number between 8 and 40. Selecting a number will apply that size to the entire text in the selected tab. The "Color" item displays on click a JColorChooser, to select a color that will be applied to the entire text in the selected tab.

         

               

     

 

 

If a left click on the mouse occurs over the title of a tab it displays a JPopupMenu with only one item that says "Close Tab". On click, it closes the presently selected tab without warning.

//code for removing tab
if (SwingUtilities.isRightMouseButton(e) && tabbedPane.getUI().tabForCoordinate(tabbedPane, e.getX(), e.getY())!=-1) {
                    popup=new JPopupMenu();
                    removeItem=new JMenuItem("Close Tab(Ctrl+W)");
                    removeItem.addActionListener(new java.awt.event.ActionListener() {
    
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            // TODO Auto-generated method stub
                            tabbedPane.remove(tabbedPane.getSelectedIndex());
                        }
                        
                    });
                    popup.add(removeItem);
                    popup.show(window, e.getX(), e.getY()+60);   
                }
            }

 

 

 

Finally there is a key handler class that is added to each text area as a key listener to enable well known keyboard shortcuts to certain functionalities.

public class keyhandler implements KeyListener {

    ui ui;

    public keyhandler(ui ui) {
        this.ui=ui;
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_S) {
            ui.file.saveFile((sample) ui.tabbedPane.getComponentAt(ui.tabbedPane.getSelectedIndex()));
        }
        if (e.isControlDown() && e.isShiftDown() && e.getKeyCode()==KeyEvent.VK_S) {
            ui.file.saveFileAs((sample) ui.tabbedPane.getComponentAt(ui.tabbedPane.getSelectedIndex()));
        }
        if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_Z) {
            ui.edit.undo((sample) ui.tabbedPane.getComponentAt(ui.tabbedPane.getSelectedIndex()));
        }
        if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_Y) {
            ui.edit.redo((sample) ui.tabbedPane.getComponentAt(ui.tabbedPane.getSelectedIndex()));
        }
        if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_W) {
            ui.tabbedPane.remove(ui.tabbedPane.getSelectedIndex());
        }
        if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_N) {
            ui.file.newFile();            
        }
        if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_O) {
            ui.file.openFile(ui.createComponent());
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }
    
}

 

 

 

Download project

Reviews Report

Submitted by Srinjoy Ghosh (srinjoyghosh731)

Download packets of source code on Coders Packet