Giới thiệu
Từ phiên bản 1.5, có thể thêm các tính năng mới vào Sweet Home 3D với các tệp plug-in đặt trong thư mục plug-ins của bạn. Điều này cho phép các lập trình viên Java phát triển và phân phối các tính năng mới cho Sweet Home 3D mà không cần sửa đổi các tệp nguồn của phiên bản hiện tại (điều này tốt cho khả năng tương thích lên trên), và không cần cung cấp một phiên bản đầy đủ của chương trình (điều này tốt cho kích thước phân phối).
Tài liệu này mô tả các công cụ cần thiết để tạo plug-in, sau đó chỉ ra cách lập trình một plug-in tính toán thể tích tối đa của đồ nội thất có thể di chuyển được thêm vào nhà, và cuối cùng cung cấp một số thông tin bổ sung sẽ giúp bạn tiến xa hơn.
Cài đặt công cụ phát triển
Nếu Sweet Home 3D hướng đến đối tượng chung, phát triển plug-in đòi hỏi kỹ năng đặc biệt, và bạn nên biết cách lập trình trong Java với một IDE trước khi tiến xa hơn. Hướng dẫn này chỉ ra cách xây dựng một plug-in với Eclipse, nhưng bạn có thể sử dụng IDE mà bạn chọn, hoặc không cần IDE nào cả.
Tải xuống và cài đặt Eclipse
Trước tiên, tải xuống Eclipse từ https://www.eclipse.org/. Phiên bản có tên Eclipse IDE for Java Developers là đủ để phát triển một plug-in, nhưng bạn có thể tải xuống bất kỳ phiên bản nào cho phát triển Java.
Sau khi tải xuống, cài đặt Eclipse rất đơn giản: chỉ cần giải nén tệp lưu trữ bạn sẽ nhận được, mở thư mục eclipse và tùy thuộc vào hệ thống của bạn, chạy tệp có tên eclipse.exe (trên Windows), eclipse.app (trên Mac OS X) hoặc eclipse (trên Linux).
Lần đầu tiên chạy, Eclipse sẽ yêu cầu bạn chọn một thư mục workspace, nơi sẽ lưu trữ các dự án plug-in.
Sau khi hoàn tất, chọn File > New > Project từ menu để tạo một dự án mới, chọn Java > Java project trong trình hướng dẫn New project sẽ được hiển thị, nhập VolumePlugin làm tên dự án và nhấp vào nút Finish. Cuối cùng, đóng tab Welcome để khám phá workspace của bạn như được hiển thị trong hình 1.

Tải xuống và cài đặt thư viện Sweet Home 3D
Việc phát triển một plug-in dựa trên một số lớp của Sweet Home 3D mà Eclipse phải biết để có thể xây dựng dự án của bạn. Cách dễ nhất để thêm các lớp Sweet Home 3D vào Eclipse là tải xuống phiên bản JAR thực thi của Sweet Home 3D có sẵn tại https://sourceforge.net/projects/sweethome3d/files/SweetHome3D/SweetHome3D-7.5/SweetHome3D-7.5.jar/download. Sau khi tải xuống, kéo và thả tệp SweetHome3D-7.5.jar vào biểu tượng dự án VolumePlugin trong chế độ xem Package Explorer của Eclipse, và chọn mục Build Path > Add to Build Path trong menu ngữ cảnh của tệp SweetHome3D-7.5.jar, như được hiển thị trong hình 2.

vào Build Path
Lập trình một plug-in
Bây giờ bạn đã cài đặt các công cụ cần thiết, hãy xem cách bạn có thể lập trình plug-in đầu tiên của mình cho Sweet Home 3D.
Tạo lớp plug-in
Đầu tiên, tạo một lớp con mới của com.eteks.sweethome3d.plugin.Plugin bằng cách chọn mục menu File > New > Class trong Eclipse.

Trong hộp thoại New Java Class, nhập VolumePlugin làm tên lớp, nhập một gói (ở đây gói được chọn là com.eteks.test), và chọn com.eteks.sweethome3d.plugin.Plugin làm lớp cha của VolumePlugin. Sau khi hoàn tất, nhấp vào Finish. Eclipse sẽ tạo tệp của lớp mới với nội dung sau:
package com.eteks.test;
import com.eteks.sweethome3d.plugin.Plugin;
import com.eteks.sweethome3d.plugin.PluginAction;
public class VolumePlugin extends Plugin {
@Override
public PluginAction[] getActions() {
// TODO Auto-generated method stub
return null;
}
}
Như bạn có thể đoán từ nhận xét TODO, bạn phải thay đổi việc triển khai phương thức getActions để trả về một hành động plug-in có thể tính toán thể tích của đồ nội thất có thể di chuyển. Thay thế return null; bằng câu lệnh sau:
return new PluginAction [] {new VolumeAction()};
và chọn Edition > Quick Fix từ menu Eclipse để tạo lớp VolumeAction bị thiếu, như được hiển thị trong hình 4.

Trong hộp thoại New Java Class xuất hiện, chọn hộp kiểm Enclosing type để tạo một lớp bên trong của VolumePlugin và nhấp vào Finish. Điều này sẽ tạo lớp VolumeAction kế thừa từ lớp com.eteks.sweethome3d.plugin.PluginAction và chứa một phương thức execute trống:
public class VolumeAction extends PluginAction {
@Override
public void execute() {
// TODO Auto-generated method stub
}
}
Phương thức này là phương thức mà Sweet Home 3D sẽ gọi khi người dùng khởi chạy hành động plug-in; do đó đây là nơi bạn phải triển khai cách tính toán thể tích của đồ nội thất và hiển thị nó:
public class VolumeAction extends PluginAction {
@Override
public void execute() {
float volumeInCm3 = 0;
// Tính tổng thể tích của hộp bao quanh của
// mỗi mảnh đồ nội thất có thể di chuyển trong nhà
for (PieceOfFurniture piece : getHome(). getFurniture()) {
if (piece. isMovable()) {
volumeInCm3 += piece. getWidth()
* piece. getDepth()
* piece. getHeight();
}
}
// Hiển thị kết quả trong một hộp thông báo (³ là số 3 ở dạng siêu ký tự)
String message = String. format(
"Thể tích tối đa của đồ nội thất có thể di chuyển trong nhà là %.2f m³.",
volumeInCm3 / 1000000);
JOptionPane. showMessageDialog(null, message);
}
}
Bây giờ bạn đã xác định những gì bạn muốn plug-in thực hiện, bạn phải mô tả cách người dùng sẽ khởi chạy hành động mới này. Bạn có thể chọn thêm một mục menu mới vào một menu, và/hoặc một nút mới vào thanh công cụ. Lựa chọn này được thực hiện bằng cách thiết lập các thuộc tính thích hợp của hành động plug-in khi tạo ra nó. Ví dụ, nếu bạn muốn người dùng khởi chạy hành động thể tích với mục menu Compute volume được tìm thấy trong menu Tools, bạn sẽ thêm hàm tạo sau vào lớp VolumnAction:
public VolumeAction() {
putPropertyValue(Property.NAME, "Compute volume");
putPropertyValue(Property.MENU, "Tools");
// Kích hoạt hành động theo mặc định
setEnabled(true);
}
Lớp plug-in VolumePlugin bây giờ đã được lập trình, và gần như sẵn sàng hoạt động như một plug-in trong Sweet Home 3D. Hai điều cuối cùng cần làm là:
- tạo một tệp mô tả ApplicationPlugin.properties,
- đặt các tệp lại với nhau trong một tệp JAR.
Tạo tệp mô tả plug-in
Một tệp ApplicationPlugin.properties mô tả tên plug-in, lớp của nó, các phiên bản tối thiểu của Sweet Home 3D và Java mà nó được hỗ trợ, và các vấn đề pháp lý. Chọn File > New > File từ menu Eclipse, nhập tên tệp ApplicationPlugin.properties và nhấp vào Finish, như được hiển thị trong hình 5.

Sau đó nhập mô tả sau vào tệp mới và lưu lại:
name=Thể tích đồ nội thất có thể di chuyển
class=com.eteks.test.VolumePlugin
description=Tính toán thể tích của đồ nội thất có thể di chuyển trong nhà
version=1.0
license=GNU GPL
provider=(C) Bản quyền 2024 Space Mushrooms
applicationMinimumVersion=1.5
javaMinimumVersion=1.5
Tạo tệp JAR plug-in
Tệp JAR plug-in chứa các tệp class được tạo từ việc biên dịch tệp VolumePlugin.java, và tệp ApplicationPlugin.properties. Vì Eclipse biên dịch một tệp Java ngay khi bạn lưu nó, bạn chỉ cần chọn File > Export… từ menu và chọn Java > JAR file trong hộp thoại Export sẽ được hiển thị. Trong trình hướng dẫn Jar Export xuất hiện như được hiển thị trong hình 6, chọn hộp kiểm dự án và nhập đường dẫn của một tệp JAR đặt trong thư mục plug-ins của Sweet Home 3D. Thư mục thích hợp này phụ thuộc vào hệ thống của bạn như sau:
- trên Windows Vista / 7 / 8 / 10 / 11, thư mục này là C:\Users\user\AppData\Roaming\eTeks\Sweet Home 3D\plugins,
- trên Windows XP và các phiên bản Windows trước đó, thư mục này là C:\Documents and Settings\user\Application Data\eTeks\Sweet Home 3D\plugins,
- trên macOS, nó là thư mục con Library/Application Support/eTeks/Sweet Home 3D/plugins của thư mục người dùng của bạn,
- trên Linux và các Unix khác, nó là thư mục con .eteks/sweethome3d/plugins của thư mục người dùng của bạn.

Kiểm tra plug-in
Plug-in bạn phát triển sẽ chạy trong Sweet Home 3D, hoặc với phiên bản plug-in, phiên bản Java Web Start, hoặc phiên bản installers hoặc SweetHome3D-7.5.jar bạn đã tải xuống trước đó. Vì cái cuối cùng là một JAR thực thi, bạn có thể chạy nó bằng cách nhấp đúp vào nó hoặc với lệnh sau:
Plug-in bạn phát triển sẽ chạy trong Sweet Home 3D, hoặc với phiên bản plug-in, phiên bản Java Web Start, hoặc phiên bản installers hoặc SweetHome3D-7.5.jar bạn đã tải xuống trước đó. Vì cái cuối cùng là một JAR thực thi, bạn có thể chạy nó bằng cách nhấp đúp vào nó hoặc với lệnh sau:
java -jar /path/to/SweetHome3D-7.5.jar
Miễn là bạn đang thử nghiệm, bạn có thể thích chạy Sweet Home 3D với lệnh này, để có thể đọc trong bảng điều khiển dấu vết ngăn xếp của các ngoại lệ được ném ra trong quá trình thực thi plug-in của bạn.
Khi Sweet Home 3D được khởi chạy, bạn sẽ thấy menu mới và mục của nó xuất hiện như được hiển thị trong hình 7:

Nếu bạn chọn mục menu mới cho ví dụ nhà được tạo trong hướng dẫn người dùng, bạn sẽ nhận được kết quả sau:

Gỡ lỗi plug-in
Nếu bạn cần gỡ lỗi plug-in của mình từ Eclipse, hãy tạo một cấu hình gỡ lỗi bằng cách làm theo các bước sau:
- Chọn Run > Debug Configurations… từ menu, chọn mục Java Application trong danh sách cấu hình có sẵn của hộp thoại Debug configurations, nhấp vào nút New ở góc trên bên trái và nhập tên cho cấu hình.
- Nhấp vào nút Search… ở bên phải trường văn bản Main class và nhấp đúp vào lớp SweetHome3DBootstrap
trong số các lớp được đề xuất.

- Nhấp vào tab Classpath, chọn mục con VolumePlugin (classpath mặc định) của mục User Entries trong danh sách Classpath và nhấp vào nút Remove.
- Nhấp vào mục User Entries trong danh sách Classpath, nhấp vào nút Add JARs…, chọn mục SweetHome3D-7.5.jar và xác nhận lựa chọn của bạn.

- Chọn tab Source, nhấp vào nút Add…, nhấp đúp vào mục Java Project trong hộp thoại Add Source, chọn mục VolumePlugin trong cửa sổ bật lên Project Selection và xác nhận lựa chọn của bạn.

- Cuối cùng, nhấp vào nút Debug để khởi chạy Sweet Home 3D ở chế độ gỡ lỗi. Khi chương trình đang chạy, mở tệp VolumePlugin.java, đặt một điểm dừng trong phương thức execute và chọn Tools > Compute volume từ menu Sweet Home 3D. Eclipse sẽ dừng lại ở điểm dừng đã chọn để bạn có thể thực hiện chương trình từng bước và kiểm tra giá trị biến.


Mỗi khi bạn sửa đổi mã nguồn của plug-in, đừng quên tạo JAR plug-in trước khi khởi chạy cấu hình gỡ lỗi mà bạn đã tạo. Để tăng tốc quá trình xuất JAR trong eclipse, hãy chuyển đến bước thứ hai của trình hướng dẫn xuất JAR và chọn tùy chọn Lưu mô tả của JAR này trong không gian làm việc. Điều này sẽ thêm một mục mới trong dự án với một mục menu ngữ cảnh Create JAR.
Triển khai plug-in
Khi đã sẵn sàng, plug-in của bạn có thể được triển khai trên máy tính của người dùng Sweet Home 3D khác bằng cách đơn giản sao chép nó vào thư mục plug-ins của họ. Từ phiên bản 1.6, một tệp plug-in cũng có thể được cài đặt trong thư mục plug-ins của Sweet Home 3D bằng cách nhấp đúp vào nó, nếu phần mở rộng của nó là SH3P (chỉ cần đổi phần mở rộng tệp từ .zip thành .sh3p). Nếu nhấp đúp vào tệp .sh3p không khởi chạy Sweet Home 3D (phần lớn khả năng dưới Linux), bạn cũng có thể cài đặt một plug-in với lệnh sau trong cửa sổ Terminal (nơi SweetHome3D là tên của tệp thực thi được cung cấp với các trình cài đặt Sweet Home 3D):
/path/to/SweetHome3D /path/to/plugin.sh3p
Để ngừng sử dụng một plug-in, hãy xóa tệp của nó khỏi thư mục plug-ins và khởi động lại Sweet Home 3D.

Nếu bạn muốn plug-in của mình có thể chạy với tất cả các trình cài đặt Sweet Home 3D có sẵn trên trang web này, hãy chú ý giữ cho nó tương thích với Java 5, bằng cách chọn 1.5 trong trường Compiler compliance level có sẵn trong phần Java Compiler của hộp thoại được hiển thị bởi mục menu Project > Properties của Eclipse.
Nếu bạn sử dụng phiên bản trình biên dịch Java mà tính tương thích với Java 1.5 không còn khả dụng nữa, hãy cố gắng nhắm mục tiêu ít nhất Java 1.8 vẫn được sử dụng trong các phiên bản gần đây của Sweet Home 3D và đặt javaMinimumVersion trong tệp ApplicationPlugin.properties của plug-in của bạn tương ứng.
Đi xa hơn
Việc lập trình plug-in đầu tiên đã cho bạn thấy bức tranh lớn. Dưới đây là một số thông tin bổ sung sẽ giúp bạn đi xa hơn.
Sweet Home 3D API – Javadoc
Tài liệu hữu ích nhất để phát triển một plug-in mới là Sweet Home 3D API (Giao diện Lập trình Ứng dụng), được tạo ra với công cụ javadoc.
Chỉ sử dụng các lớp của các gói com.eteks.sweethome3d.plugin, com.eteks.sweethome3d.model, com.eteks.sweethome3d.tools và com.eteks.sweethome3d.viewcontroller trong plug-in của bạn nếu bạn muốn nó tương thích với các phiên bản tương lai của Sweet Home 3D. Điều này sẽ đủ lớn để lập trình bất kỳ plug-in nào hoạt động trên dữ liệu nhà có sẵn trong Sweet Home 3D.
Các gói phù hợp với các lớp khác của chương trình được bao gồm trong Javadoc chỉ để tham khảo thông tin. Đừng dựa vào API của chúng, vì nó có thể vẫn thay đổi trong tương lai mà không có đảm bảo về tính tương thích ngược (dù sao bạn cũng sẽ không thấy tham chiếu nào đến một lớp của các gói com.eteks.sweethome3d.swing, com.eteks.sweethome3d.j3d, com.eteks.sweethome3d.io hoặc com.eteks.sweethome3d trong các gói đã đề cập ở trên).
Kiến trúc các lớp Model
Sweet Home 3D dựa trên kiến trúc MVC (Model View Controller), vì vậy hiểu cách tổ chức lớp Model của nó là rất quan trọng. Hình 13 (cũng có sẵn ở định dạng PDF) trình bày gần như tất cả các lớp và giao diện có sẵn trong phiên bản 1.5 của gói com.eteks.sweethome3d.model phù hợp với lớp Model này.
[uml_diagram slug=”model-classes-diagram” map_name=”model-classes-diagram” caption=”Figure 13. UML diagram of com.eteks.sweethome3d.model package” caption_small=”(click on a class to view its javadoc)”]
Lớp trung tâm trong lớp Model là lớp HomeApplication (10), lớp siêu trừu tượng của lớp chính ứng dụng SweetHome3D. Thể hiện của lớp này cung cấp quyền truy cập vào các thể hiện Home (7) hiện đang được chỉnh sửa, và đối tượng UserPreferences (11) lưu trữ đơn vị đo lường chiều dài đang sử dụng (12), danh mục nội thất (14) và danh mục kết cấu (15) từ đó người dùng chọn các món nội thất (17) và kết cấu (18).
Một thể hiện Home (7) lưu trữ tất cả các đối tượng mà người dùng đã tạo trong kế hoạch nhà:
- danh sách các đối tượng HomePieceOfFurniture (13) thực hiện giao diện PieceOfFurniture (16),
- bộ sưu tập các đối tượng Wall (9),
- danh sách các đối tượng Room (5),
- bộ sưu tập các đối tượng DimensionLine (2),
- bộ sưu tập các đối tượng Label (3).
Các đối tượng này thực hiện giao diện Selectable (1) cũng như đối tượng ObserverCamera (4), lưu trữ vị trí của máy ảnh trong chế độ Virtual visitor. Tất cả thông tin bên ngoài được quản lý bởi các đối tượng Model, như biểu tượng và mô hình 3D của một món nội thất (16), hoặc hình ảnh của một kết cấu (20) được truy cập thông qua giao diện Content (19), được thực hiện bởi lớp URLContent và các lớp khác của gói com.eteks.sweethome3d.tools.
Sơ đồ UML này sẽ giúp bạn hiểu các lớp nào có sẵn trong mô hình Sweet Home 3D và cách bạn có thể truy cập chúng, nhưng bạn có thể nhận thấy rằng không có nhà tạo lập và không có bộ thay đổi (hoặc bộ thiết lập nếu bạn thích) nào được đề cập trong đó. Đó chỉ là do thiếu không gian nhưng bạn có thể sử dụng chúng mà không gặp vấn đề gì trong một lớp plug-in. Cũng lưu ý rằng bất kỳ sửa đổi nào của một đối tượng hiện có của mô hình sẽ được thông báo cho các thành phần hiển thị hoặc với PropertyChangeEvents, với CollectionEvents (8) hoặc với SelectionEvents (6), do đó cho phép tất cả các thay đổi được phản ánh ngay lập tức trên màn hình.
Kiến trúc các lớp plug-in
Kiến trúc của các lớp plug-in dễ hiểu hơn nhiều so với lớp Model. Gói com.eteks.sweethome3d.plugin chỉ chứa ba lớp trong đó bạn được cho là chỉ sử dụng các lớp Plugin và PluginAction, như được hiển thị trong hình 14 (cũng có sẵn ở định dạng PDF).
[uml_diagram slug=”plugin-classes-diagram” map_name=”plugin-classes-diagram” caption=”Figure 14. UML diagram of com.eteks.sweethome3d.plugin package” caption_small=”(click on a class to view its javadoc)”]
Một thể hiện PluginManager (1) được tạo ra khi khởi động ứng dụng và tìm kiếm các plug-in được cài đặt trong thư mục plug-ins của người dùng. Mỗi khi một ngôi nhà mới được chỉnh sửa, trình quản lý này sẽ khởi tạo và cấu hình một đối tượng Plugin (3) cho mỗi plug-in được tìm thấy khi khởi động. Sau đó, nó gọi phương thức getActions để truy xuất tất cả các hành động (4) sẽ được thêm làm mục menu và/hoặc nút thanh công cụ trong cửa sổ nhà. Mỗi hành động là một thể hiện của PluginAction, trông giống như lớp Action, với phương thức execute và các thuộc tính (2) có thể thay đổi của nó.
Lưu ý rằng lớp Plugin cung cấp cho bạn quyền truy cập vào một thể hiện UndoableEditSupport thông qua phương thức getUndoableEditSupport của nó. Ngay khi bạn sửa đổi một ngôi nhà hoặc các đối tượng của nó (nội thất, tường…) trong phương thức thực thi của một thể hiện PluginAction, bạn cũng nên đăng một đối tượng UndoableEdit vào hỗ trợ chỉnh sửa có thể hoàn tác được trả về bởi phương thức getUndoableEditSupport, nếu không người dùng sẽ không thể hoàn tác/làm lại chính xác các thay đổi bạn đã thực hiện.
Bản địa hóa
Nếu bạn dự định phát triển một plug-in cho cộng đồng người dùng Sweet Home 3D, hãy cố gắng bản địa hóa các chuỗi mà nó hiển thị trong tên hành động và menu hoặc trong các hộp thoại bạn sẽ tạo (hoặc ít nhất chuẩn bị bản địa hóa của nó). Hai nhà tạo lập của lớp PluginAction sẽ giúp bạn tổ chức việc dịch các thuộc tính hành động với các tệp .properties, và nếu bạn cần dịch các chuỗi khác trong plug-in của mình (như chuỗi trong hộp thoại được hiển thị bởi plug-in đã được kiểm tra) hãy tái sử dụng các tệp .properties này với lớp Java ResourceBundle.
Nếu bạn muốn giới hạn số lượng tệp thuộc tính, bạn thậm chí có thể viết các giá trị của các thuộc tính hành động và các chuỗi khác trong tệp mô tả ApplicationPlugin.properties của plug-in của bạn.
Nếu bạn muốn một ví dụ sử dụng kiến trúc này, hãy tải xuống plug-in Export to SH3F có sẵn tại https://test.sweethome3d.eu/plugins/ExportToSH3F-1.0.sh3p, và giải nén nó (tệp plug-in này cũng chứa mã nguồn của plug-in).
Như được mô tả trong Diễn đàn trợ giúp, plug-in này tạo ra một tệp SH3F chứa tất cả các nội thất bạn đã nhập vào danh mục nội thất của Sweet Home 3D.
Đóng góp plug-in
Bạn có thể đăng các plug-in mà bạn đã lập trình trong Hệ thống Theo dõi Đóng góp Plug-in để chia sẻ chúng với cộng đồng người dùng Sweet Home 3D.
Nhiều tính năng có thể được thêm vào Sweet Home 3D nhờ các plug-in, từ các trình nhập khẩu đến các trình xuất khẩu, nhưng cũng có các plug-in có thể sửa đổi dữ liệu của một ngôi nhà như Home Rotator Plug-in được phát triển bởi Michel Mbem và các plug-in khác được liệt kê trong Hướng dẫn cho Plug-in và Tiện ích mở rộng (PDF) được viết bởi Hans Dirkse và trong trang Plug-in và công cụ.
