Các khung công tác Java GUI. Chọn cái gì? Xoay, SWT, AWT, SwingX, Joodies, JavaFX, Apache Pivot? [đóng cửa]


228

Có khá nhiều khung gui ngoài kia cho java, nhưng cái gì được công nhận là khung lựa chọn ngày nay?

Sau đây là sự hiểu biết của tôi về các khung khác nhau, xin vui lòng sửa cho tôi nếu tôi sai. Đây là một bộ câu hỏi được xác định rất lỏng lẻo, nhưng tôi vẫn nghĩ nó có giá trị cho bất cứ ai nghĩ đến việc tạo ra các ứng dụng gui phong phú.


AWT

Là nền tảng của swing, nó hoạt động tốt nhưng thiếu các thành phần tiên tiến. Nếu bạn có ý định tạo ra các ứng dụng phong phú, AWT có lẽ không phải là hướng đi. Tuy nhiên, đối với các ứng dụng gui nhỏ hơn không yêu cầu giao diện người dùng phong phú. Điều này có thể phù hợp hoàn hảo vì nó là một khuôn khổ đã được thử nghiệm và đã được chứng minh.


Lung lay

Dựa trên AWT như đã nêu trước đây. Thời kỳ đầu, nó được coi là chậm và có lỗi và khiến IBM tạo SWT cho Eclipse. Tuy nhiên, với Java 5 (hoặc 6?), Swing trở thành khung lựa chọn để xây dựng các ứng dụng mới. Swing có rất nhiều thành phần phong phú nhưng vẫn còn thiếu ở một số lĩnh vực. Một ví dụ là không có thành phần TreeTable đầy đủ tính năng có thể thực hiện sắp xếp và lọc / tìm kiếm.


SWT

Được tạo bởi IBM cho Eclipse, họ dường như nghĩ rằng Swing không phù hợp với Eclipse vào thời điểm đó. Bản thân nó là cấp độ khá thấp và nó sử dụng các tiện ích gốc của nền tảng thông qua JNI. Nó hoàn toàn không liên quan đến Swing và AWT. API của họ tuy nhiên hơi khó hiểu và không trực quan. Chúng có một số thành phần nâng cao giống như TreeTable. (nhưng tôi không nghĩ họ hỗ trợ sắp xếp và lọc ra khỏi hộp). SWT sử dụng một số ràng buộc riêng (thông qua JNI?) Và điều đáng nói trên internet là khung này không nên được sử dụng trong các dự án ngày nay. (tại sao không?)


Xích đu

Dựa trên Swing và nhiệm vụ của nó là tạo ra các thành phần phong phú cho swing. Vẫn đang được phát triển. (mặc dù không hoạt động lắm.) Có một bộ các thành phần rất đẹp, ví dụ như TreeTable. Nhưng TreeTable không hỗ trợ lọc và sắp xếp theo như tôi biết. Tuy nhiên, nó hỗ trợ tìm kiếm với đánh dấu.

Lưu ý rằng SwingX là các thành phần (AFAIU) là phần mở rộng hoặc thành phần của các thành phần Xoay hiện có


Joodies

Một khuôn khổ mà tôi không biết gì về ... Điểm mạnh và điểm yếu của nó là gì? Những gì Jgoodies thiết lập ngoài phần còn lại?

Joodies OTOH là về PLAFs và bố trí.


JavaFX

Flagship mới nhất của Java / Oracle. hứa hẹn sẽ là tiêu chuẩn thực tế trong việc phát triển các ứng dụng web hoặc máy tính để bàn phong phú.


Trục xoay Apache

Nó kết xuất UI bằng Java2D, do đó giảm thiểu tác động của các di sản (IMO, cồng kềnh) của Swing và AWT. (@Augustus Thoo)

Trọng tâm chính của nó dường như tập trung vào RIA (Ứng dụng Internet phong phú), nhưng có vẻ như nó cũng có thể được áp dụng cho các ứng dụng máy tính để bàn. Và như một nhận xét cá nhân, Trông rất thú vị! Tôi đặc biệt thích đó là một dự án apache.

https://cwiki.apache.org/PIVOT/frequently-asked-questions-faq.html


Qt Jambi

Một trình bao bọc java cho thư viện qt riêng được viết bằng c / c ++. Rất mạnh mẽ, được sử dụng rộng rãi và được chấp nhận. Có rất nhiều thành phần GUI và API dễ sử dụng.

http://qt-jambi.org/


Vì vậy, để cố gắng tóm tắt một chút về những gì tôi đang hỏi:

Nói rằng tôi muốn tạo một ứng dụng máy tính để bàn ngày nay bằng Java bao gồm rất nhiều thành phần nâng cao, tôi nên chọn cái gì? Và tại sao?

Cái nào trong số những khung này nên được công nhận là không dùng nữa và cái nào nên được công nhận là khung của tương lai xa?

Khung tiêu chuẩn thực tế ngày nay là gì và bạn sử dụng công cụ nào để tạo các ứng dụng java gui?


Tôi có thể hối hận khi hỏi điều này, nhưng dù sao cũng nên thử:

C # /. Net được cho là có một bộ rất tốt các thành phần dễ sử dụng có thể uốn cong theo mọi hướng có thể. Và sau khi nghiên cứu các khung java khác nhau ở một mức độ nào đó, tôi dường như không thể nói giống nhau về Java. Tại sao lại thế này? Tại sao java (ngôn ngữ lập trình được sử dụng rộng rãi nhất trên thế giới) không có cùng bộ thành phần GUI?

Có phải java đã dựa trên các thành phần gui của họ ở mức độ thấp hơn nhiều và có thể viết tất cả các thành phần nâng cao này mà tôi đang tìm kiếm, nhưng bạn phải tự làm nhiều việc nếu không phải là tất cả công việc?


Tôi không biết rằng SWT là "dựa trên sự kết hợp giữa AWT và Swing". Đó thực sự là trường hợp? Tôi nghĩ rằng đó là JNI thuần túy để gọi hệ thống cửa sổ của HĐH ...
Rich

@Rich Oh, nó đã được nói trong một trong những câu trả lời bình luận. Tôi chỉ cho rằng họ biết những gì họ đang nói về.
netbrain

4
Tôi nghĩ bạn nhầm lẫn giữa "Bộ công cụ UI" và "Khung GUI". AWT, Swing và SWT là các bộ công cụ UI nhưng tôi chắc chắn sẽ không gọi chúng là "khung". Các khung dựa trên bộ công cụ UI cụ thể và cung cấp keo để xây dựng ứng dụng của bạn. Trước tiên, bạn nên chọn bộ công cụ UI và sau đó chọn một khung làm việc trên bộ công cụ đó. FWIW, tôi sẽ chọn Swing với khung Guts-GUI do chính tôi tạo ra :-)
jfpoilpret

1
Nó hầu như luôn luôn là Swing so với SWT (đối với tôi ít nhất), để so sánh nhỏ, bạn có thể kiểm tra những điều chính mà một lập trình viên Java SWT có kinh nghiệm nên biết khi chuyển sang Swing là gì? ..
phù thủy

2
JavaFX không còn là một phần của SDK xem trước và nó có sẵn để sử dụng Sản xuất. xin vui lòng cập nhật bài viết này.

Câu trả lời:


79

Cây quyết định:

  1. Các khung như Qt và SWT cần DLL gốc. Vì vậy, bạn phải tự hỏi: Có phải tất cả các nền tảng cần thiết được hỗ trợ? Bạn có thể đóng gói các DLL gốc với ứng dụng của bạn?

    Xem ở đây, làm thế nào để làm điều này cho SWT .

    Nếu bạn có lựa chọn ở đây, bạn nên chọn Qt hơn SWT. Qt đã được phát triển bởi những người hiểu UI và máy tính để bàn trong khi SWT đã được phát triển không cần thiết để làm cho Eclipse nhanh hơn. Đó là bản vá hiệu năng cho Java 1.4 hơn là khung UI. Không có JFace, bạn thiếu nhiều thành phần UI chính hoặc các tính năng rất quan trọng của các thành phần UI (như lọc trên bảng).

    Nếu SWT thiếu một tính năng mà bạn cần, khung công tác có phần thù địch với việc mở rộng nó. Ví dụ: bạn không thể mở rộng bất kỳ lớp nào trong đó (các lớp không phải là cuối cùng, họ chỉ đưa ra ngoại lệ khi gói this.getClass()không org.eclipse.swtvà bạn không thể thêm các lớp mới trong gói đó vì nó đã được ký).

  2. Nếu bạn cần một giải pháp Java thuần túy, nguyên bản, điều đó sẽ khiến bạn phải nghỉ ngơi. Hãy bắt đầu với AWT, Swing, SwingX - cách xoay.

    AWT đã lỗi thời. Swing đã lỗi thời (có thể ít hơn nhưng không có nhiều công việc đã được thực hiện trên Swing trong 10 năm qua). Bạn có thể lập luận rằng Swing là tốt để bắt đầu nhưng tất cả chúng ta đều biết rằng mã thối. Và điều đó đặc biệt đúng với các UI ngày nay.

    Điều đó để lại cho bạn với SwingX. Sau một thời gian dài chậm tiến độ, sự phát triển đã trở lại . Hạn chế lớn với Swing là nó bám vào một số ý tưởng cũ rất hay bị chảy máu cách đây 15 năm nhưng lại cảm thấy "vụng về" ngày nay. Ví dụ: các khung nhìn bảng hỗ trợ lọc và sắp xếp nhưng bạn vẫn phải định cấu hình này. Bạn sẽ phải viết rất nhiều mã tấm nồi hơi chỉ để có được một giao diện người dùng phong nha mà cảm thấy hiện đại.

    Một khu vực yếu khác là theo chủ đề. Cho đến hôm nay, có rất nhiều chủ đề xung quanh. Xem ở đây cho một top 10 . Nhưng một số chậm, một số lỗi, một số không đầy đủ. Tôi ghét nó khi tôi viết UI và người dùng phàn nàn rằng cái gì đó không phù hợp với họ vì họ đã chọn một chủ đề kỳ lạ.

  3. Joodies là một lớp khác trên đỉnh của Swing, giống như SwingX. Nó cố gắng để làm cho Swing dễ chịu hơn để sử dụng. Các trang web trông tuyệt vời. Chúng ta hãy xem hướng dẫn ... hm ... vẫn đang tìm kiếm ... chờ đợi. Có vẻ như không có tài liệu nào trên trang web cả. Google để giải cứu . Không, không có hướng dẫn hữu ích nào cả.

    Tôi không cảm thấy tự tin với khung UI cố gắng hết sức để che giấu tài liệu khỏi những người hâm mộ mới tiềm năng. Điều đó không có nghĩa là Joodies là xấu; Tôi không thể tìm thấy bất cứ điều gì tốt để nói về nó nhưng nó có vẻ tốt.

  4. JavaFX. Tuyệt vời, sành điệu. Có hỗ trợ nhưng tôi cảm thấy nó giống một món đồ chơi sáng bóng hơn là một khung UI nghiêm túc. Cảm giác này bắt nguồn từ việc thiếu các thành phần UI phức tạp như bảng cây. Có một thành phần dựa trên webkit để hiển thị HTML .

    Khi được giới thiệu, suy nghĩ đầu tiên của tôi là "năm năm quá muộn". Nếu mục tiêu của bạn là một ứng dụng đẹp cho điện thoại hoặc trang web, tốt. Nếu mục đích của bạn là ứng dụng máy tính để bàn chuyên nghiệp, hãy chắc chắn rằng nó cung cấp những gì bạn cần.

  5. Trục. Lần đầu tiên tôi nghe về nó. Về cơ bản, nó là một khung UI mới dựa trên Java2D. Vì vậy, tôi đã thử nó ngày hôm qua. Không có swing, chỉ là một chút nhỏ của AWT ( new Font(...)).

    Ấn tượng đầu tiên của tôi là một trong những tốt đẹp. Có một tài liệu phong phú giúp bạn bắt đầu. Hầu hết các ví dụ đều có bản demo trực tiếp (Lưu ý: Bạn phải bật Java trong trình duyệt web; đây là rủi ro bảo mật ) trong trang web, do đó bạn có thể thấy mã và ứng dụng kết quả cạnh nhau.

    Theo kinh nghiệm của tôi, nhiều nỗ lực đi vào mã hơn là vào tài liệu. Bằng cách xem xét các tài liệu Pivot, rất nhiều nỗ lực đã phải đi vào mã. Lưu ý rằng hiện tại có một lỗi ngăn một số ví dụ hoạt động ( PIVOT-858 ) trong trình duyệt của bạn.

    Ấn tượng thứ hai của tôi về Pivot là nó dễ sử dụng. Khi tôi gặp phải một vấn đề, tôi thường có thể giải quyết nó nhanh chóng bằng cách xem xét một ví dụ. Mặc dù vậy, tôi đang thiếu một tài liệu tham khảo về tất cả các kiểu mà mỗi thành phần hỗ trợ.

    Như với JavaFX, nó thiếu một số thành phần cấp cao hơn như thành phần bảng cây ( PIVOT-306 ). Tôi đã không thử tải lười biếng với chế độ xem bảng. Ấn tượng của tôi là nếu mô hình cơ bản sử dụng tải lười biếng, vậy là đủ.

    Hứa hẹn. Nếu bạn có thể, hãy thử xem.


Đã thử bản demo Pivot "Kitchen chìm", sau khi mở một số nhóm, nó tiếp tục ăn toàn bộ CPU. Nếu đó là vì thiết kế Pivot, thì tôi chắc chắn không muốn nó trong các dự án của mình.
Tên hiển thị

Có vẻ như tôi đã tìm thấy nguồn gốc của sự cố và nó đã được sửa trong các phiên bản sau: apache-pOLL-users.399431.n3.nabble.com/ Thẻ
Tên hiển thị

2
JavaFX 8 (dành cho Java 8 trở lên) có tiện ích TreeTableView. Tuy nhiên, JavaFX 2.2 (đối với Java 7) thiếu điều này và cũng thiếu các dialgos thông tin và lỗi tiêu chuẩn: xem stackoverflow.com/a/12760202/105137 . Ngoài ra, thư viện tiện ích ControlsFX chỉ có sẵn cho Java 8: fxexperience.com/controlsfx
kostmo

12

Bản thân SWT ở mức khá thấp và nó sử dụng các tiện ích gốc của nền tảng thông qua JNI. Nó hoàn toàn không liên quan đến Swing và AWT. Các Eclipse IDE và tất cả các ứng dụng khách hàng giàu dựa trên Eclipse, giống như khách hàng Vuze BitTorrent , được xây dựng sử dụng SWT. Ngoài ra, nếu bạn đang phát triển các trình cắm thêm Eclipse, thông thường bạn sẽ sử dụng SWT.
Tôi đã phát triển các ứng dụng và plugin dựa trên Eclipse được gần 5 năm rồi, vì vậy tôi rõ ràng bị thiên vị. Tuy nhiên, tôi cũng có nhiều kinh nghiệm làm việc với SWT và bộ công cụ UI của JFace, được xây dựng trên đầu trang của nó. Tôi đã tìm thấy JFace rất giàu có và quyền lực; trong một số trường hợp, nó thậm chí có thể là lý do chính để chọn SWT. Nó cho phép bạn hoàn thành giao diện người dùng hoạt động khá nhanh, miễn là nó giống như IDE (với bảng, cây, điều khiển gốc, v.v.). Tất nhiên bạn cũng có thể tích hợp các điều khiển tùy chỉnh của mình, nhưng điều đó cần thêm một số nỗ lực.


Theo ý kiến ​​của bạn, một thành phần nâng cao như TreeTable với sắp xếp và lọc cột có phải là vấn đề lớn với SWT + JFace không?
netbrain

@netbrain: Tôi đã làm điều đó rất nhiều lần, nó khá đơn giản với JFace. Đây là những gì tôi muốn nói bởi giao diện "giống như IDE", có thể không phải là lựa chọn tốt nhất cho các từ.
Zsolt Török

9

Tôi muốn đề xuất một khung công tác khác: Apache Pivot http://pOLL.apache.org/ .

Tôi đã thử nó một thời gian ngắn và bị ấn tượng bởi những gì nó có thể cung cấp dưới dạng RIA (Ứng dụng Internet phong phú) ala Flash.

Nó kết xuất UI bằng Java2D, do đó giảm thiểu tác động của các di sản (IMO, cồng kềnh) của Swing và AWT.


1
Tôi có ấn tượng rằng netbrain đã hỏi về các ứng dụng máy tính để bàn. Đối với các khung RIA, hãy xem xét cả GWT và Vaadin. Các khung này cho phép bạn viết bằng Java, biên dịch và nhận JavaScript chạy rất tốt trên tất cả các trình duyệt web phổ biến.
Costis Aivalis

Trục không thể được áp dụng cho các ứng dụng máy tính để bàn?
netbrain

Có thể đó là vấn đề định nghĩa, nhưng khung RIA về cơ bản được thiết kế để chạy trong trình duyệt.
Costis Aivalis

2
@netbrain: Có, bạn có thể chạy Pivot dưới dạng ứng dụng máy tính để bàn (JFrame) hoặc applet (JApplet).
Augustus Thoo

9

Swing + SwingX + Miglayout là sự kết hợp lựa chọn của tôi. Miglayout đơn giản hơn nhiều so với Swings nhận thấy 200 trình quản lý bố cục khác nhau và mạnh mẽ hơn nhiều. Ngoài ra, nó cung cấp cho bạn khả năng "gỡ lỗi" bố cục của bạn, đặc biệt tiện dụng khi tạo bố cục phức tạp.


8

Một lựa chọn khác là sử dụng Qt Jambi . Nó có gần như tất cả sự tuyệt vời của Qt (nhiều thành phần, tài liệu tốt, dễ sử dụng), mà không gặp rắc rối với C ++. Tôi đã sử dụng nó 3-4 năm trước cho một dự án nhỏ, thậm chí sau đó nó gần như đã trưởng thành.

Bạn có thể muốn xem các cuộc thảo luận về Swing so với Qt ở đây .


5

Ý kiến ​​cá nhân của tôi: Hãy tham gia cùng với nền tảng NetBeans.

Nếu bạn cần các thành phần nâng cao (nhiều hơn NetBeans cung cấp), bạn có thể dễ dàng tích hợp SwingX mà không gặp sự cố (hoặc Joodies) vì nền tảng NetBeans hoàn toàn dựa trên Swing.

Tôi sẽ không bắt đầu một ứng dụng máy tính để bàn lớn (hoặc một ứng dụng sẽ lớn) nếu không có một nền tảng tốt được xây dựng dựa trên khung UI bên dưới.

Tùy chọn khác là SWT cùng với RCP Eclipse, nhưng khó hơn (mặc dù không phải là không thể) để tích hợp các thành phần Swing "thuần túy" vào một ứng dụng như vậy.

Đường cong học tập hơi dốc đối với nền tảng NetBeans (mặc dù tôi đoán điều đó cũng đúng với Eclipse) nhưng có một số cuốn sách hay xung quanh mà tôi rất muốn giới thiệu.


1
Lưu ý rằng SwingX là các thành phần (AFAIU) là phần mở rộng hoặc thành phần của các thành phần Xoay hiện có. Joodies OTOH là về PLAFs và bố trí. Nhưng như bạn đã nói, hoặc sẽ tích hợp hoàn hảo với Swing.
Andrew Thompson

1
+1 Dựa trên sự phát triển của bạn trên Swing. Swing được xây dựng trên đỉnh AWT và bao gồm các thành phần trọng lượng nhẹ trông và hoạt động giống nhau trên tất cả các nền tảng, vì vậy bạn không bao giờ nên sử dụng trực tiếp các thành phần AWT. Có một số lượng lớn Đậu xuất sắc mà bạn có thể dễ dàng thêm vào GUI phát triển của mình, ví dụ như toedter.com JCalWiki.
Costis Aivalis

1
@Andrew ngoài PLAF và bố cục, Joodies cung cấp nhiều hơn: ràng buộc đậu (cho mẫu mô hình trình bày), xác thực và khung "giống như JSR-296" (cái đó là thương mại).
jfpoilpret

3

bạn đã quên ứng dụng Java Desktop dựa trên JSR296 dưới dạng Swing Framework tích hợp trong NetBeans

ngoại trừ AWT và JavaFX là tất cả các khung công tác được mô tả của bạn dựa trên Swing, nếu bạn bắt đầu với Swing thì bạn sẽ hiểu (rõ ràng) cho tất cả các Khung này (Khung dựa trên)

ATW, SWT (Eclipse), Ứng dụng máy tính để bàn Java (Netbeans), SwingX, Joodies

tất cả đều có khung (tôi không biết gì thêm về Joodies). Đã lâu rồi JavaFX không có bất kỳ tiến triển nào, rất nhiều Khung dựa trên Swing bị dừng lại, nếu không thì không có phiên bản mới nhất

theo quan điểm của tôi - tốt nhất trong số họ là SwingX, nhưng đòi hỏi kiến ​​thức sâu sắc nhất về Swing,

Nhìn và cảm nhận các khung dựa trên Swing


một phần của chúng trên các Thành phần AWT, một phần trên Swing JCompoentns, nhưng giữa AWT và Swing là khác biệt với các phương thức được triển khai, có thể truy cập và kế thừa, ví dụ: Swing JComponents trực tiếp thực hiện rất nhiều phương thức kế thừa hoặc lồng nhau trực tiếp từ AWT :-)
mKorbel

JSR296 đã chết. Nó không còn được "duy trì" và hỗ trợ cho nó đã bị xóa khỏi NetBeans. (Và nó chưa bao giờ là một khung thực sự tốt để bắt đầu)
a_horse_with_no_name

@a_horse_with_no_name ngay with same progresstrong SWT, SwingX, chủ sở hữu mới, thợ sửa chữa mới
mKorbel

1
SWT, được phát triển bởi IBM, không dựa trên Swing, đây là / là một công nghệ cạnh tranh. Xích đu sử dụng AWT. JavaFX cũng không dựa trên Swing. Đó là một khuôn khổ hoàn toàn mới. Một số người gọi nó là sự kế thừa cho Swing, nhưng vẫn còn quá non nớt để gọi trận chiến đó. Tôi đang đưa ra quyết định chính xác vào lúc này và Swing là ứng cử viên của tôi, đơn giản vì thực tế đó là lựa chọn trưởng thành nhất nhưng thực tế nhất hiện có.
Gordon

1
SwingX là phần mở rộng của Swing (đó là lý do tại sao nó đòi hỏi kiến ​​thức về Swing), trên thực tế, một số tính năng của SwingX đã được đưa vào chính Swing.
Gordon

3

Tôi đã khá hài lòng với Swing cho các ứng dụng máy tính để bàn mà tôi đã tham gia. Tuy nhiên, tôi chia sẻ quan điểm của bạn về Swing không cung cấp các thành phần nâng cao. Những gì tôi đã làm trong những trường hợp này là đi cho JIDE. Nó không miễn phí, nhưng cũng không quá đắt và nó cung cấp cho bạn nhiều công cụ hơn trong vành đai của bạn. Cụ thể, họ cung cấp một TreeTable có thể lọc.


Tốt để biết! Vì vậy, JIDE đã tạo ra các thành phần của riêng họ dựa trên ...
netbrain

Có, JIDE đã tạo ra khá nhiều thành phần bao gồm lưới, cây, bảng, biểu đồ và những thứ tương tự. Như tôi đã nói, nó không miễn phí nhưng đã dành thời gian để tự mình làm những thứ này, có lẽ bạn nên sử dụng thứ gì đó đã được tạo ra. Hơn nữa, theo như tôi hiểu, JIDE linh hoạt trong việc cho phép các dự án nguồn mở sử dụng các thành phần của chúng để đổi lấy một liên kết đến trang web của họ hoặc logo trong hộp thoại 'Giới thiệu'.
sbrattla

3

Tôi sẽ đi với Swing. Để bố trí tôi sẽ sử dụng bố cục mẫu Joodies. Đáng để nghiên cứu sách trắng về Bố cục biểu mẫu tại đây - http://www.jgoodies.com/freeware/forms/

Ngoài ra nếu bạn định bắt đầu phát triển một ứng dụng máy tính để bàn khổng lồ, bạn chắc chắn sẽ cần một khung. Những người khác đã chỉ ra khuôn khổ netbeans. Tôi không thích nó lắm nên đã viết một cái mới mà bây giờ chúng tôi sử dụng trong công ty của tôi. Tôi đã đặt nó lên sourceforge, nhưng không tìm thấy thời gian để ghi chép lại nhiều. Đây là liên kết để duyệt mã:

http://swingobj.svn.sourceforge.net/viewvc/swingobj/

Showcase sẽ cho bạn thấy làm thế nào để đăng nhập đơn giản thực sự ..

Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nào về nó tôi có thể giúp đỡ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.