2012-06-20 19 views
7

Tôi có một textField trong ứng dụng của tôi sẽ được khởi tạo theo chương trình (textField.setText()) khi người dùng nhấp vào một mục trong JList. người dùng sau sẽ thay đổi giá trị này theo cách thủ công. Tôi gặp khó khăn khi sử dụng trình nghe tài liệu để phát hiện các thay đổi trong trường văn bản này. Khi các thay đổi xảy ra theo chương trình, nó không phải làm gì ngoài việc xảy ra theo cách thủ công, nó sẽ thay đổi màu nền thành màu đỏ.Làm thế nào để tạo sự khác biệt giữa textField.setText() và thêm văn bản vào textField bằng tay trong java?

Cách phát hiện xem textField đã được điền thủ công hay bằng textField.setText()?

txtMode.getDocument().addDocumentListener(new DocumentListener() { 
     public void insertUpdate(DocumentEvent e) { 
      if (!mode.equals(e.getDocument())) 
      txtMode.setBackground(Color.red); 
     } 

     public void removeUpdate(DocumentEvent e) { 
      if (mode.equals(e.getDocument())) 
      txtMode.setBackground(Color.white);    
     } 

     public void changedUpdate(DocumentEvent e) { 
      //To change body of implemented methods 
     } 
    }); 

Trả lời

8

có hai cách

  • loại bỏ DocumentListener trước setText("...") thêm DocumentListener trở lại nếu được thực hiện

đang

public void attachDocumentListener(JComponent compo){ 
     compo.addDocumentListener(someDocumentListener); 
} 

//similair void for remove.... 
  • sử dụng boolean giá trị cho việc vô hiệu hóa "nếu cần thiết", nhưng bạn phải thay đổi contens của bạn DocumentListener

ví dụ

txtMode.getDocument().addDocumentListener(new DocumentListener() { 
    public void insertUpdate(DocumentEvent e) { 
     if (!mode.equals(e.getDocument())) 

     if (!updateFromModel){ 
      txtMode.setBackground(Color.red); 
     } 
    } 

    public void removeUpdate(DocumentEvent e) { 
     if (mode.equals(e.getDocument())) 

     if (!updateFromModel){ 
      txtMode.setBackground(Color.white); 
     } 
    } 

    public void changedUpdate(DocumentEvent e) { 
     //To change body of implemented methods 
    } 
}); 
+1

Điểm bắt ở đây là đôi khi setText() được gọi bởi ai đó không phải là mã của riêng bạn. Đây là vấn đề tôi đang chiến đấu chống lại vào lúc này, dù sao đi nữa. Tôi ước họ có thể có một wasTriggeredByUser() trên mọi sự kiện. – Trejkaz

+0

@Trejkaz xin vui lòng làm thế nào, ở đâu, tại sao, là có một số lý do đặc biệt, btw Tài liệu là mô hình cho JTextComponents, sau đó tiêu thụ/bắn tất cả các thay đổi/sự kiện mô hình betweens để xem và ngược lại – mKorbel

4

Hãy ghi nhớ rằng tất cả các thính giả sự kiện được thực hiện trên Swing Event Chủ đề . Vì vậy, mọi thứ có thể không đi theo thứ tự chính xác như bạn muốn họ. Trong tình huống này, mọi giải pháp sẽ là hack-ish bởi vì bạn không thể kiểm soát toàn bộ chuỗi xoay và ai đăng sự kiện lên đó.

Điều tôi đang cố gắng nói là: giả sử bạn chọn sử dụng một số cờ để cho người nghe biết rằng đó là một thay đổi có lập trình. Đây là kịch bản có thể (tôi giả sử bạn đang theo dõi sự cai trị tốt đẹp của làm bất kỳ bản cập nhật giao diện người dùng từ sợi đu qua invokeLater):

  1. đặt cờ để bỏ qua sự kiện
  2. setText
  3. bộ cờ false

nếu bạn làm tất cả trong một lệnh gọi, setText sẽ kích hoạt sự kiện cập nhật được đăng vào cuối hàng đợi sự kiện, do thời gian chúng được thực thi, cờ sẽ là sai.

Vì vậy, bạn nên thực hiện bước 1 và 2 trong một cuộc gọi invokeLater hoặc thậm chí invokeAndWait và sau đó đăng sự kiện khác với invokeLater để hủy đặt cờ. Và cầu nguyện rằng người dùng của bạn không quá nhanh để thực hiện một số thay đổi giữa hai lời gọi này, nếu không, chúng cũng được coi là một thay đổi có lập trình.

Các vấn đề liên quan