2010-11-20 38 views
5

Chúc mừng đến Ưu điểm Swing, đây là câu hỏi hay (tôi hy vọng) cho bạn.thay đổi hành vi của JFileChooser: ngăn chặn "chọn" khi nhập vào đường dẫn tệp JTextField

Dưới đây là các yêu cầu công việc và giải pháp có thể tôi thấy. Tôi muốn một người có trải nghiệm như vậy để chia sẻ một số suy nghĩ về điều này.

này không yêu cầu mã hóa hoặc bất cứ điều gì như thế, tôi chỉ cần lời khuyên chung như mà cách tiếp cận đáng tin cậy hơn về thực tế, tôi cần phải làm việc với tin những biểu tượng mà cư trú tại sun.swing và/hoặc các gói javax.swing.plaf.

Nhiệm vụ là sửa đổi/thay đổi hành vi JFileChooser (chỉ một chút, thực sự).

  1. khi người dùng nhấn enter vào tên tệp JTextField và trường có chứa đường dẫn đến thư mục, không "chọn" thư mục, nhưng chuyển sang thư mục thay thế. Có, hộp thoại được định cấu hình để chấp nhận thư mục, nhưng chúng tôi chỉ cần chấp nhận các nhấp chuột vào nút "Mở" và (có thể) nhấp đúp vào bảng danh sách tệp.

  2. ngăn chặn người dùng từ lựa chọn một thư mục/tập tin với hơn dữ liệu 1GB qua đánh nhập vào tên tập tin văn bản lĩnh vực

Here're vài lựa chọn giải pháp chung:

a. lắng nghe các thay đổi dựa trên thuộc tính mà JFileChooser cung cấp (mà AFAICS được kích hoạt sau khi thực tế và sẽ không cung cấp mức độ kiểm soát chúng ta cần ở đây).

b. tinker với javax.swing.plaf.basic.BasicFileChooserUI (thông qua refrection, phá vỡ đóng gói riêng tư cao nhất) và thay đổi tham chiếu đến

private Action approveSelectionAction = new ApproveSelectionAction(); 

để hành động tùy chỉnh của chúng tôi không kiểm tra thêm cho 1 và 2. Đây liên kết tiếp cận với gói plaf và có thể không thành công trong trường hợp hành động này bằng cách nào đó bị ghi đè trong một số lớp bên dưới lớp UI này.

c. đi ngang qua phân cấp thành phần JFileChooser, tìm JTextField (mà dường như chỉ xuất hiện một lần trong cây thành phần), trang trí tất cả các trình lắng nghe hành động treo trên JTextField đó bằng các kiểm tra tùy chỉnh của chúng ta. Phiên gỡ lỗi của tôi cho thấy rằng JTextField này là một số phân lớp ẩn danh của JTextField đang sống trong sun.swing.FilePane. Cách tiếp cận này dường như thân thiện với OO hơn, nhưng có một cơ hội cho một số hệ điều hành trường văn bản này vắng mặt, hoặc một số JTextField khác cũng có mặt trong hệ thống phân cấp. Vâng, có vẻ như API JFileChooser công cộng sẽ không đủ để đạt được hành vi đó, trong khi hai tùy chọn còn lại là ma thuật sâu hoặc không thể chuyển đổi (dài hạn), hoặc thậm chí cả hai.

Vì vậy, câu hỏi đặt ra là: bạn sẽ chọn phương pháp nào và tại sao?

Trả lời

5

Về tùy chọn2, bạn không cần sử dụng sự phản chiếu để tùy chỉnh Hành động chấp nhận. Bạn chỉ có thể ghi đè phương thức approvedSelection(). Một cái gì đó như:

JFileChooser chooser = new JFileChooser(new File(".")) 
{ 
    public void approveSelection() 
    { 
     if (getSelectedFile().exists()) 
     { 
      System.out.println("duplicate"); 
      return; 
     } 
     else 
      super.approveSelection(); 
    } 
}; 
+0

Oh me dumbo, tôi sẽ kiểm tra và báo cáo lại với những phát hiện của tôi. –

+0

Vâng vâng, tôi đã khá có thể đánh chặn và giải giáp sự kiện lựa chọn phê duyệt bằng cách không gọi super.approveSelection() trong một số trường hợp đáng lẽ phải được coi là không hợp lệ. Đó là một giải pháp khá tốt, cảm ơn một lần nữa. –

3

Gần đây tôi đã gặp phải yêu cầu tương tự, tức là, nhấn Enter trong JTextField của một JFileChooser sẽ làm cho hộp thoại được hiển thị đi qua một thư mục thay vì trở về từ hộp thoại. Chỉ việc nhấp vào nút Mở sẽ gây ra lựa chọn cuối cùng.

Giải pháp khá đơn giản (ít nhất là cho ứng dụng của tôi) và có hai thành phần cho nó (Xin lỗi cho định dạng sai lầm. Tôi mới tham gia diễn đàn này và tôi không chắc chắn tại sao mã không hiển thị chính xác) .

1 - Đăng ký một AWTListener để theo dõi các loại sự kiện cuối cùng được tạo bởi người sử dụng

class MyChooser extends JFileChooser implements java.awt.AWTEventListener { 

    ... 
    MyChooser(){ 
     Toolkit.getDefaultToolkit().addAWTEventListener(this, 
     AWTEvent.MOUSE_EVENT_MASK + AWTEvent.KEY_EVENT_MASK); 
     ... 

    } 

    int lastEventId; 

    public void eventDispatched(AWTEvent e) { 
     lastEventId=e.getID(); 
    } 
} 

2 - Override phương pháp approveSelection() của JFileChooser và kiểm tra xem các yêu cầu chính là kết quả của một con chuột sự kiện (có thể do người dùng nhấp vào nút Mở) gây ra hoặc sự kiện quan trọng do người dùng nhấn Enter. Biến 'lastEventId' cung cấp quyền truy cập vào thông tin này. Sau đó, chọn lựaSelection của tôi sẽ như sau:

public void approveSelection() { 
    File f=getSelectedFile(); 
    if (f.exists() && isTraversable(f) && lastEventId == 
     KeyEvent.KEY_PRESSED) { 
     setCurrentDirectory(f); 
     return; 
    } 
    super.approveSelection(); } 
+0

Hoạt động đẹp mắt. Như một con chuột-ophobic các chức năng mặc định đã thực sự gây phiền nhiễu cho tôi, và tôi lo sợ việc tìm kiếm giải pháp sẽ là v khó khăn. –

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