2010-02-26 38 views
16

Tôi đang cố tải hình ảnh để sử dụng làm biểu tượng trong ứng dụng của mình. Phương pháp thích hợp theo số tutorial này là:Tải tài nguyên bằng cách sử dụng getClass(). GetResource()

protected ImageIcon createImageIcon(String path, String description) 
{ 
    java.net.URL imgURL = getClass().getResource(path); 
    if (imgURL != null) { 
     return new ImageIcon(imgURL, description); 
    } else { 
     System.err.println("Couldn't find file: " + path); 
     return null; 
    } 
} 

Vì vậy, tôi đã đặt vị trí của tệp và chuyển nó làm tham số cho hàm này. Điều này không hiệu quả, tức là imgURL không có giá trị. Khi tôi cố gắng tạo ImageIcon bằng cách đi qua đường dẫn rõ ràng:

ImageIcon icon = new ImageIcon(path,"My Icon Image"); 

Nó hoạt động rất tốt! Vì vậy, ứng dụng có thể lấy hình ảnh từ một đường dẫn được xác định rõ ràng, nhưng không nhận được hình ảnh bằng cách sử dụng getResources(). Trong cả hai trường hợp, giá trị của biến đường dẫn là như nhau. Tại sao nó không hoạt động? Tài nguyên được tìm thấy như thế nào bởi trình nạp lớp?

Cảm ơn.

+2

Bạn đang sử dụng IDE? IDE có được thiết lập để sao chép tài nguyên vào bất cứ nơi nào các lớp được biên dịch không? – z5h

+0

Hình ảnh nằm ở đâu so với lớp và đến gốc của dự án? – willcodejavaforfood

+0

Có, tôi đang sử dụng Eclipse và không được thiết lập để sao chép tài nguyên. Đã khắc phục điều đó. Lớp học nằm ở thư mục gốc/bin//MyClass và hình ảnh được đặt trong thư mục gốc/resources/images/myImage.gif Cảm ơn câu trả lời của bạn. – Luhar

Trả lời

12

Bạn có thể yêu cầu một con đường ở định dạng này:

/package/path/to/the/resource.ext 

Ngay cả các byte để tạo các lớp trong bộ nhớ được tìm thấy theo cách này:

my.Class -> /my/Class.class 

và getResource sẽ cung cấp cho bạn một Mà URL có thể được sử dụng để truy xuất InputStream.

Nhưng ... Tôi khuyên bạn nên sử dụng trực tiếp getClass().getResourceAsStream(...) với cùng một đối số, vì nó trả về trực tiếp InputStream và không phải lo lắng về việc tạo một đối tượng URL (có thể phức tạp) phải biết cách tạo InputStream.

Tóm lại: thử sử dụng getResourceAsStream và một số hàm tạo của ImageIcon sử dụng tham số đầu vào làm đối số.

classloaders

Hãy cẩn thận nếu ứng dụng của bạn có nhiều classloaders. Nếu bạn có một ứng dụng độc lập đơn giản (không có máy chủ hoặc những thứ phức tạp), bạn không nên lo lắng. Tôi không nghĩ đó là trường hợp mà ImageIcon cung cấp có khả năng tìm ra nó.

Edit: classpath

getResource là -Như mattb says- tài nguyên tải từ classpath (từ .jar của bạn hoặc thư mục classpath). Nếu bạn đang đóng gói một ứng dụng, thật tuyệt khi có hoàn toàn, vì vậy bạn có thể đưa tệp biểu tượng vào trong ứng dụng của mình và lấy nó theo cách này.

14

getClass().getResource(path) tải tài nguyên từ đường dẫn lớp, không phải từ đường dẫn hệ thống tệp.

+0

lol! Tôi cho rằng anh ta có classpath không phải là filepath. Tôi sẽ sửa câu trả lời của tôi. – helios

3

Là một noobie tôi đã bối rối bởi điều này cho đến khi tôi nhận ra rằng "đường dẫn" được gọi là đường dẫn tương đối vào MyClass. lớp tệp trong hệ thống tệp chứ không phải MyClass. java tệp. IDE của tôi sao chép các tài nguyên (như xx.jpg, xx.xml) vào một thư mục cục bộ cho lớp MyClass.class. Ví dụ, bên trong một thư mục pkg được gọi là "target/classes/pkg. Vị trí tệp lớp có thể khác với các IDE khác nhau và tùy thuộc vào cách xây dựng được cấu trúc cho ứng dụng của bạn. Trước tiên, bạn nên khám phá hệ thống tệp và tìm vị trí của tệp MyClass.class và vị trí được sao chép của tài nguyên được liên kết mà bạn đang tìm cách trích xuất.Sau đó xác định đường dẫn liên quan đến tệp MyClass.class và viết nó như một giá trị chuỗi với "dấu chấm" và "dấu gạch chéo".

Ví dụ: dưới đây là cách tôi tạo tệp app1.fxml có sẵn cho ứng dụng javafx của tôi trong đó "MyClass.class" có liên quan hoàn toàn là "Main.class". Tệp Main.java là nơi chứa dòng mã gọi điện tài nguyên này. Trong trường hợp cụ thể của tôi, các tài nguyên được sao chép vào một vị trí ở cùng mức với thư mục gói kèm theo. Đó là: /target/classes/pkg/Main.class và /target/classes/app1.fxml. Vì vậy, diễn giải ... tham chiếu tương đối "../app1.fxml" là "bắt đầu từ Main.class, đi lên một cấp độ thư mục, bây giờ bạn có thể thấy tài nguyên".

FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(getClass().getResource("../app1.fxml")); 

Lưu ý rằng trong chuỗi đường dẫn tương đối "../app1.fxml", hai dấu chấm đầu tiên tham chiếu thư mục chứa Main.class và dấu "." cho biết một phần mở rộng tập tin để làm theo. Sau khi những chi tiết này trở thành bản chất thứ hai, bạn sẽ quên tại sao nó lại khó hiểu.

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