2013-01-07 93 views
1

可能重複:
Iframe over applet flickering的Java 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); 

} 

    } 

但有可能使其在另一種方式?

+0

確保它是雙緩衝的。 – aioobe

+0

我該如何檢查?我是新來的java –

+1

BTW - 'AvatarClient.instance.getGraphics()'有一個非常糟糕的代碼味道。對於任何基於AWT或Swing的組件,這不是您要做的事情。爲了更快地獲得更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –

回答

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找到一個例子,但基本上你正在尋找的關鍵字是「雙緩衝」,以找到解決閃爍問題的大量細節。