1

可能重复:
iframe over applet 闪烁

当我把iframe它放在小程序上时,它会闪烁并闪烁很多。

这就是我认为造成它的原因。

    // Create a timer that will handle the canvas updates, effectively drawing it at the desired FPS
    tickTimer = new javax.swing.Timer(1000/Constants.APPLET_FRAMERATE, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            update(AvatarClient.instance.getGraphics());               


        }
     });

    // Start the timer
    tickTimer.start();

这是源代码:

 package main;



   import java.applet.Applet;
   import java.awt.Dimension;
   import java.awt.Graphics;
   import java.awt.MediaTracker;
   import java.awt.event.ActionEvent;
   import java.awt.event.ActionListener;
   import javascript.JavascriptCommands;

   import javax.swing.JOptionPane;
   import javax.swing.Timer;

   import client.GraphicsHandler;
   import client.avatar.AvatarController;
   import client.guiboxes.QuestionBox;
   import client.moods.MoodController;
   import client.rooms.RoomController;
   import client.tools.StuffPreloader;
   import networking.ConnectionHandler;
   import networking.NetworkMessage;
   import networking.NetworkingConstants;

   import misc.Constants;
   import misc.Language;



  public class AvatarClient extends jApplet{

/**
 * 
 */
private static final long serialVersionUID = 3792036962966286054L;
public GraphicsHandler canvas;
public ConnectionHandler connection;
Timer tickTimer;
public MediaTracker mediaTracker;

public String userName = "a"; //$NON-NLS-1$
public String localizationFolder = "";

public static AvatarClient instance;

/* called when the Applet is loaded */
public void init()    {
    instance = this;


    //setSize(new Dimension( Constants.APPLET_WIDTH,  Constants.APPLET_HEIGHT ) );
    // SET THE APPLET SIZE

    // Get the applet parameters
    userName = getParameter("userName"); //$NON-NLS-1$
    String password = getParameter("password"); //$NON-NLS-1$
    localizationFolder = getParameter("localization");


    // Create a mediatracker for image loding
    mediaTracker = new MediaTracker(this);



    System.out.println("Jesper er sej!");


    canvas = new GraphicsHandler(this);// Create a canvas, all the drawing is done within the canvas        
    canvas.setStatusMsg(Language.getString("AvatarClient.connectMessage")); // Apply a status message //$NON-NLS-1$
    canvas.setPreferredSize(new Dimension(Constants.APPLET_WIDTH,  Constants.APPLET_HEIGHT));

    // Adjust the applet options as well ( THIS SHOULD REMOVE THE BLINKING )
    setBackground(new java.awt.Color(229, 229, 229));
    setMaximumSize(new java.awt.Dimension(Constants.APPLET_WIDTH,  Constants.APPLET_HEIGHT));
    setPreferredSize(new java.awt.Dimension(Constants.APPLET_WIDTH,  Constants.APPLET_HEIGHT));
    setSize(new java.awt.Dimension(Constants.APPLET_WIDTH,  Constants.APPLET_HEIGHT ));
    setLayout(null);
    this.setIgnoreRepaint(true);
    this.add(canvas);
    validate();

    // FINALLY, create a connection handler thread ( It tries to connect to the as the first thing it does )
    connection= new ConnectionHandler(this, userName, password);
    new Thread(connection).start();





    // Create a timer that will handle the canvas updates, effectively drawing it at the desired FPS
    tickTimer = new javax.swing.Timer(1000/Constants.APPLET_FRAMERATE, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            update(AvatarClient.instance.getGraphics());               


        }
     });

    // Start the timer
    tickTimer.start();




    // Add mouse and keyboard listeners to the canvas of this applet
    canvas.addMouseListener(EventsHandler.getInstance());
    canvas.addKeyListener(EventsHandler.getInstance());
    canvas.addMouseMotionListener(EventsHandler.getInstance());
    //System.out.println(canvas.);
    //this.setFocusable(false);

    new JavascriptCommands();


    // Preload some of the gui elements
    StuffPreloader.instance.loadStuff();




    // TO OVERCOME THE SECURITY PROBLEMS FOR CALLING NEW NOTIFICATIONS FROM JS
    Timer notif = new javax.swing.Timer(100, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if(newNotif)    {
                GraphicsHandler.instance.addQbox(notif_title, notif_text, QuestionBox.QUESTION_TIPBOX, 0);
                newNotif = false;
            }


        }
     });

    // Start the timer
    notif.start();
    notif.setRepeats(true);







    // Get focus to this applet
    getFocusBack();


}


boolean newNotif = false;
String notif_text, notif_title;


// START AND WHEN USER RETURNS
public void start() {
    //setSize(new Dimension( Constants.APPLET_WIDTH,  Constants.APPLET_HEIGHT ) );
    getFocusBack();




    GraphicsHandler.instance.stepsToDraw = 30;

}

public void stop()  {
    //connection.closeConnection();
}


/* Applet termination */
public void destroy()    {
    tickTimer.stop(); // Stop the update timer
}

// OVERRIDE
public void update(Graphics g)    {
    canvas.update(g);
}

public void paint(Graphics g)    {
        //canvas.requestFocus(); // Try to get focus so the user doesnt have to click for chat input
}



public void showError(String message)   {
JOptionPane.showMessageDialog(this,
        "Error:\n\n" + message, //$NON-NLS-1$
        "Error!", //$NON-NLS-1$
        JOptionPane.ERROR_MESSAGE);
}






public void getFocusBack()  {
    canvas.requestFocus(); // Try to get focus so the user doesnt have to click for chat input
    canvas.requestFocusInWindow();
}


/**************************
/** JAVASCRIPT COMMANDS
 * *****************************/

public void changeRoom(int id)  {
    getFocusBack();

     NetworkMessage msg = new NetworkMessage();
     msg.add(NetworkingConstants.N_ROOMCHANGE);
     msg.add((int)id); // REquest for data
     msg.send(connection.out);
}

public void changeMood(int id)  {
    getFocusBack();

    MoodController.instance.SetMoodByIndex(id);
}

public void nextMood()  {
    getFocusBack();

    MoodController.instance.SetNextMood();
}

public void previousMood()  {
    getFocusBack();

    MoodController.instance.SetPreviousMood();
}



public void openLogView()   {
    getFocusBack();
    AvatarController.instance.outputLog();
}

public void refreshSidebar()    {
    RoomController.instance.updateSidebarInfo(true);
}

public void openWardrobe()  {
    getFocusBack();

    // OPEN WARDROBE
    NetworkMessage msg = new NetworkMessage();
    msg.add(NetworkingConstants.N_WARDROBEUPDATE);
    msg.add((short)-2);
    msg.send(ConnectionHandler.instance.out);
}

public void notifyB()   {
    System.out.println("addnotification: ");
}



public void addNotification(String title, String text)  {
    getFocusBack();
    notif_title = title;
    notif_text = text;
    newNotif = true;

    //GraphicsHandler.instance.addQbox("This is a test message lores ipsum testing the line flow with a longer text, I wonder how it will work", QuestionBox.QUESTION_APARTMENT, 123); //$NON-NLS-1$ //$NON-NLS-2$
    //GraphicsHandler.instance.addQbox(text, title, QuestionBox.QUESTION_TIPBOX, 0); 



}

public void placeItem(int itemID)   {
    NetworkMessage msg = new NetworkMessage();
    msg.add(NetworkingConstants.N_ITEMPLACEMENT);
    msg.add((short)1); // Placing the item
    msg.add((short)itemID);
    msg.send(ConnectionHandler.instance.out);
}

public void forceFocus() {

    Timer focusBack = new javax.swing.Timer(150, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            getFocusBack();           


        }
     });

    // Start the timer
    focusBack.start();
    focusBack.setRepeats(false);

}

   }

但有可能以另一种方式实现吗?

4

1 回答 1

1

双缓冲可以解决这个问题。

基本上,您应该在未显示的画布上绘制,而不是在实时画布上绘制。绘制后立即交换两个画布实例,使“隐藏”画布成为显示的画布。

http://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_graphics将提供更多细节。

您可以在例如http://www.apl.jhu.edu/Notes/LMBrown/courses/605-481/notes/Concurrent-Programming/Double-Buffer-Example.html找到有关如何执行此操作的示例,但是基本上,您要查找的关键字是“双缓冲”,以找到解决闪烁问题的大量细节。

于 2013-01-07T18:09:49.157 回答