Search code examples
javaswingjbuttonjtextfieldmouselistener

Get a JTextFeild to go back to a transparent state


I am trying to get a JTextField to show over a JButton when I click the button. I have that working, but when I click out of the button it still stays visible. I'm using a MouseListener event so once I exit the button I want JTextField to become transparent again, but it stays visible.

My code:

import java.awt.EventQueue;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseEvent;


public class magicalJtextField extends JFrame implements MouseListener{

private JPanel contentPane;
private JTextField textField;


public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                magicalJtextField frame = new magicalJtextField();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}


public magicalJtextField() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);


    textField = new JTextField();
    textField.setBounds(78, 78, 89, 30);
    contentPane.add(textField);
    textField.setColumns(10);

    JButton button = new JButton("");
    //button transparent
//      button.setOpaque(false);
//      button.setContentAreaFilled(false);
//      button.setBorderPainted(false);
    button.setBounds(78, 78, 89, 23);
    button.addMouseListener(this);
    contentPane.add(button);

    textField.setVisible(false);

}
public void mouseEntered(MouseEvent e) 
{
//button.setText("Mouse Entered");
//button.setBackground(Color.CYAN);
//  textField.setVisible(true);
}

public void mouseExited(MouseEvent e) 
{
    textField.setVisible(false);    
}   
public void mouseClicked(MouseEvent e) 
{
    textField.setVisible(true);
}
public void mousePressed(MouseEvent e) 
{
    textField.setVisible(true);
}   
public void mouseReleased(MouseEvent e)
{
    textField.setVisible(true);
}
}

Solution

  • I suggest a CardLayout for the Jbutton-JTextField magic trick (edit: I actually saw the recommendations in the comments only after I posted because it was so obvious and on an answer). Pressing the button will switch the card and then exiting the text field area with the mouse will switch it again.

    enter image description here

    public class Example extends JPanel {
    
        public static void main(String[] args) {
    
            EventQueue.invokeLater(() -> {
                JFrame frame = new JFrame();
                frame.add(new Example());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            });
        }
    
        public Example() {
    
            CardLayout cards = new CardLayout(5, 5);
            JPanel panel = new JPanel(cards);
    
            JButton button = new JButton("");
            JTextField textField = new JTextField(10);
    
            button.addActionListener(e -> {
                cards.next(panel);
                textField.requestFocusInWindow();
            });
    
            textField.addMouseListener(new MouseAdapter() {
    
                @Override
                public void mouseExited(MouseEvent e) {
    
                    cards.next(panel);
                }
            });
    
            panel.add(button);
            panel.add(textField);
    
            add(panel);
        }
    }
    

    As you were told by Andrew Thompson, don't use null layouts and don't specify bounds. Use a proper layout manager to do this for you.