JDK-4124119 : lightweight component lost the focus after draging the frame by mouse
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.6,1.2.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_2.5.1
  • CPU: generic,sparc
  • Submitted: 1998-03-31
  • Updated: 1999-02-03
  • Resolved: 1999-02-03
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.2 1.2.2Fixed
Related Reports
Duplicate :  
Relates :  
Description
lightweight component lost the focus after draging the frame by mouse

mike.colburn@East 1999-01-25
Test: java Main. When the Frame comes up click in the text field to give it
focus. Move the frame using the mouse. Make sure the text field still has
focus (blinking cursor should still be visible).

import java.awt.event.*;

class Main extends Frame implements ActionListener {
    Main() {
        super("Focus Test");
        String sLabel = "Lightweight component below (text field)";	
   	Label TFL = new Label(sLabel, Label.LEFT);
   	add(TFL, BorderLayout.NORTH);
        SimpleTextField canvas = new SimpleTextField(30, 5);
        add(canvas, BorderLayout.CENTER); 
        canvas.addActionListener(this);
        setSize(new Dimension(300,125));               
        setVisible(true);
        requestFocus();
        
    }
    public void actionPerformed(ActionEvent evt) {
        System.out.println(evt);
    }
    static public void main(String[] args) {
        new Main();
    }
}

class SimpleTextField extends Component implements Runnable {
    int border;
    int length;
    Font font;
    FontMetrics fontM;
    char[] buffer;
    int bufferIx;

    boolean hasFocus;
    boolean cursorOn;

    SimpleTextField(int len, int bor) {
        super();
        border = bor;
        length = len;
        buffer = new char[len];
        font = getFont();
        if (font == null) {
            font = new Font("Dialog", Font.PLAIN, 20);
        }
        fontM = getFontMetrics(font);

        // Listen for key and mouse events.
        this.addMouseListener(new MouseEventHandler());
        this.addFocusListener(new FocusEventHandler());
        this.addKeyListener(new KeyEventHandler());

        // Set text cursor.
        setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));

        // Start the thread that blinks the cursor.
        (new Thread(this)).start();
    }

    public Dimension getMinimumSize() {
        // The minimum height depends on the point size.
        int w = fontM.charWidth('m') * length;
        return new Dimension(w + 2*border, fontM.getHeight() + 2*border);
    }
    public Dimension getPreferredSize() {
        return getMinimumSize();
    }
    public Dimension getMaximumSize() {
        return new Dimension(Short.MAX_VALUE, getPreferredSize().height);
    }

    public boolean isFocusTraversable() {
        return true;
    }

    public void paint(Graphics g) {
        int y = (getSize().height-fontM.getHeight())/2;

        // Clear the background using the text background color.
        g.setColor(SystemColor.text);
        g.fillRect(0, 0, getSize().width, getSize().height);

        g.setFont(font);
        g.setColor(SystemColor.textText);
        g.drawChars(buffer, 0, bufferIx, border, y + fontM.getAscent());

        // Draw blinking cursor.
        int x = fontM.charsWidth(buffer, 0, bufferIx) + border;
        int w = fontM.charWidth('c');
        if (hasFocus) {
            g.setColor(getForeground());
            g.fillRect(x, y, w, fontM.getHeight());
            if (cursorOn) {
                if (bufferIx < buffer.length) {
                    g.setColor(SystemColor.text);
                    g.fillRect(x+2, y+2, w-4, fontM.getHeight()-4);
                }
            }
        }
    }

    // Event handlers
    class MouseEventHandler extends MouseAdapter {
        public void mousePressed(MouseEvent evt) {
            requestFocus();
        }
    }
    class FocusEventHandler extends FocusAdapter {
        public void focusGained(FocusEvent evt) {
            hasFocus = true;
            repaint();
        }
        public void focusLost(FocusEvent evt) {
            hasFocus = false;
            repaint();
        }
    }
    class KeyEventHandler extends KeyAdapter {
        public void keyPressed(KeyEvent evt) {
            switch (evt.getKeyCode()) {
              case KeyEvent.VK_DELETE:
              case KeyEvent.VK_BACK_SPACE:
                if (bufferIx > 0) {
                    bufferIx--;
                    repaint();
                }
                break;
              case KeyEvent.VK_ENTER:
                ActionEvent action = 
                    new ActionEvent(SimpleTextField.this,
                                    ActionEvent.ACTION_PERFORMED,
                                    String.valueOf(buffer, 0, bufferIx));
                // Send contents of buffer to listeners
                processEvent(action);
                break;
              default:
                repaint();
            }
        }
        public void keyTyped(KeyEvent evt) {
            if (bufferIx < buffer.length 
                    && !evt.isActionKey() 
                    && !Character.isISOControl(evt.getKeyChar())) {
                buffer[bufferIx++] = evt.getKeyChar();
            }
        }
    }

    // Support for Action Listener.
    ActionListener actionListener;

    public void addActionListener(ActionListener l) {
        actionListener = AWTEventMulticaster.add(actionListener, l);
    }

    // Override processEvent() to deal with ActionEvent.
    protected void processEvent(AWTEvent evt) {
        if (evt instanceof ActionEvent) {
            processActionEvent((ActionEvent)evt);     
        } else {
            super.processEvent(evt);
        }
    }

    // Supply method to process Action event.
    protected void processActionEvent(ActionEvent evt) {
        if (actionListener != null) {
            actionListener.actionPerformed(evt);
        }
    }
    
    public void run() {
        while (true) {
            try {
                // If component has focus, blink the cursor every 1/2 second.
                Thread.sleep(500);
                cursorOn = !cursorOn;
                if (hasFocus) {
                    repaint();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}


Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.2.2 FIXED IN: 1.2.2 INTEGRATED IN: 1.2.2
14-06-2004

SUGGESTED FIX ------- canvas.c ------- 519,530c519,527 < } else if (QLength(awt_display) > 0) { < /* If there are more events in the queue, look ahead for any focus < * events caused by a grab (i.e. a menu invocation) - if they exist, < * then this focus-out event is temporary. < */ < XEvent nevent; < < XPeekEvent(awt_display, &nevent); < if ((nevent.type == FocusOut || nevent.type == FocusIn) && < nevent.xfocus.mode == NotifyGrab) { < temp = TRUE; < } --- > } else { > /* If the event is sent by client or it is caused by a grab > * (i.e. a menu invocation), then this focus-out event is > * temporary. > */ > if (fevent->send_event || > (fevent->mode == NotifyGrab || > fevent->mode == NotifyWhileGrabbed)) > temp = TRUE; jenny.wang@East 1998-12-21
21-12-1998

EVALUATION Tested against 1.1.7A (released update), and 1.2fcs-O on Solaris. Occurs only with 1.2. Does not occur using the same builds on WindowsNT. david.mendenhall@eng 1998-10-23 eric.hawkes@eng 1998-10-23 The bug occurs also in 1.1.8. xianfa.deng@Eng 1998-11-27
23-10-1998