2012-05-27 29 views
12

netbeansを使用してアプリケーションを読み込むと、最初のJTextFieldが自動的にフォーカスされ、このJTextFieldに「Enter your Username」と書かれています。フィールドが表示されますが、アプリケーションがロードされると、このフィールドにフォーカスが当てられます。つまり、「ユーザー名を入力してください」が表示されないことがあります。JTextFieldのフォーカスを解除する方法

+0

Theresの2つのJTextField、最初のユーザ名用、パスワードための第二、および中のJMenuItemと呼ばれるログ(ただ一つのフォーカス可能コンポーネント:)でGUIでテストされていない)

、私はアプリケーションを実行した瞬間、最初のJTextFieldフォーカスされている、私はそれを望んでいない –

+0

BTW - 各アプリのユーザー名。インストールが*予想される*定数である、ちょうどデフォルトのユーザー名フィールドを設定し、正しい場合、次のフィールドにユーザータブを許可します。定数*になることが保証されている場合は、フィールドに値を設定して無効にします。フォーカスは**フォーカスされません。フォーカスはデフォルトで第2フィールドに移動します。 –

答えて

14

ログインが最高のモーダルダイアログで行いますが、それはそれで問題を引き起こすことになるコンポーネントが表示されている後を呼び出さなければなりませんが、それがブロックされているrequestFocusInWindow()方法事実、ダイアログはモーダルです!

この例では、ダイアログが表示された後、Rob CamickのRequestFocusListenerDialog Focusに表示)を使用してフォーカスを管理しています。

Login with focused password field

注:ユーザーが何かを行う前に、それがどのように表示されるかです。パスワードフィールドはデフォルトでフォーカスされています。

package test.t100.t001; 

import java.awt.BorderLayout; 
import java.awt.GridLayout; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JPasswordField; 
import javax.swing.JTextField; 
import javax.swing.SwingConstants; 
import javax.swing.SwingUtilities; 
import javax.swing.event.AncestorEvent; 
import javax.swing.event.AncestorListener; 

public class LoginRequired { 

    LoginRequired() { 
     JFrame f = new JFrame("Login Required"); 
     f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     f.setSize(400, 300); 
     f.setResizable(false); 
     f.setLocationByPlatform(true); 
     f.setVisible(true); 

     showLogin(f); 
    } 

    private void showLogin(JFrame frame) { 
     JPanel p = new JPanel(new BorderLayout(5,5)); 

     JPanel labels = new JPanel(new GridLayout(0,1,2,2)); 
     labels.add(new JLabel("User Name", SwingConstants.RIGHT)); 
     labels.add(new JLabel("Password", SwingConstants.RIGHT)); 
     p.add(labels, BorderLayout.WEST); 

     JPanel controls = new JPanel(new GridLayout(0,1,2,2)); 
     JTextField username = new JTextField("Joe Blogs"); 
     controls.add(username); 
     JPasswordField password = new JPasswordField(); 
     password.addAncestorListener(new RequestFocusListener(false)); 
     controls.add(password); 
     p.add(controls, BorderLayout.CENTER); 

     //LayoutManager l = new GroupLayout(p); 
     //p.setLayout(l); 
     JOptionPane.showMessageDialog(
      frame, p, "Log In", JOptionPane.QUESTION_MESSAGE); 
    } 

    /** 
    * @param args none 
    */ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable(){ 
      @Override 
      public void run() { 
       new LoginRequired(); 
      } 
     }); 
    } 

} 

/** 
* Convenience class to request focus on a component. 
* 
* When the component is added to a realized Window then component will 
* request focus immediately, since the ancestorAdded event is fired 
* immediately. 
* 
* When the component is added to a non realized Window, then the focus 
* request will be made once the window is realized, since the 
* ancestorAdded event will not be fired until then. 
* 
* Using the default constructor will cause the listener to be removed 
* from the component once the AncestorEvent is generated. A second constructor 
* allows you to specify a boolean value of false to prevent the 
* AncestorListener from being removed when the event is generated. This will 
* allow you to reuse the listener each time the event is generated. 
*/ 
class RequestFocusListener implements AncestorListener 
{ 
    private boolean removeListener; 

    /* 
    * Convenience constructor. The listener is only used once and then it is 
    * removed from the component. 
    */ 
    public RequestFocusListener() 
    { 
     this(true); 
    } 

    /* 
    * Constructor that controls whether this listen can be used once or 
    * multiple times. 
    * 
    * @param removeListener when true this listener is only invoked once 
    *      otherwise it can be invoked multiple times. 
    */ 
    public RequestFocusListener(boolean removeListener) 
    { 
     this.removeListener = removeListener; 
    } 

    @Override 
    public void ancestorAdded(AncestorEvent e) 
    { 
     JComponent component = e.getComponent(); 
     component.requestFocusInWindow(); 

     if (removeListener) 
      component.removeAncestorListener(this); 
    } 

    @Override 
    public void ancestorMoved(AncestorEvent e) {} 

    @Override 
    public void ancestorRemoved(AncestorEvent e) {} 
} 
+0

hmmm私の言葉も+1 – mKorbel

+0

@AloneInTheDarkこれは別の質問です。質問。 –

4

requestFocusInWindow()を使用して、最初にJTextfieldではなく他のコンポーネントにフォーカスを設定します。

しかし、私は(NetBeansであると仮定)constructorJTextFieldinitComponents()後の呼び出しにネイティブフォーカスシステム、むしろsetText(String s)を変更しないをお勧めしたいです。

さらに、オプションの読書:How to Use the Focus Subsystem

+0

ログインするためにJMenuItemをクリックしなければならない場合はどうすればいいですか?他の要素でrequestFocusInWindow()を使用しましたが、そのJMenuItemをクリックした瞬間にJTextFieldがフォーカスされ、JMenuItemをクリックするとJTextFieldがフォーカスされず、後で動作しますが、初めて動作しません。 –

+0

'JMenuItem'のNetBeansプロパティエディタの' nextFocusableComponent'プロパティ? – Asif

+0

私はそれを修正しました。起動時にurコードを2回使用しました.Jmenuitemをクリックすると、 –

3

ユーザが最初にやる必要があると仮定して、ユーザ名フィールドにキーボードフォーカスを与えるのは正しい動作です。代わりに、焦点にクリアするのは、なぜ明確ではないだけで、ユーザーのタイプの後に?:

import java.awt.*; 
import javax.swing.*; 
import javax.swing.text.Document; 

public class PlaceholderTextField extends JTextField { 

    public static void main(final String[] args) { 
     final PlaceholderTextField tf = new PlaceholderTextField(""); 
     tf.setColumns(20); 
     tf.setPlaceholder("All your base are belong to us!"); 
     final Font f = tf.getFont(); 
     tf.setFont(new Font(f.getName(), f.getStyle(), 30)); 
     JOptionPane.showMessageDialog(null, tf); 
    } 

    private String placeholder; 

    public PlaceholderTextField() { 
    } 

    public PlaceholderTextField(
     final Document pDoc, 
     final String pText, 
     final int pColumns) 
    { 
     super(pDoc, pText, pColumns); 
    } 

    public PlaceholderTextField(final int pColumns) { 
     super(pColumns); 
    } 

    public PlaceholderTextField(final String pText) { 
     super(pText); 
    } 

    public PlaceholderTextField(final String pText, final int pColumns) { 
     super(pText, pColumns); 
    } 

    public String getPlaceholder() { 
     return placeholder; 
    } 

    @Override 
    protected void paintComponent(final Graphics pG) { 
     super.paintComponent(pG); 

     if (placeholder.length() == 0 || getText().length() > 0) { 
      return; 
     } 

     final Graphics2D g = (Graphics2D) pG; 
     g.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g.setColor(getDisabledTextColor()); 
     g.drawString(placeholder, getInsets().left, pG.getFontMetrics() 
      .getMaxAscent() + getInsets().top); 
    } 

    public void setPlaceholder(final String s) { 
     placeholder = s; 
    } 

} 

何かをあなたが本当にただ、いくつかのオプションをフォーカスを削除する場合:

  • component.setFocusable(false);
  • KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
  • KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
3
textField.setFocusable(false); 
textField.setFocusable(true); 

textFieldにフォーカスがある場合にのみ、TAB順の次のコンポーネントに自動的にフォーカスが当てられます。その効果はTABプレスと同じです。

関連する問題