Search code examples
javaswingawtjlabeljtextfield

JLabel - On Mouse Entered change to JTextField


I have a JLabel with some text and I would like as soon as the mouse is entered on it, a JTextField to be appeared on the place of the text so that the user can enter some text. If the mouse is not on it, it just displays its text as normal. I use:

JLabel jl = new JLabel("Enter mouse to make a search!")
jl.addMouseListener(new MouseAdapter()
{
     public void mouseEntered(MouseEvent evt)
     {
         JTextField textField = new JTextField(20);
         //????
     }

     public void mouseExited(MouseEvent evt)
     {
                 jl.setText("Enter mouse to make a search!");
     }
});

However, I am having some troubles on how to replace the jlabel with a jtextfield. How could I do that?


Solution

  • Use a JPanel that uses a CardLayout to hold both the JLabel and the JTextField, and then swap them using the CardLayout's show(...) method, when desired. Don't forget to transfer the text from the JTextField to the JLabel in the mouseExited method.

    For example:

    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    class SwapPanel extends JPanel {
        private static final int COLUMNS = 20;
        public static final String LABEL = "label";
        public static final String TEXT_FIELD = "text field";
        private JLabel label = new JLabel();
        private JTextField textField = new JTextField(COLUMNS);
        private CardLayout cardLayout = new CardLayout();
    
        public SwapPanel() {
            setLayout(cardLayout);
            add(label, LABEL);
            add(textField, TEXT_FIELD);
    
            MyMouse myMouse = new MyMouse();
    
            label.addMouseListener(myMouse);
            textField.addMouseListener(myMouse);
        }
    
        private class MyMouse extends MouseAdapter {
            @Override
            public void mouseEntered(MouseEvent e) {
                cardLayout.show(SwapPanel.this, TEXT_FIELD);
            }
    
            @Override
            public void mouseExited(MouseEvent e) {
                label.setText(textField.getText());
                cardLayout.show(SwapPanel.this, LABEL);
            }
        }
    }
    

    import javax.swing.*;
    
    public class TestSwapPanel extends JPanel {
        private static final int GAP = 20;
        private SwapPanel swapPanel = new SwapPanel();
    
        public TestSwapPanel() {
            setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
            add(swapPanel);
        }
    
        private static void createAndShowGui() {
            TestSwapPanel mainPanel = new TestSwapPanel();
    
            JFrame frame = new JFrame("Swap Components");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGui();
                }
            });
        }
    }
    

    Or if you want to swap back to JLabel on pressing enter, and having the JTextField focused and all text selected on swapping:

    import java.awt.CardLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    class SwapPanel2 extends JPanel {
        private static final long serialVersionUID = 1L;
        private static final int COLUMNS = 20;
        public static final String LABEL = "label";
        public static final String TEXT_FIELD = "text field";
        private JLabel label = new JLabel();
        private JTextField textField = new JTextField(COLUMNS);
        private CardLayout cardLayout = new CardLayout();
    
        public SwapPanel2() {
            setLayout(cardLayout);
            add(label, LABEL);
            add(textField, TEXT_FIELD);
    
            MyMouse myMouse = new MyMouse();
    
            label.addMouseListener(myMouse);
            textField.addMouseListener(myMouse);
            textField.addActionListener(myMouse);
        }
    
        public void showLabel() {
            label.setText(textField.getText());
            cardLayout.show(SwapPanel2.this, LABEL);
        }
    
        public void showTextField() {
            textField.selectAll();
            cardLayout.show(SwapPanel2.this, TEXT_FIELD);
            textField.requestFocusInWindow();
        }
    
        private class MyMouse extends MouseAdapter implements ActionListener {
            @Override
            public void mouseEntered(MouseEvent e) {
                showTextField();
            }
    
            @Override
            public void mouseExited(MouseEvent e) {
                showLabel();
            }
    
            @Override
            public void actionPerformed(ActionEvent arg0) {
                showLabel();
            }
        }
    }