2011-09-09 27 views
12

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()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.

Trả lời

6

Câu hỏi hay. Để trả lời câu hỏi này, chúng ta cần hiểu các khối mã java trước tiên. chúng tôi có một khối ẩn danh trước khi construtor sẽ được thực hiện.

package com.test; 

import java.applet.Applet; 
import java.awt.*; 

public class AppletTest extends Applet { 
    { 
     System.out.println("I m Anonymous block"); 
    } 

    static { 
     System.out.println("I m static block"); 
    } 

    public AppletTest() 
    { 
     System.out.println("I m constructor"); 
    } 

    public void init() 
    { 
     System.out.println("init"); 
    } 

    public void start() 
    { 
     System.out.println("start"); 
    } 

    public void stop() 
    { 
     System.out.println("stop"); 
    } 

    public void destroy() 
    { 
     System.out.println("destory"); 
    } 

    public void paint(Graphics g) 
    { 
     g.drawString("test Applet",10,10); 
    } 
} 

gọi:

<applet code="AppletTest.class" height=300 width=300></applet> 

khi chạy lớp này sử dụng appletviewer bạn có thể lưu ý sự khác biệt. Applet chạy lần đầu tiên bạn sẽ nhận được

I m static block 
    I m Anonymous block 
    I m constructor 
    init 
    start 

trong khi làm Applet restart -

stop 
destory 
init 
start 

và trên Applet tải lại

stop 
destory 
I m Anonymous block 
I m constructor 
init 
start 

cho câu hỏi thứ hai của bạn, Applet không đảm bảo cùng một đầu ra trên các thành phần hệ điều hành, mạng và phần cứng khác nhau.

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