Filtering JList Component Models

Filter items in a long list are often accomplished using the JTextField component. As the user inputs into the JTextField component, the set of items shown in the list is narrowed to just those things that correspond to the input received from the user.

It is necessary to utilize two elements to implement this function of the JList component, one of which is a model that filters a set of elements based on some text. The other executes the filter method when the user enters text.

Implementing the input field is a simpler job, so let’s start with it in our review of the implementation process. The JTextField component model is a document used with a Swing set of components. It is necessary to implement the DocumentListener interface in the model in order to monitor input to a Document. Text input, updating, and deletion are tracked using three methods defined below:

  • public void insertUpdate (DocumentEvent event)
  • public void changedUpdate (DocumentEvent event)
  • public void removeUpdate (DocumentEvent event)

When the model attributes are updated, the changedUpdate() method is used to update the model. It is possible that it will not be realized. In order to avoid duplicating filtering actions across all three methods, the generic method generated in the custom model is simply called by the other two. A detailed explanation of the JTextField component, which is used for filtering in the JList component, may be found in the following section:

JTextField input = new JTextField(); 
String lastSearch = ""; 

DocumentListener listener = new DocumentListener() { 
    public void insertUpdate(DocumentEvent event) { 
        Document doc = event.getDocument(); 
        lastSearch = doc.getText(0, doc.getLength()); 
        ((FilteringModel)getModel()).filter(lastSearch); 
    } 

    public void removeUpdate(DocumentEvent event) { 
        Document doc = event.getDocument(); 
        lastSearch = doc.getText(0, doc.getLength()); 
        ((FilteringModel)getModel()).filter(lastSearch); 
    }

    public void changedUpdate(DocumentEvent event) {
    } 
}; 

input.getDocument().addDocumentListener(listener);

In order to avoid being restricted to just using the JTextField component that was generated using the JList, the installJTextField() method is used, which attaches the event listener to the component that was built using the JList in the first place. In addition, a mechanism is provided to eliminate this match. Through the usage of these methods, the user of a filtering JList may choose to use their own JTextField in place of the default one.

public void installJTextField(JTextField input) { 
    input.getDocument().addDocumentListener(listener); 
} 

public void unnstallJTextField(JTextField input) { 
    input.getDocument().removeDocumentListener(listener); 
}

After that, the filtering model is taken into consideration. This case implements the filter() function, which is invoked by methods that implement the DocumentListener interface, as seen below. To put this strategy into action, you’ll need to have two lists of objects on hand: a source list and a filtered list of items. Because you are inheriting from the AbstractListModel class, you must implement some of the methods listed below in your code:

  • Constructor
  • Method for adding items to the model is being implemented in this project.
  • getElementAt() is used to get an element.
  • getSize() is used to retrieve sizes.
  • The constructor produces two instances of the List objects. The type of objects that are stored as List elements does not matter. Therefore List objects are generated to carry items of the following types:
List<Object> list; 
List<Object> filteredList; 

public FilteringModel() { 
    list = new ArrayList<>(); 
    filteredList = new ArrayList<>(); 
}

Model elements are added by adding them to the original model and then filtering the resulting model with the previously added elements. Optimization of this approach may be achieved by using a method to filter a single element when it is added; however, in this implementation, the filter() function is invoked when an element is added, which is also used to filter the whole list. (It should be noted that the event implementation in the DocumentListener also invokes the filter() method.) As a result, even when only one item is added to the list, the whole list is filtered, with each item that matches the search parameters being added to the filtered list.

public void addElement(Object element) { 
    list.add(element); 
    filter(); 
}

The size of the returned model is the same as the size of the filtered list, but not the same as the original:

public int getSize() { 
    return filteredList.size(); 
}

Similar to the technique for obtaining the size of a model, the method for obtaining an item from a list returns elements from the filtered list rather than the original list. In order to avoid having to go through the complete list, it has been implemented as follows:

public Object getElementAt(int index) { 
    Object returnValue; 
    if (index < filteredList.size()) { 
        returnValue = filteredList.get(index); 
    } else { 
        returnValue = null;
    } 
    return returnValue; 
}

Finally, the filter() method is responsible for most of the work. Because you have no way of knowing whether the new search string will broaden or limit the set of items, the quickest and most straightforward solution is to remove the whole filtered list and replace it with items that fit your search criteria from the original list. A match may be discovered at the beginning of a line as well as at any point throughout it. An example of searching for the letter “A” is shown below. This function enables you to locate items in a string that begin with the capital letter “A” or contain the letter “A” at any point in the string.

void filter(String search) {
    filteredList.clear();
    for (Object element: list) {
        if (element.toString().contains(search)) {
            filteredList.add(element); 
        } 
    } 
    fireContentsChanged(this, 0, getSize()); 
}

It is important to note that the search in this approach is case-sensitive. You may alter the method to implement a case-insensitive search and start the search at the beginning of the string.

After you have added entries to the filtered list, you may also sort the results. This operation requires your familiarity with the model’s contents. The function toString() is currently used by search, which does not indicate that it may include elements of a suitable type that can also be sorted when it is performed.

Here is a full implementation of the JList filter element with an inner class ListModel, as seen in the accompanying code sample. This class implements the DocumentListener interface, which the text component uses to listen for new documents. Although the addition of this class may seem needless at first look, given that filtering is only done for this model, the specification of behavior in this implementation is the most accurate.

package org.kodejava.swing;

import javax.swing.AbstractListModel;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.util.ArrayList;
import java.util.List;

public class FilteringJList extends JList<Object> {
    private JTextField input;

    public FilteringJList() {
        setModel(new FilteringModel());
    }

    public void installJTextField(JTextField input) {
        if (input != null) {
            this.input = input;
            FilteringModel model = (FilteringModel) getModel();
            input.getDocument().addDocumentListener(model);
        }
    }

    public void uninstallJTextField(JTextField input) {
        if (input != null) {
            FilteringModel model = (FilteringModel) getModel();
            input.getDocument().removeDocumentListener(model);
            this.input = null;
        }
    }

    public void setModel(ListModel<Object> model) {
        if (!(model instanceof FilteringModel)) {
            throw new IllegalArgumentException();
        } else {
            super.setModel(model);
        }
    }

    public void addElement(Object element) {
        ((FilteringModel) getModel()).addElement(element);
    }

    private static class FilteringModel extends AbstractListModel<Object> implements DocumentListener {
        List<Object> list;
        List<Object> filteredList;
        String lastFilter = "";

        public FilteringModel() {
            list = new ArrayList<>();
            filteredList = new ArrayList<>();
        }

        public void addElement(Object element) {
            list.add(element);
            filter(lastFilter);
        }

        public int getSize() {
            return filteredList.size();
        }

        public Object getElementAt(int index) {
            Object returnValue;
            if (index < filteredList.size()) {
                returnValue = filteredList.get(index);
            } else {
                returnValue = null;
            }
            return returnValue;
        }

        void filter(String search) {
            filteredList.clear();
            for (Object element : list) {
                if (element.toString().contains(search)) {
                    filteredList.add(element);
                }
            }
            fireContentsChanged(this, 0, getSize());
        }

        public void insertUpdate(DocumentEvent event) {
            Document doc = event.getDocument();
            try {
                lastFilter = doc.getText(0, doc.getLength());
                filter(lastFilter);
            } catch (BadLocationException ble) {
                System.err.println("Bad location: " + ble);
            }
        }

        public void removeUpdate(DocumentEvent event) {
            Document doc = event.getDocument();
            try {
                lastFilter = doc.getText(0, doc.getLength());
                filter(lastFilter);
            } catch (BadLocationException ble) {
                System.err.println("Bad location: " + ble);
            }
        }

        public void changedUpdate(DocumentEvent event) {
        }
    }
}

It is now necessary to develop a test program. The following six lines will be crucial in the event. They build a JList component, attach it to the JScrollPane component, and then attach a text box to it as seen in the code:

FilteringJList list = new FilteringJList();
JScrollPane pane=new JScrollPane(list);
frame.add(pane,BorderLayout.CENTER);
JTextField text=new JTextField();list.installJTextField(text);
frame.add(text,BorderLayout.NORTH);

To the model, new components are introduced in the program’s primary body. The model shown below includes a list of Christmas gifts, the names of Santa’s reindeer, the names of London Underground lines, and the letters of the Greek alphabet.

package org.kodejava.swing;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.EventQueue;

public class JListFiltersDemo {
    public static void main(String[] args) {
        Runnable runner = () -> {
            JFrame frame = new JFrame("Filtering List");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            FilteringJList list = new FilteringJList();
            JScrollPane pane = new JScrollPane(list);
            frame.add(pane, BorderLayout.CENTER);
            JTextField text = new JTextField();
            list.installJTextField(text);
            frame.add(text, BorderLayout.NORTH);
            String[] elements = {
                    "Partridge in a pear tree", "Turtle Doves", "French Hens",
                    "Calling Birds", "Golden Rings", "Geese-a-laying",
                    "Swans-a-swimming", "Maids-a-milking", "Ladies dancing",
                    "Lords-a-leaping", "Pipers piping", "Drummers drumming",
                    "Dasher", "Dancer", "Prancer", "Vixen", "Comet", "Cupid",
                    "Donner", "Blitzen", "Rudolf", "Bakerloo", "Center",
                    "Circle", "District", "East London", "Hammersmith and City",
                    "Jubilee", "Metropolitan", "Northern", "Piccadilly Royal",
                    "Victoria", "Waterloo and City", "Alpha", "Beta", "Gamma",
                    "Delta", "Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa",
                    "Lambda", "Mu", "Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma",
                    "Tau", "Upsilon", "Phi", "Chi", "Psi", "Omega"};
            for (String element : elements) {
                list.addElement(element);
            }
            frame.setSize(500, 500);
            frame.setVisible(true);
        };
        EventQueue.invokeLater(runner);
    }
}
Filtering JList Component Models Demo

Filtering JList Component Models Demo

Because this filtering strategy is based on the JList component and its accompanying JTextField component, it will operate successfully if your list’s entries are appropriately displayed when you use the function toString(). Creating a Filter interface that is provided to the model when filtering operations are performed might be useful for doing more complicated filtering tasks.

In this example, the only item that is not addressed is the process of selection. By default, when the contents of the model list change, the JList does not update the selection of the model list. Filtering may be used to either retain the chosen item or emphasize the first item in the list, depending on the desired behavior.

Even though the original JList component does not explicitly offer the functionality, there are techniques to implement filtering. Overriding the getNextMatch() function allows you to alter the default behavior if you so want.

How do I create a simple mail client program in Swing?

The code snippet below show you how to create a simple Java Swing application that can be used to send an e-mail. The program allows user to supply the from email address, to email address, the subject and the message of the email. User need to select the available SMTP server to connect to and provide the username and password for authentication to the mail server.

Here is the user interface of this simple email client:

Simple E-mail Client

Simple E-mail Client

The main routine for sending the email is in the SendEmailActionListener class, which is an implementation of an ActionListener interface that will handle email sending process when Send E-mail button is pressed.

package org.kodejava.mail;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;

public class SendEmailClient extends JFrame {
    private final JTextField fromField = new JTextField();
    private final JTextField toField = new JTextField();
    private final JTextField subjectField = new JTextField();
    private final JComboBox<String> mailSmtpHostComboBox = new JComboBox<>();
    private final JTextField usernameField = new JTextField();
    private final JPasswordField passwordField = new JPasswordField();
    private final JTextArea contentTextArea = new JTextArea();

    private SendEmailClient() {
        InitializeUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SendEmailClient client = new SendEmailClient();
            client.setVisible(true);
        });
    }

    private void InitializeUI() {
        setTitle("Send E-mail Client");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(new Dimension(500, 500));

        getContentPane().setLayout(new BorderLayout());

        // Header Panel
        JPanel headerPanel = new JPanel();
        headerPanel.setLayout(new GridLayout(6, 2));
        headerPanel.add(new JLabel("From:"));
        headerPanel.add(fromField);

        headerPanel.add(new JLabel("To:"));
        headerPanel.add(toField);

        headerPanel.add(new JLabel("Subject:"));
        headerPanel.add(subjectField);

        headerPanel.add(new JLabel("SMTP Server:"));
        headerPanel.add(mailSmtpHostComboBox);
        mailSmtpHostComboBox.addItem("smtp.gmail.com");

        headerPanel.add(new JLabel("Username:"));
        headerPanel.add(usernameField);

        headerPanel.add(new JLabel("Password:"));
        headerPanel.add(passwordField);

        // Body Panel
        JPanel bodyPanel = new JPanel();
        bodyPanel.setLayout(new BorderLayout());
        bodyPanel.add(new JLabel("Message:"), BorderLayout.NORTH);
        bodyPanel.add(contentTextArea, BorderLayout.CENTER);

        JPanel footerPanel = new JPanel();
        footerPanel.setLayout(new BorderLayout());
        JButton sendMailButton = new JButton("Send E-mail");
        sendMailButton.addActionListener(new SendEmailActionListener());

        footerPanel.add(sendMailButton, BorderLayout.SOUTH);

        getContentPane().add(headerPanel, BorderLayout.NORTH);
        getContentPane().add(bodyPanel, BorderLayout.CENTER);
        getContentPane().add(footerPanel, BorderLayout.SOUTH);
    }

    private class SendEmailActionListener implements ActionListener {
        SendEmailActionListener() {
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Properties props = new Properties();
            props.put("mail.smtp.host", mailSmtpHostComboBox.getSelectedItem());
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.port", "465");
            props.put("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.ssl.protocols", "TLSv1.2");

            Session session = Session.getDefaultInstance(props);
            try {
                InternetAddress fromAddress = new InternetAddress(fromField.getText());
                InternetAddress toAddress = new InternetAddress(toField.getText());

                Message message = new MimeMessage(session);
                message.setFrom(fromAddress);
                message.setRecipient(Message.RecipientType.TO, toAddress);
                message.setSubject(subjectField.getText());
                message.setText(contentTextArea.getText());

                Transport.send(message, usernameField.getText(),
                        new String(passwordField.getPassword()));
            } catch (MessagingException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>javax.mail-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How to define JRadioButton label position?

In this code snippet you’ll see how to define JRadioButton label position. By default, the label will be displayed on the right side of the button. In the code below you will see some examples for placing the label on the left side, at the top and the bottom of the JRadioButton.

To define the label position we use the combination of the setHorizontalTextPosition() and setVerticalTextPosition() method and specified the position using one of the available constant in SwingConstants interface.

package org.kodejava.swing;

import javax.swing.*;

public class RadioButtonLabelPosition {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();

        // Create JRadioButton with label on the right
        JRadioButton button1 = new JRadioButton("Button One");
        button1.setHorizontalTextPosition(SwingConstants.RIGHT);

        // Create JRadioButton with label on the left
        JRadioButton button2 = new JRadioButton("Button Two");
        button2.setHorizontalTextPosition(SwingConstants.LEFT);

        // Create JRadioButton with label at the bottom centered.
        JRadioButton button3 = new JRadioButton("Button Three");
        button3.setVerticalTextPosition(SwingConstants.BOTTOM);
        button3.setHorizontalTextPosition(SwingConstants.CENTER);

        // Create JRadioButton with label at the top centered.
        JRadioButton button4 = new JRadioButton("Button Four");
        button4.setVerticalTextPosition(SwingConstants.TOP);
        button4.setHorizontalTextPosition(SwingConstants.CENTER);

        panel.add(button1);
        panel.add(button2);
        panel.add(button3);
        panel.add(button4);

        frame.add(panel);
        frame.setSize(500, 300);
        frame.setVisible(true);
    }
}

Here is a screen capture result of the code snippet above:

JRadioButton Label Position

How do I flash the window taskbar in Swing?

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class WindowTaskbarFlash extends JFrame {
    private WindowTaskbarFlash() throws HeadlessException {
        initUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                () -> new WindowTaskbarFlash().setVisible(true));
    }

    private void initUI() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        pack();
        setSize(200, 200);
        setState(Frame.ICONIFIED);

        // Demonstrate flashes the application window task bar
        // by calling the toFront method every 5 seconds.
        Timer timer = new Timer(5000, e -> toFront());
        timer.start();
    }
}

How do I change JFrame state programmatically?

In the following code snippet you’ll learn how to programmatically change the frame state of a JFrame component in a Swing application. The JFrame states are represented as a bitwise masks. You can minimize, maximize or make the JFrame state to normal, using the JFrame.setExtendedState() method.

You can pass the following values as the parameter to the method:

  • Frame.NORMAL
  • Frame.ICONIFIED
  • Frame.MAXIMIZED_HORIZ
  • Frame.MAXIMIZED_VERT
  • Frame.MAXIMIZED_BOTH
package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;

public class SwingFrameState extends JFrame {
    public SwingFrameState() throws HeadlessException {
        initUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                () -> new SwingFrameState().setVisible(true));
    }

    private void initUI() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());

        final JButton minimize = new JButton("Minimize");
        final JButton maximize = new JButton("Maximize");
        final JButton normal = new JButton("Normal");

        add(normal);
        add(minimize);
        add(maximize);

        pack();
        setSize(500, 200);

        ActionListener listener = e -> {
            if (e.getSource() == normal) {
                setExtendedState(Frame.NORMAL);
            } else if (e.getSource() == minimize) {
                setExtendedState(Frame.ICONIFIED);
            } else if (e.getSource() == maximize) {
                setExtendedState(Frame.MAXIMIZED_BOTH);
            }
        };

        minimize.addActionListener(listener);
        maximize.addActionListener(listener);
        normal.addActionListener(listener);
    }
}

The screenshot of the output from the code snippet above is:

Change JFrame State Programmatically

Change JFrame State Programmatically

How do I disable keyboard events in JTextArea?

The following example demonstrate how to disable some keys in JTextArea and JScrollPane using the InputMap. In the disableKeys() method below we disable the arrow keys including the UP, DOWN, LEFT and RIGHT.

Let’s see the code snippet below:

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class TextAreaDisableKeyDemo extends JFrame {
    public TextAreaDisableKeyDemo() {
        initialize();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                () -> new TextAreaDisableKeyDemo().setVisible(true));
    }

    private void initialize() {
        setSize(500, 200);
        setTitle("Disable Keys Demo");
        setLayout(new BorderLayout());
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JTextArea textArea = new JTextArea("Hello World!");
        JScrollPane scrollPane = new JScrollPane(textArea);
        disableKeys(textArea.getInputMap());
        disableKeys(scrollPane.getInputMap(
                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT));

        getContentPane().add(scrollPane, BorderLayout.CENTER);
    }

    private void disableKeys(InputMap inputMap) {
        String[] keys = {"UP", "DOWN", "LEFT", "RIGHT"};
        for (String key : keys) {
            inputMap.put(KeyStroke.getKeyStroke(key), "none");
        }
    }
}

The output of the code snippet above is:

Disable Keyboard Events in JTextArea

How do I create a single line JTextArea?

The following example will show you how to create a single line JTextArea. A single line means that you cannot insert a new line in the text area. When pressing the enter key it will be replaced by a space.

This can be done by putting a property called filterNewlines and set its value to Boolean.TRUE into the document model of the JTextArea.

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class SingleLineTextArea extends JFrame {
    private SingleLineTextArea() {
        initialize();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                () -> new SingleLineTextArea().setVisible(true));
    }

    private void initialize() {
        setSize(500, 200);
        setTitle("Single Line Text Area");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        final JTextArea textArea = new JTextArea();
        textArea.setLineWrap(true);

        // Filter a new line, pressing enter key will be replaced
        // with a space instead.
        textArea.getDocument().putProperty("filterNewlines",
                Boolean.TRUE);

        JScrollPane scrollPane = new JScrollPane(textArea);

        // Pressing the Save button print out the text area text
        // into the console.
        JButton button = new JButton("Save");
        button.addActionListener(e -> System.out.println(textArea.getText()));
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        getContentPane().add(button, BorderLayout.SOUTH);
    }
}

The screenshot of the result of the code snippet above is:

Single Line JTextArea Demo

How do I move focus from JTextArea using TAB key?

The default behavior when pressing the tabular key in a JTextArea is to insert a tab spaces in the text area. In this example you’ll see how to change this to make the tab key to transfer focus to other component forward or backward.

The main routine can be found in the key listener section. When the tab key is pressed we will tell the text area to transfer to focus into other component. Let’s see the code snippet below.

package org.kodejava.swing;

import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class TextAreaTabMoveFocus extends JFrame {
    public TextAreaTabMoveFocus() {
        initialize();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                () -> new TextAreaTabMoveFocus().setVisible(true));
    }

    private void initialize() {
        setSize(500, 200);
        setTitle("JTextArea TAB DEMO");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        JTextField textField = new JTextField();
        JPasswordField passwordField = new JPasswordField();
        final JTextArea textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea);

        // Add key listener to change the TAB behavior in
        // JTextArea to transfer focus to other component forward
        // or backward.
        textArea.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_TAB) {
                    if (e.getModifiersEx() > 0) {
                        textArea.transferFocusBackward();
                    } else {
                        textArea.transferFocus();
                    }
                    e.consume();
                }
            }
        });

        getContentPane().add(textField, BorderLayout.NORTH);
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        getContentPane().add(passwordField, BorderLayout.SOUTH);
    }
}

The output of the code snippet above is:

JTextArea Move Focus Using Tab

How do I read text file into JTextArea?

Using the read(Reader in, Object desc) method inherited from the JTextComponent allow us to populate a JTextArea with text content from a file. This example will show you how to do it.

In this example we use an InputStreamReader to read a file from our application resource. You could use other Reader implementation such as the FileReader to read the content of a file. Let’s see the code below.

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Objects;

public class PopulateTextAreaFromFile extends JPanel {
    public PopulateTextAreaFromFile() {
        initialize();
    }

    public static void showFrame() {
        JPanel panel = new PopulateTextAreaFromFile();
        panel.setOpaque(true);

        JFrame frame = new JFrame("Populate JTextArea from File");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(PopulateTextAreaFromFile::showFrame);
    }

    private void initialize() {
        JTextArea textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea);
        try {
            // Read some text from the resource file to display in
            // the JTextArea.
            textArea.read(new InputStreamReader(Objects.requireNonNull(
                    getClass().getResourceAsStream("/data.txt"))), null);
        } catch (IOException e) {
            e.printStackTrace();
        }

        this.setPreferredSize(new Dimension(500, 200));
        this.setLayout(new BorderLayout());
        this.add(scrollPane, BorderLayout.CENTER);
    }
}

The output of the code snippet above is:

Read Text File into JTextArea

How do I insert a text in a specified position in JTextArea?

The insert(String str, int pos) of the JTextArea allows us to insert a text at the specified position. In the example below we insert brown and over words into the current JTextArea text.

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class TextAreaInsertText extends JPanel {
    public TextAreaInsertText() {
        initializeUI();
    }

    public static void showFrame() {
        JPanel panel = new TextAreaInsertText();
        panel.setOpaque(true);

        JFrame frame = new JFrame("JTextArea Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TextAreaInsertText::showFrame);
    }

    private void initializeUI() {
        String text = "The quick fox jumps the lazy dog.";

        JTextArea textArea = new JTextArea(text);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JScrollPane scrollPane = new JScrollPane(textArea);

        textArea.insert("brown ", 10);
        textArea.insert("over ", 26);

        this.setPreferredSize(new Dimension(500, 200));
        this.setLayout(new BorderLayout());
        this.add(scrollPane, BorderLayout.CENTER);
    }
}

The screenshot of the result from the code snippet above is:

JTextArea Insert Text Demo