0

I have created new class which extends JTextArea and have implemented that class with FocusListener but the code inside the focusLost method is not getting executed. Whats the cause?

protected class JDynamicTextArea extends JTextArea implements FocusListener { 
    public JDynamicTextArea() { 
        super(); 
        addFocusListener(this); 
    } 
    public void focusGained(FocusEvent e) { } 
    public void focusLost(FocusEvent e) { 
        System.out.println("Focus lost"); 
    } 
}
StanislavL
  • 56,971
  • 9
  • 68
  • 98
eatSleepCode
  • 4,427
  • 7
  • 44
  • 93
  • Have you registered the class as a focus listener using addFocusListener? – MadProgrammer Mar 26 '13 at 09:16
  • yes, i have added focus listener inside the constructor. – eatSleepCode Mar 26 '13 at 09:17
  • I think you will need to provide example code then – MadProgrammer Mar 26 '13 at 09:17
  • protected class JDynamicTextArea extends JTextArea implements FocusListener { public JDynamicTextArea() { super(); addFocusListener(this); } public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { System.out.println("Focus lost"); } } – eatSleepCode Mar 26 '13 at 09:23
  • Do I need to implement keylistener as well? – eatSleepCode Mar 26 '13 at 09:38
  • Normally, I wouldn't immediately assume the AWT event thread was the issue, but based on [this recent question](http://stackoverflow.com/questions/15542410/focuslistener-on-editable-jcombobox-not-firing/15546211), I'm wondering if you are constructing your JDynamicTextArea in the AWT event thread (since Swing objects fail in mysterious ways if used in any other thread). – VGR Mar 26 '13 at 09:43
  • @MadProgrammer I was thinking that if I transfer focus on tab keypress. – eatSleepCode Mar 26 '13 at 09:52
  • @user2113996 `KeyListener` is NEVER a good choice for trying to transfer focus. You need to take advantage of the [focus transferal system](http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html) – MadProgrammer Mar 26 '13 at 10:03
  • typically, low-level listeners like focusListener are so hard to get correct that _not_ using them is the best option most of the time. So the real question is: what do you want to achieve? Chances are that you can do so by some higher level methods (f.i. by binding focus transfer keys, as @MadProgrammer suggested) – kleopatra Mar 26 '13 at 12:09
  • btw: JSomething are _not_ meant to be subclassed, but used as-are. As they already provide a feature to adding a listener, there's no need to subclass just to add a ... listener :-) – kleopatra Mar 26 '13 at 12:11
  • @kleopatra I need to store some data inside textarea while instantiating its object, I am creating it dynamically so need that information for further use. – eatSleepCode Mar 26 '13 at 13:42
  • still doesn't sound like a legitimate reason for subclassing - anyway, best to show a SSCCE that demonstrates what you are trying to achieve and where you are stuck. – kleopatra Mar 26 '13 at 13:44
  • @kleopatra Some values are associated with the JTextArea which are only available while instantiating that object. – eatSleepCode Apr 03 '13 at 12:23
  • as they can't fall fall from open sky, they most probably are available to the instantiating code as well - so still no reason for subclassing ;-) – kleopatra Apr 03 '13 at 12:55
  • it seems you didn't understand the problem. And it is very big code in my project so i cant' put a SSCCE, but i will try to put one. :) – eatSleepCode Apr 03 '13 at 13:39

1 Answers1

1

Seems to work just fine for me...

Click the second text field and you should see the focus lost event fire.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestFocus {

    public static void main(String[] args) {
        new TestFocus();
    }

    public TestFocus() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            add(new JScrollPane(new JDynamicTextArea()));
            add(new JTextField(10));
        }

    }

    protected class JDynamicTextArea extends JTextArea implements FocusListener {

        public JDynamicTextArea() {
            super(10, 10);
            addFocusListener(this);
        }

        public void focusGained(FocusEvent e) {
            System.out.println("Focus gained");
        }

        public void focusLost(FocusEvent e) {
            System.out.println("Focus lost");
        }

    }

}

Updated with key focus transfer

To reenable keyboard transfer focus, you need to add the following to the constructor

Set<KeyStroke> strokes = new HashSet<KeyStroke>(Arrays.asList(KeyStroke.getKeyStroke("pressed TAB")));
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, strokes);
strokes = new HashSet<KeyStroke>(Arrays.asList(KeyStroke.getKeyStroke("shift pressed TAB")));
setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, strokes);
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 3
    ehhh ... me telling the newbie to _not_ subclass and you old hand doing it _twice_ for no viable reason at all :-( – kleopatra Mar 26 '13 at 12:12
  • @kleopatra Sorry Kleo, I'm not, I'm trying to demonstrate that there code works with a running example in some small attempt to find out what it is they are trying to achieve. I got the fact that they want to reinstate the transfer focus keys out of the OP – MadProgrammer Mar 26 '13 at 19:54
  • @kleopatra Now you've told me I the past I shouldn't use setPreferredSize, so the only way to provide suitable sizing hints is to override getPreferredSize ... Now, if I follow your suggestions, I can't possible ever create anything in Swing ;) - Seriously, I understand and support your point – MadProgrammer Mar 26 '13 at 21:11