Khi applet của tôi khởi động lần đầu tiên từ môi trường trong sạch, mọi thứ hoạt động theo cách tôi mong đợi. Tôi sinh ra hai chủ đề, một cho xử lý chung, và một cho đồ họa. Tôi thực hiện tất cả các cuộc gọi thao tác GUI từ chuỗi gửi sự kiện. Start/Stop được xử lý một cách chính xác từ appletviewer, nhưng Restart/Reload thì không. Tôi có Canvas được gọi là drawCanvas
làm Thành phần duy nhất trong ngăn nội dung của ứng dụng của tôi và tôi sử dụng bộ đệm kép để vẽ.Xử lý chính xác Tải lại và Khởi động lại từ AppletViewer
tôi quan sát các vấn đề ở đây:
public void start() {
/* ... some stuff */
executeOnEDTAndWait(
new Thread() {
@Override
public void run() {
/* ... more stuff ... */
setupDrawCanvas();
if(drawCanvas.isDisplayable()) {
drawCanvas.createBufferStrategy(2);
/* ... some more stuff */
} else {
/* This is where it runs into difficulties */
}
/* ... */
đâu setupDrawCanvas
được định nghĩa như thế này:
private void setupDrawCanvas() {
setVisible(false);
setIgnoreRepaint(true);
getContentPane().removeAll();
drawCanvas = new Canvas();
drawCanvas.setName("drawCanvas");
drawCanvas.setSize(
newDrawCanvasDimension.width,
newDrawCanvasDimension.height);
drawCanvas.setIgnoreRepaint(true);
getContentPane().add(drawCanvas);
getContentPane().setVisible(true);
drawCanvas.setVisible(true);
setVisible(true);
}
Ngoài ra, đây là các mã có liên quan trong destroy()
public void destroy() {
/* .. some stuff .. */
/* dispose of drawCanvas */
drawCanvas.setVisible(false);
if(drawCanvas.getBufferStrategy() != null) {
drawCanvas.getBufferStrategy().dispose();
}
/* reset and disable the applet's GUI */
setVisible(false);
getContentPane().removeAll();
removeAll();
/* .. some more stuff */
Lần đầu tiên thông qua , mọi thứ đều hoạt động tốt. Khi tôi khởi động lại từ appletviewer
, trước tiên, stop()
được gọi là nguyên nhân khiến tất cả các chuỗi của tôi phải nhập vào trạng thái chờ. Sau đó, destroy()
được gọi là đánh thức tất cả các chủ đề của tôi một lần nữa và cho phép chúng thoát ra, cũng như làm và invokeAndWait()
trên EDT để dọn dẹp các tiện ích của tôi và thực hiện setVisible (false). Vì vậy, sau khi phá hủy hoàn thành các cuộc gọi appletviewer
init/bắt đầu một lần nữa và quá trình lặp lại chính xác như trước, ngoại trừ nó không thành công trong start()
tại khu vực tôi đã lưu ý ở trên.
Điều mà tôi nhận thấy rất ít ý nghĩa với tôi là nếu tôi sao chép applet bằng cách sử dụng appletviewer
và sau đó tải lại bản sao, mọi thứ sẽ hoạt động như mong đợi khi tôi cố gắng khởi động lại hoặc tải lại bản sao lần đầu tiên, nhưng sẽ sụp đổ với một ngoại lệ lần thứ hai.
Cái gì khác tôi nhận thấy trong khi cố gắng gỡ bỏ vấn đề này là các appletviewer
và một hành động trình duyệt hoàn toàn khác nhau như host để applet của tôi; họ thậm chí không gọi số init()
và start()
trong cùng điều kiện. Ngoài ra, khởi động lại và tải lại dường như không có gì hơn là gọi tới stop()
->destroy()
->init()
->start()
nhưng với những sửa đổi tinh tế đối với môi trường thực thi. Vì vậy, câu hỏi của tôi là, ý nghĩa của các hoạt động khởi động lại và tải lại (tức là khi nào chúng được sử dụng) và nó có phải là một vấn đề mà applet của tôi thất bại trong appletviewer khi chúng xảy ra không? Không.