Search TextField Handling x

19 views
Skip to first unread message

gmu

unread,
Nov 13, 2009, 11:21:14 PM11/13/09
to Mac Widgets for Java
Can someone help me figure how to handle x that clears the text in
search tecxt. Iam handling key press but want to clear search results
when user presses x and clears the search string in the JTextField
(search variant)

TIA.

Ken Orr

unread,
Nov 14, 2009, 6:25:12 AM11/14/09
to Mac Widgets for Java
When the "X" button is pressed, text should automatically be cleared.
You're not seeing this?

Harald Kuhr

unread,
Nov 14, 2009, 7:50:53 AM11/14/09
to mac-widget...@googlegroups.com
Hi,

If you want a custom action bound to the clear/cancel button, you can
assign an Action(Listener) to the search field.

http://developer.apple.com/Mac/library/technotes/tn2007/tn2196.html#JTEXTFIELD_SEARCH_CANCELACTION

Like this:

JTextField text; // Must have the "search" type
text.putClientProperty("JTextField.Search.CancelAction", new
AbstractAction("ClearSearch") {
public void actionPerformed(ActionEvent event) {
// Clear search results here
}
}


.k

gmu

unread,
Nov 15, 2009, 7:29:49 AM11/15/09
to Mac Widgets for Java
Works great. Thanks, especially for pointing out the developer doc. I
am a new to Java on MAC and had no idea about the
notes from Apple. I hope all "variants" work on Windows as well. Yet
to test there.

On Nov 14, 7:50 am, Harald Kuhr <harald.k...@gmail.com> wrote:
> Hi,
>
> If you want a custom action bound to the clear/cancel button, you can  
> assign an Action(Listener) to the search field.
>
> http://developer.apple.com/Mac/library/technotes/tn2007/tn2196.html#J...

Harald Kuhr

unread,
Nov 15, 2009, 8:26:24 AM11/15/09
to mac-widget...@googlegroups.com
On 15. nov.. 2009, at 13.29, gmu wrote:

> I hope all "variants" work on Windows as well. Yet to test there.

I'm afraid the client properties in the technote are Apple-specific
(unless Ken did some magic to emulate the behaviour on other
platforms?). However, the client properties are just silently ignored
when not recognized so there should be no problem on Windows.


--
Harald K

Ken Orr

unread,
Nov 15, 2009, 8:50:16 AM11/15/09
to mac-widget...@googlegroups.com
Harald is right -- Apple's client properties will only work on a Mac. I do have an enhancement request for the a Search field on all platforms:


-Ken

Harald Kuhr

unread,
Nov 15, 2009, 9:27:30 AM11/15/09
to mac-widget...@googlegroups.com
On 15. nov.. 2009, at 14.50, Ken Orr wrote:

I do have an enhancement request for the a Search field on all platforms:



Came to think of it, I did write a quick hack to get similar functionality on other platforms some time ago. It doesn't look anything like the Apple search widget (nor the Windows search widget on Windows). But it could be used as a starting point. Feel free to include the code in Mac Widgets.

I have a ComponentFactory with a static get(), that returns the factory for the current environment, then I use the factory to create or decorate different components. 

It's not LAF-change aware, nor is it safe if you don't use the system LAF. But I guess at least the last issue could be fixed. And changing LAF in a running application isn't really that useful IMHO...


-- 
Harald K



// ComponentFactory
  public static ComponentFactory get() {...}

 abstract JTextField decorateSearchTextField(JTextField pTextField, ActionListener pResetAction);

// MacComponentFactory
  @Override
  JTextField decorateSearchTextField(final JTextField pTextField, final ActionListener pResetAction) {
    pTextField.putClientProperty("JTextField.variant", "search");
    pTextField.putClientProperty("Quaqua.TextField.style", "search");

    pTextField.putClientProperty("JTextField.Search.CancelAction", pResetAction);

    return pTextField;
  }

// DefaultComponentFactory
  @Override
  JTextField decorateSearchTextField(final JTextField pTextField, final ActionListener pResetAction) {
    Icon icon = new MetalIconFactory.PaletteCloseIcon();

    final JButton reset = new JButton(new AbstractAction("", icon) {
      public void actionPerformed(ActionEvent e) {
        pTextField.setText("");
        if (pResetAction != null) {
          pResetAction.actionPerformed(e);
        }
      }
    });

    reset.addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        pTextField.requestFocusInWindow();
      }
    });

    reset.setCursor(Cursor.getDefaultCursor());
    reset.setFocusable(false);
    reset.setOpaque(true);
    reset.setBackground(Color.LIGHT_GRAY);
    reset.setBorderPainted(false);
    reset.setContentAreaFilled(false);
    reset.setBorder(EMPTY_BORDER);
    reset.setHorizontalAlignment(JButton.LEFT);

    pTextField.add(reset);

    // Makes sure the reset button is only visible when there's text in the field
    final DocumentAdapter resetVisibleHandler = new DocumentAdapter() {
      protected void editHappened(DocumentEvent pDocumentEvent) {
        reset.setVisible(pDocumentEvent.getDocument().getLength() > 0);
      }
    };
    reset.setVisible(pTextField.getDocument().getLength() > 0);
    pTextField.getDocument().addDocumentListener(resetVisibleHandler);
    pTextField.addPropertyChangeListener("document", new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent pEvent) {
        Document oldDoc = (Document) pEvent.getOldValue();
        if (oldDoc != null) {
          oldDoc.removeDocumentListener(resetVisibleHandler);
        }

        Document newDoc = (Document) pEvent.getNewValue();
        if (newDoc != null) {
          newDoc.addDocumentListener(resetVisibleHandler);
        }
      }
    });

    // Make sure icon does not overlap text
    Insets margin = (Insets) pTextField.getMargin().clone();
    margin.right += reset.getPreferredSize().width;
    pTextField.setMargin(margin);

    // Layout reset when text field changes size
    pTextField.addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent pEvent) {
        JTextField textField = (JTextField) pEvent.getComponent();

        Dimension size = textField.getSize();
        Insets insets = (Insets) textField.getInsets().clone();
        int w = reset.getPreferredSize().width;
        insets.right -= w;

        reset.setBounds(new Rectangle(size.width - w - insets.right, 0, w + insets.right, size.height));
      }
    });

    return pTextField;
  }

Ken Orr

unread,
Nov 15, 2009, 10:38:50 AM11/15/09
to mac-widget...@googlegroups.com
I'll take a look at this -- thanks Harald!

Thasso Griebel

unread,
Nov 16, 2009, 5:54:48 AM11/16/09
to mac-widget...@googlegroups.com
There is a library based on SwingX that implements the search field
for multiple platforms

http://code.google.com/p/xswingx/

cheers,

thasso
--
Dipl. Inf. Thasso Griebel-------------------Lehrstuhl fuer Bioinformatik
Office 3426--http://bio.informatik.uni-jena.de--Institut fuer Informatik
Phone +49 (0)3641 9-46454-----------Friedrich-Schiller-Universitaet Jena
Fax +49 (0)3641 9-46452----------Ernst-Abbe-Platz 2, 07743 Jena, Germany



--
Dipl. Inf. Thasso Griebel-------------------Lehrstuhl fuer Bioinformatik
Office 3426--http://bio.informatik.uni-jena.de--Institut fuer Informatik
Phone +49 (0)3641 9-46454-----------Friedrich-Schiller-Universitaet Jena
Fax +49 (0)3641 9-46452----------Ernst-Abbe-Platz 2, 07743 Jena, Germany



Reply all
Reply to author
Forward
0 new messages