2013-07-03 10 views
2

默認情況下,當JTextField獲得焦點時,插入符號位於文本的開頭。不過,我認爲更好的行爲是將其定位在最後,或選擇所有文本,例如http://jsfiddle.net/Marcel/jvJzX/。什麼是一個很好的方法來做到這一點?理想情況下,該解決方案將全局應用於應用程序中的所有JTextField。默認行爲將焦點定位在焦點JTextField的末尾處的最佳方式是什麼?

例(按Tab鍵,重點領域):

public static void main(String[] args) { 
    JTextField field = new JTextField("hello world!"); 
    JOptionPane.showMessageDialog(null, field); 
} 

編輯:爲了澄清,這將是很好,如果我沒有通過我的應用程序來搜索和更改所有文本字段。

+0

要麼或在結束時光標定位 –

+0

這就是可能是signoficant差,(我的觀點)有兩種方式與卡拉移動到文檔的結尾看@MadProgrammer的答案或selectAll()看我的評論(@MadProgrammer)後 – mKorbel

回答

5

無論是實際行爲,也不要求有詳細描述:

當一個JTextField獲得焦點插入符號位於文本

這是不完全正確的開始 :當它被

獲得焦點
  • 點擊,插入符號被放置在鼠標位置
  • 其他手段(tabbing,programmatic)它被放置在當時焦點位置 丟失。

因此,要求:

更好的行爲是它在結束處,或選擇所有 文本

需要一點思想的那些案件不會減少可用性,至少對於第一個用戶可能會被混淆,如果鼠標手勢將被否決。第二個是有爭議的,可能是OS/LAF的依賴。就我個人而言,如果其位置並非一開始就不會觸及插入符號。

從技術上講,溶液在全球範圍上焦點改變組件狀態的觸發的變化是註冊到的KeyboardFocusManager一個PropertyChangeListener:

PropertyChangeListener pl = new PropertyChangeListener() { 

    @Override 
    public void propertyChange(PropertyChangeEvent evt) { 
     if (!(evt.getNewValue() instanceof JTextField)) return; 
     JTextField field = (JTextField) evt.getNewValue(); 
     // crude check to not overdo it 
     int dot = field.getCaretPosition(); 
     if (dot == 0) { 
      field.selectAll(); 
     } 
    } 
}; 
KeyboardFocusManager.getCurrentKeyboardFocusManager() 
    .addPropertyChangeListener("permanentFocusOwner", pl); 
+2

+1,便於全球解決方案。 'selectAll()'應該被包裝在SwingUtilities.invokeLater()中,否則JFormattedTextField上的選擇將不起作用。 – camickr

+0

@camickr好點!雖然對formattedTextField的可用性不完全確定 - 它的navigationFilter可能有自己的想法? – kleopatra

+1

+1 - 您可能還想檢查'event.getOldValue()'是否是JTextField,以撤銷'selectAll()'。 – splungebob

3

添加FocusListener到外地

focusGained被觸發,設置字段的文本的末尾插入位置...

field.setCaretPosition(field.getDocument().getLength()); 

How to write a focus listener更多細節

更新

要選擇所有文本,y你可以使用...

field.selectAll(); 

這將移動光標到最後。

我過去所做的是創建一個實用程序類(例如,AutoSelectOnFocusManager),它有一個單一的FocusListener。基本上,您註冊(或取消註冊)JTextComponent s,併爲您管理流程。節省了大量的重複的代碼:P

更新一個簡單的例子

難道這個簡單的例子來測試意見反饋,以爲我只是在重擊,以及...

import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.event.FocusAdapter; 
import java.awt.event.FocusEvent; 
import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Wackme { 

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

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

       JTextField field1 = new JTextField("Some text", 20); 
       JTextField field2 = new JTextField("Some text", 20); 

       field1.addFocusListener(new FocusAdapter() { 
        @Override 
        public void focusGained(FocusEvent e) { 
         System.out.println("Move to end"); 
         JTextField field = ((JTextField)e.getComponent()); 
         field.selectAll(); 
         //field.setCaretPosition(field.getDocument().getLength()); 
        } 
       }); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new GridBagLayout()); 
       frame.add(field1); 
       frame.add(field2); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
+0

我認爲應該是'field.getDocument()。getLength() - 1' –

+1

@MadProgrammer [我認爲](http://stackoverflow.com/a/8544512/714968),但需要將XXX.selectAll()包裝到'invokeLat er' – mKorbel

+1

@mKorbel它取決於,我知道如果它是一個'JSpinner',它肯定是 – MadProgrammer

-2

您需要創建自定義的JTextField並越過你要必要的方法和像你想選擇焦點的所有值虎子然後再編寫代碼,該方法執行步驟

相關問題