2014-04-02 7 views
0

저는 Java 응용 프로그램에서 작업하고 있으며 스스로 해결할 수없는 문제가 발생했습니다.DocumentFilter에서 숫자 만 허용하는 동안 JTextField를 문자열 값으로 설정합니다.

DocumentFilter에 숫자 항목 만 허용하도록 설정했지만 기본값은 텍스트입니다. JTextField을 기본값으로 다시 설정하는 버튼이 있으며 DocumentFilter 때문에 예상대로 작동하지 않습니다.

이 문제를 어떻게 극복 할 수 있습니까?

감사

+0

텍스트 내용? 숫자가 포함되어 있지 않습니까? 본문의 목적은 무엇입니까? – MadProgrammer

+0

그것은 문자 텍스트입니다. 내가 말했듯이 그것은 디폴트 값이다. –

+0

@ Yury Lankovskiy는 흥미로운 질문이 될 수 있습니다. 그러나 여기에 SSCCE/MCVE/MCTRE, short, runnable, 지역 변수의 하드 코드 된 값으로 컴파일 할 수 있습니다. – mKorbel

답변

2

숫자 데이터 만 입력 할 수 있지만 숫자가 아닌 값을 표시해야하는 필드는 모순입니다.

텍스트가 Document을 통해 필드에 입력되었으므로 사용자 또는 프로그래밍 방식으로 콘텐츠가 생성되는 방식을 구분하지 않습니다. 당신이 필드에 "메시지"를 표시하려는 경우

, 당신은 필드가있을 때 예

Prompt fields

를 들어 SwingLabs SwingX Library

PromptSupport 살펴보고 수 있습니다 "프롬프트"는 숨겨 지지만 사용자가 무언가를 입력하거나 포커스를 얻었을 때 강조 표시 할 때까지 표시되도록 제어 할 수 있습니다.

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import org.jdesktop.swingx.prompt.BuddySupport; 
import org.jdesktop.swingx.prompt.PromptSupport; 

public class PromptSupportTest { 

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

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

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

    public class TestPane extends JPanel { 

     public TestPane() { 
      JTextField firstName = new JTextField(10); 
      PromptSupport.setPrompt("First Name", firstName); 
      PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, firstName); 

      JTextField lastName = new JTextField(10); 
      PromptSupport.setPrompt("Last Name", lastName); 
      PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, lastName); 

      JTextField picture = new JTextField(10); 
      PromptSupport.setPrompt("Picture", picture); 
      PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, picture); 

      JButton browse = new JButton("..."); 
      browse.setMargin(new Insets(0, 0, 0, 0)); 
      browse.setContentAreaFilled(false); 
      browse.setFocusPainted(false); 
      browse.setFocusable(false); 
      browse.setOpaque(false); 
      // Add action listener to brose button to show JFileChooser... 

      BuddySupport.addRight(browse, picture); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      gbc.weightx = 1; 

      add(firstName, gbc); 
      add(lastName, gbc); 
      add(picture, gbc); 

      gbc.anchor = GridBagConstraints.CENTER; 
      add(new JButton("Ok"), gbc); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 

는 또한 당신에게 "친구"텍스트 구성 요소가 다른 구성 요소를 허용하는 동일한 API의 일부입니다 BuddySupport의 예를 추가했습니다. 여기에 고전적인 "파일 브라우저"조합을 수행했지만, 이처럼 항상 "검색"스타일 필드를 사용합니다 ...

4

한 가지를 수행합니다 기본 문서가 버튼 클릭에

final JTextField textField = new JTextField(); 
final Document defaultDocument=textField.getDocument(); 

먼저 텍스트 필드에 대한 유효성 검사를 사용하지 않도록 다시 기본 문서를 설정 한 경우 일부 다음을 설정

저장소를 기본 텍스트

btn.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     textField.setDocument(defaultDocument); 
     textField.setText("hi"); 
    } 
}); 

문서 필터 추가 다시 사용자 입력을 확인하기 위해 텍스트 필드에 포커스를 맞 춥니 다.

How to implement in Java (JTextField class) to allow entering only digits?을 참조하십시오.


- 편집 -

당신은 text fieldfocus listener을 추가하여 그것을 할 수 있습니다.

텍스트 필드의 값이 비어 있으면 기본 값을 다시 힌트로 설정하십시오. 버튼 클릭시이를 수행 할 필요가 없습니다.

final JTextField textField = new JTextField("First Name"); 

    final Document defaultDocument = textField.getDocument(); 

    final PlainDocument doc = new PlainDocument(); 
    doc.setDocumentFilter(new DocumentFilter() { 
     @Override 
     public void insertString(FilterBypass fb, int off, String str, AttributeSet attr) 
       throws BadLocationException { 
      fb.insertString(off, str.replaceAll("\\D++", ""), attr); // remove 
                    // non-digits 
     } 

     @Override 
     public void replace(FilterBypass fb, int off, int len, String str, 
       AttributeSet attr) throws BadLocationException { 
      fb.replace(off, len, str.replaceAll("\\D++", ""), attr); // remove 
                    // non-digits 
     } 
    }); 

    textField.addFocusListener(new FocusListener() { 

     @Override 
     public void focusLost(FocusEvent e) { 
      System.out.println("focus lost"); 
      if(textField.getText() == null || textField.getText().trim().length()==0){ 
       textField.setDocument(defaultDocument); 
       textField.setText("First Name"); 
      } 
     } 

     @Override 
     public void focusGained(FocusEvent e) { 
      System.out.println("focus gained"); 
      textField.setDocument(doc); 
     } 
    }); 
+0

나는 내 게시물을 업데이 트했습니다. 한번 봐주세요. – Braj

+0

예 OP는 런타임에 수행 할 수 있습니다. OP는 기본적으로 하나의 문서 필터와 숫자를위한 두 번째 문서 필터 만 필요합니다. – Braj

+0

감사합니다. 대신 PromptSupport를 사용하고 있습니다. 훨씬 쉽습니다. –

2

당신이

또는 어쩌면 Text Prompt 클래스 PromptSupport

같은 것을 사용할 수 있습니다 여기에

는 코드입니다. PromptSupport와 비슷하지만 일반 JTextField에서 사용할 수 있으므로 전체 SwingX 프로젝트가 필요하지 않습니다.