2014-07-25 22 views
11

Mô hình MVC của JavaFX bằng cách sử dụng FXML âm thanh tuyệt vời và tất cả nhưng tôi gặp khó khăn khi tìm hiểu cách tổ chức các gói dự án của mình.Cấu trúc dự án JavaFX

Mỗi hướng dẫn tôi tìm thấy về JavaFX là cách đơn giản và không tổ chức: Chúng chỉ đơn giản là tạo MỘT gói và tạo mọi thứ ở đó, mọi bộ điều khiển, mọi fxml, mọi css. Tôi không muốn điều đó. Tôi muốn mọi thứ ở đúng nơi.

Tuy nhiên, "đường dẫn" của JavaFX có vẻ ... "yếu". Việc sử dụng các URL làm cho nó để nếu tôi muốn giới hạn tài nguyên của tôi vào các tập tin địa phương, tôi phải làm toàn bộ điều getClass().getResource("foo.fxml").openStream(). Điều đó thật tuyệt vời, nhưng bằng cách lấy các tài nguyên từ một đường dẫn lớp, đường dẫn đến từ gói mà lớp đó đang ở. Tôi đã muốn gốc của dự án. Điều đó sẽ đơn giản hóa cuộc sống của tôi, nhưng JavaFX dường như không hoạt động như thế.

Cho phép nhận được một ví dụ thực tế:

Hãy tưởng tượng tôi có một FXML "Login Screen". Hãy tưởng tượng tôi muốn màn hình đăng nhập đó sử dụng biểu định kiểu. Lý tưởng nhất, css đó sẽ nằm trong cùng một gói của fxml đó. Nhưng nếu tôi muốn sử dụng cùng một .css trong FXML khác thì sao? Điều đó có nghĩa là tôi phải đặt cả hai FXML trong cùng một gói? Rõ ràng tôi "không cần phải", nhưng làm thế nào để tôi làm điều đó sau đó?

Ngoài ra, hãy nói rằng tôi muốn thay đổi cảnh khi tôi đăng nhập đúng cách. Trong sự kiện thích hợp của FXML Controller, tôi sẽ phải gọi một "setScene". Con đường đó cũng sẽ khó đạt được vì nếu tôi có các gói FXML trong các gói khác nhau. Nó chỉ có vẻ như là tất cả mọi thứ là trong một gói khổng lồ cồng kềnh hoặc tất cả mọi thứ là khó khăn để truy cập mà không cần đến hack như "../../dir".

Ứng dụng Henley Sales trong http://docs.oracle.com/javafx/2/best_practices/jfxpub-best_practices.htm có vẻ là một ví dụ về ứng dụng được tổ chức tốt, mặc dù ứng dụng này là một TabPane duy nhất. Thật không may (ít nhất tôi nghĩ) nguồn không mở. ý tưởng của nó là một cái gì đó như thế này:

client 
    Main.class 
    styles.css 
     client.images 
      image.png 
     client.screen1 
      Screen1.fxml 
      Screen1Controller.java 
     client.screen2 
      Screen2.fxml 
      Screen2Controller.java 
     ... 

này doenst vẻ giống như một khởi đầu tồi tệ, nhưng nó có một vài vấn đề (hoặc ít nhất tôi nhìn thấy chúng như các vấn đề).

Đối với 'The Henley Sales', thông minh của nó để có một Main sẽ gọi một trong các gói FXML (dễ truy cập, các thư mục của FXML nằm dưới lớp Main). Tuy nhiên, đối với biểu định kiểu, nó sẽ phải được mã hóa cứng bởi scene.getStylesheets().add(...);. Tôi thực sự muốn có sự lựa chọn việc chọn biểu định kiểu của tôi trong FXML. Sau đó, biểu định kiểu là một phần của thành phần Chế độ xem. Việc truy cập tệp .css từ một URL trong FXML sẽ rất khó với cấu trúc này, vì nó ở trên các thư mục của chúng.

Ngoài ra, với tổ chức này, làm cách nào để tôi thay đổi cảnh hoàn toàn? Trong dự án này, điều đó là không cần thiết vì toàn bộ dự án là một TabbedPane duy nhất. Chính gọi nó, và nó được thực hiện. Không cần phải hoán đổi thêm. Nhưng một khung cảnh đăng nhập đơn giản (hoặc bất kỳ lý do gì mà một người sẽ cần phải trao đổi toàn bộ khung cảnh) đòi hỏi một nhu cầu truy cập vào các đường dẫn FXML.

Và sau đó là các tài nguyên. Các tệp css có thể cần sử dụng hình ảnh. Cấu trúc đó giải quyết nó bằng cách đặt tệp .css lên trên cùng và tạo một gói chỉ dành cho các tệp mà tệp .css có thể cần. Nếu tôi muốn một FXML cụ thể có một .css khác nhau, tho, một vấn đề khác sẽ đến.

Dường như một chu kỳ. Css cần quyền truy cập vào một thư mục tài nguyên được chia sẻ. FXML cần truy cập vào Css. Các bộ điều khiển của FXML cần truy cập vào các FXML khác. Tôi hy vọng tôi đã rõ ràng về cấu trúc dự án của tôi nghi ngờ. Xin hãy giúp tôi về việc tạo ra một cấu trúc dự án JavaFX đủ mạnh cho một ứng dụng nhiều hơn cơ bản, hoặc chuyển hướng tôi đến một số mã nguồn tốt.

Ồ, Im sử dụng Netbeans bằng cách này.

Trả lời

23

IMHO, bạn không nên tạo gói tùy thuộc vào màn hình của bạn!

Tiếp cận của tôi đối với các ứng dụng như

  • Một gói cho tương ứng controllers các views
  • gói khác nhau cho dịch vụ (kinh doanh) và dao (kiên trì) lớp, nếu tồn tại
  • Một gói/thư mục cho các tài nguyên như hình ảnh, css, v.v.
  • Gói cho fxml được gọi là view trong tài nguyên

    src/main/java 
        | 
        controllers 
        | 
        Screen1controller.java 
        Screen2controller.java 
        service 
        | 
        Service1.java 
        dao(persist) 
        | 
        SaveProducts.java 
    src/main/resources 
        | 
        view 
        | 
        screen1.fxml 
        screen2.fxml 
        css 
        | 
        style.css 
        | 
        images 
        | 
        img1.jpg 
        img2.jpg 
    

Việc triển khai ở trên có thể được xem xét cho dự án Maven.

Đối với một dự án đơn giản, bạn có thể xem structure here. Nó là một dự án maven!

+0

Hmm có vẻ thú vị, mặc dù css có vẻ khó tiếp cận từ một URL trong FXML (trừ khi tôi làm ../ điều mà tôi hơi không thích ...). Tôi có thể đặt các tài nguyên sau khi xem gói tho, Nó có ý nghĩa vì các tài nguyên là một phần của khung nhìn. Tôi không biết những gì dịch vụ và DAO là dành cho tho, bạn có thể cho tôi một ví dụ? (Ứng dụng Im sẽ tạo ra sử dụng máy chủ MySQL để tìm nạp và lưu trữ dữ liệu) – Xkynar

+0

Cập nhật câu trả lời của tôi để rõ ràng hơn! – ItachiUchiha

+0

Nhược điểm của phương pháp này là chế độ xem và bộ điều khiển không nằm trong cùng thư mục và do đó SceneBuilder không có khả năng liên kết chúng. Nếu ScreenBuilder không yêu cầu nó, tôi sẽ đặt fxml vào thư mục tài nguyên. – ChrLipp

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