Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
942 connectés 

  FORUM HardWare.fr
  Programmation
  Java

   Problème d'affichage d'une applet

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème d'affichage d'une applet

n°911920
cofondinde
Posté le 01-12-2004 à 12:03:53  profilanswer
 

Bonjour à tous,
 
Je travaille sur un programme visant a résoudre le problème de concurrency bien connu ; les fuemurs de cigarette. Je rencontre un problème avec mon apllet avec un NullPointerException.
J'ai cherché dans tous les sens mais là j'arrive à court d'idées...
Toute suggestion est la bienvenue, merci d'avance
 
PS : C'est à rendre dans 4 heures :cry:  
 
Voici l'applet :
 
 
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.applet.Applet;
 
 
public class CigarApplet
    extends Applet {
 
  public static final int NUM_SMOKER = 3;
  public static final int NUM_INGREDIENT = 1;
 
  public Lock lock_ = new Lock();
  public Lock matches_ = new Lock();
  public Lock paper_ = new Lock();
  public Lock tobacco_ = new Lock();
 
  CigarCanvas display;
  Thread[] smoke = new Thread[CigarCanvas.NUM_SMOKER];
  Thread agent = new Thread();
  Scrollbar slider;
  Button restart;
  Button freeze;
 
  boolean isStandalone;
 
  //Initialize the applet
  public void init() {
    try {
      setLayout(new BorderLayout());
      slider = new Scrollbar(Scrollbar.HORIZONTAL, 50, 5, 0, 100);
      restart = new Button("Restart" );
      freeze = new Button("Freeze" );
      Panel p1 = new Panel();
      p1.setLayout(new BorderLayout());
      p1.add("Center", slider);
      p1.add("East", restart);
      p1.add("West", freeze);
      add("South", p1);
      display = new CigarCanvas(this);
      display.setSize(300, 320);
      add("Center", display);
 
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  public int sleepTime() {
    return (slider.getValue() * (int) (100 * Math.random()));
  }
 
  public int eatTime() {
    return (slider.getValue() * (int) (50 * Math.random()));
  }
 
  public void start() {
 
    agent = new Agent(matches_, paper_, tobacco_, lock_);
    for (int i = 0; i < NUM_SMOKER - 1; ++i) {
      smoke[i] = new Smoker(this, i, matches_, paper_, tobacco_, lock_);
      smoke[i].start();
    }
  }
 
  public void stop() {
    for (int i = 0; i < NUM_SMOKER - 1; ++i) {
      smoke[i].interrupt();
      smoke[i].stop(); //required for java 1.1
    }
  }
 
  public boolean handleEvent(Event event) {
    if (event.id != event.ACTION_EVENT) {
      return super.handleEvent(event);
    }
    else if (event.target == restart) {
      stop();
      slider.setValue(50);
      start();
 
      display.thaw();
      return true;
    }
    else if (event.target == freeze) {
      display.freeze();
      return true;
    }
    else {
      return super.handleEvent(event);
    }
  }
}
 
et le Canvas :
 
import java.applet.Applet;
import java.applet.*;
import java.awt.*;
import java.awt.Graphics;
import java.awt.MediaTracker;
 
public class CigarCanvas
    extends Canvas {
 
  CigarApplet controller;
  double[] smokeX = new double[NUM_SMOKER];
  double[] smokeY = new double[NUM_SMOKER];
  double[] ingredientX = new double[NUM_INGREDIENT];
  double[] ingredientY = new double[NUM_INGREDIENT];
  double agentY = 150;
  double agentX = 150;
 
  public static final int NUM_SMOKER = 3;
  public static final int NUM_INGREDIENT = 1;
  static final int AGENT = 0;
  static final int WAITING_SMOKER = 1;
  static final int SMOKING_SMOKER = 2;
 
  Image[] imgs = new Image[5];
  int[] smoker_state = new int[NUM_SMOKER];
  boolean[] smoker_redraw = new boolean[NUM_SMOKER];
  boolean[] ingredient_redraw = new boolean[NUM_INGREDIENT];
 
  boolean frozen = false;
 
  public CigarCanvas(CigarApplet controller) {
    super();
    this.controller = controller;
    MediaTracker mt = new MediaTracker(this);
 
    imgs[0] = controller.getImage(controller.getDocumentBase(), "images/agent.gif" );
    mt.addImage(imgs[0], 0);
    imgs[1] = controller.getImage(controller.getCodeBase(),"images/matches_waiting.gif" );
    mt.addImage(imgs[1], 1);
    imgs[2] = controller.getImage(controller.getCodeBase(),"images/paper_waiting.gif" );
    mt.addImage(imgs[2], 2);
    imgs[3] = controller.getImage(controller.getCodeBase(),"images/tobacco_waiting.gif" );
    mt.addImage(imgs[3], 3);
    imgs[4] = controller.getImage(controller.getCodeBase(),"images/matches_smoking.gif" );
    mt.addImage(imgs[4], 4);
    imgs[5] = controller.getImage(controller.getCodeBase(),"images/paper_smoking.gif" );
    mt.addImage(imgs[5], 5);
    imgs[6] = controller.getImage(controller.getCodeBase(),"images/tobacco_smoking.gif" );
    mt.addImage(imgs[6], 6);
    imgs[7] = controller.getImage(controller.getCodeBase(),"images/matches.gif" );
    mt.addImage(imgs[7], 7);
    imgs[8] = controller.getImage(controller.getCodeBase(),"images/paper.gif" );
    mt.addImage(imgs[8], 8);
    imgs[9] = controller.getImage(controller.getCodeBase(),"images/tobacco.gif" );
    mt.addImage(imgs[9], 9);
 
    try {
      mt.waitForID(0);
      mt.waitForID(1);
      mt.waitForID(2);
      mt.waitForID(3);
      mt.waitForID(4);
      mt.waitForID(5);
      mt.waitForID(6);
      mt.waitForID(7);
      mt.waitForID(8);
      mt.waitForID(9);
    }
    catch (java.lang.InterruptedException e) {
      e.printStackTrace();
    }
    initPlacing();
  }
 
  Image offscreen;
  Dimension offscreensize;
  Graphics offgraphics;
 
  void backdrop() {
    Dimension d = size();
    if ( (offscreen == null) || (d.width != offscreensize.width)
        || (d.height != offscreensize.height)) {
      offscreen = createImage(d.width, d.height);
      offscreensize = d;
      offgraphics = offscreen.getGraphics();
      offgraphics.setFont(new Font("Helvetica", Font.BOLD, 18));
    }
    offgraphics.setColor(Color.magenta);
    offgraphics.fillRect(0, 0, size().width, size().height);
    for (int i = 0; i < NUM_SMOKER; i++) {
      smoker_redraw[i] = true;
    }
    for (int i = 0; i < NUM_INGREDIENT; i++) {
      ingredient_redraw[i] = true;
    }
 
  }
 
  void drawtable() {
    offgraphics.setColor(Color.red);
    offgraphics.fillOval(105, 105, 180, 90);
  }
 
  public void paint(Graphics g) {
    backdrop();
    update(g);
  }
 
  synchronized void setSmoker(int id, int s) {
    while (frozen) {
      try {
        wait();
      }
      catch (Exception e) {
      }
    }
    smoker_state[id] = s; //smoker_state receives the image that will be
    // displayed for the smoker id
    smoker_redraw[id] = true; //smoker id will be redraw
    repaint();
  }
 
 
synchronized void setIngredient(int fi, int se) throws java.lang.
    InterruptedException {
  while (frozen) {
    wait();
  }
  ingredient_redraw[fi] = true;
  ingredient_redraw[se] = true;
  repaint();
}
 
public void update(Graphics g) {
  g.fillRect( (int) agentX, (int) agentY, imgs[0].getWidth(this),
             imgs[0].getHeight(this));
  g.drawImage(imgs[0], (int) agentX, (int) agentY, this);
  for (int i = 0; i < NUM_SMOKER; i++) {
    if (smoker_redraw[i]) {
      smokerPaint(offgraphics, i);
      smoker_redraw[i] = false;
    }
  }
  for (int i = 0; i < NUM_INGREDIENT; i++) {
    if (ingredient_redraw[i]) {
      ingredientPaint(offgraphics, i);
      ingredient_redraw[i] = false;
    }
  }
  drawtable();
  agentPaint(offgraphics);
  g.drawImage(offscreen, 0, 0, null);
}
 
void initPlacing() {
  //will initialize the coordinates of the icons of smokers and agent//
 
  for (int i = 0; i < NUM_SMOKER; i++) {
    smokeX[i] = 50;
    smokeY[0] = 20;
    smokeY[i] = smokeX[0] + i * 50;
  }
 
  for (int i = 0; i < NUM_INGREDIENT; i++) {
    ingredientX[i] = 105;
    ingredientY[0] = 20;
    ingredientY[i] = ingredientX[0] + i * 50;
  }
}
 
void smokerPaint(Graphics g, int i) {
  g.setColor(Color.lightGray);
 
  g.fillRect( (int) smokeX[i], (int) smokeY[i], imgs[i].getWidth(this),
             imgs[i].getHeight(this));
 
  g.drawImage(imgs[smoker_state[i]], (int) smokeX[i], (int) smokeY[i], this);
 
}
 
void ingredientPaint(Graphics g, int i) {
  g.setColor(Color.lightGray);
 
  g.fillRect( (int) ingredientX[i], (int) ingredientY[i], imgs[i].getWidth(this),
             imgs[i].getHeight(this));
 
  g.drawImage(imgs[i], (int) ingredientX[i],
              (int) ingredientY[i], this);
 
}
 
void agentPaint(Graphics g) {
  g.setColor(Color.lightGray);
  g.fillRect( (int) agentX, (int) agentY, imgs[0].getWidth(this),
             imgs[0].getHeight(this));
  g.drawImage(imgs[0], (int) agentX, (int) agentY, this);
 
}
 
synchronized void thaw() {
  frozen = false;
  notifyAll();
}
 
synchronized void freeze() {
  frozen = true;
}
 
}
 
 
J'ai égalemnt les classe Agent (threads) , Smoker (thread) et Lock. Si vous en avez besoin..

mood
Publicité
Posté le 01-12-2004 à 12:03:53  profilanswer
 

n°911928
Bidem
Posté le 01-12-2004 à 12:17:54  profilanswer
 

Peux-tu envoyer l'erreur que tu reçois (la stackTrace) ?

n°911935
cofondinde
Posté le 01-12-2004 à 12:30:40  profilanswer
 

Je veux bien mais comment l'avoir? J'execute mon applet dans une page web alors la barre d'état contient juste NullPointerException...
 
Comment je peux faire? Désolée, ca doit etre une question stupide..

n°911956
patachou
Posté le 01-12-2004 à 13:07:18  profilanswer
 

tu fais afficher la console java...

n°912017
cofondinde
Posté le 01-12-2004 à 14:02:39  profilanswer
 

Voici l'erreur en question. IL s'agit d'une erruer su rla fonction getDocumentBAse mais je ne comprends pas pourquoi. Entre temps j'ai un peu modifié mes classes, le chargement des images se fait desormais dans l'applet. Le nouveau code est après la description de l'erreur. Les lignes concernées par l'eereur sont précedées de *****  Merci d'avance
 
java.lang.NullPointerException
 
 at java.applet.Applet.getDocumentBase(Applet.java:125)
 
 at cigar_smoker.CigarApplet.init(CigarApplet.java:44)
 
 at cigar_smoker.CigarApplet.main(CigarApplet.java:152)
 
java.lang.NullPointerException
 
 at cigar_smoker.Smoker.<init>(Smoker.java:32)
 
 at cigar_smoker.CigarApplet.start(CigarApplet.java:111)
 
 at cigar_smoker.CigarApplet.main(CigarApplet.java:153)
 
Exception in thread "main"  
 
_________________________________________________
CIGAR_CANVAS
 
package cigar_smoker;
 
import java.awt.*;
import java.awt.MediaTracker;
import java.net.URL;
 
public class CigarCanvas
    extends Canvas {
 
  CigarApplet controller;
  double[] smokeX = new double[NUM_SMOKER];
  double[] smokeY = new double[NUM_SMOKER];
  double[] ingredientX = new double[NUM_INGREDIENT];
  double[] ingredientY = new double[NUM_INGREDIENT];
  double agentY = 150;
  double agentX = 150;
 
  public static final int NUM_SMOKER = 3;
  public static final int NUM_INGREDIENT = 1;
  static final int AGENT = 0;
  static final int WAITING_SMOKER = 1;
  static final int SMOKING_SMOKER = 2;
 
   
  int[] smoker_state = new int[NUM_SMOKER];
  boolean[] smoker_redraw = new boolean[NUM_SMOKER];
  boolean[] ingredient_redraw = new boolean[NUM_INGREDIENT];
 
  boolean frozen = false;
 
  URL image;
 
  public CigarCanvas(CigarApplet controller) {
    super();
    this.controller = controller;    
    initPlacing();
  }
 
  Image offscreen;
  Dimension offscreensize;
  Graphics offgraphics;
 
  void backdrop() {
    Dimension d = size();
    if ( (offscreen == null) || (d.width != offscreensize.width)
        || (d.height != offscreensize.height)) {
      offscreen = createImage(d.width, d.height);
      offscreensize = d;
      offgraphics = offscreen.getGraphics();
      offgraphics.setFont(new Font("Helvetica", Font.BOLD, 18));
    }
    offgraphics.setColor(Color.magenta);
    offgraphics.fillRect(0, 0, size().width, size().height);
    for (int i = 0; i < NUM_SMOKER; i++) {
      smoker_redraw[i] = true;
    }
    for (int i = 0; i < NUM_INGREDIENT; i++) {
      ingredient_redraw[i] = true;
    }
 
  }
 
  void drawtable() {
    offgraphics.setColor(Color.red);
    offgraphics.fillOval(105, 105, 180, 90);
  }
 
  public void paint(Graphics g) {
    backdrop();
    update(g);
  }
 
  synchronized void setSmoker(int id, int s) {
    while (frozen) {
      try {
        wait();
      }
      catch (Exception e) {
      }
    }
    smoker_state[id] = s; //smoker_state receives the image that will be
    // displayed for the smoker id
    smoker_redraw[id] = true; //smoker id will be redraw
    repaint();
  }
 
  synchronized void setIngredient(int fi, int se) throws java.lang.
      InterruptedException {
    while (frozen) {
      wait();
    }
    ingredient_redraw[fi] = true;
    ingredient_redraw[se] = true;
    repaint();
  }
 
  public void update(Graphics g) {
    g.fillRect( (int) agentX, (int) agentY, controller.imgs[0].getWidth(this),
               controller.imgs[0].getHeight(this));
    g.drawImage(controller.imgs[0], (int) agentX, (int) agentY, this);
    for (int i = 0; i < NUM_SMOKER; i++) {
      if (smoker_redraw[i]) {
        smokerPaint(offgraphics, i);
        smoker_redraw[i] = false;
      }
    }
    for (int i = 0; i < NUM_INGREDIENT; i++) {
      if (ingredient_redraw[i]) {
        ingredientPaint(offgraphics, i);
        ingredient_redraw[i] = false;
      }
    }
    drawtable();
    agentPaint(offgraphics);
    g.drawImage(offscreen, 0, 0, null);
  }
 
  void initPlacing() {
    //will initialize the coordinates of the icons of smokers and agent//
 
    for (int i = 0; i < NUM_SMOKER; i++) {
      smokeX[i] = 50;
      smokeY[0] = 20;
      smokeY[i] = smokeX[0] + i * 50;
    }
 
    for (int i = 0; i < NUM_INGREDIENT; i++) {
      ingredientX[i] = 105;
      ingredientY[0] = 20;
      ingredientY[i] = ingredientX[0] + i * 50;
    }
  }
 
  void smokerPaint(Graphics g, int i) {
    g.setColor(Color.lightGray);
 
    g.fillRect( (int) smokeX[i], (int) smokeY[i], controller.imgs[i].getWidth(this),
               controller.imgs[i].getHeight(this));
 
    g.drawImage(controller.imgs[smoker_state[i]], (int) smokeX[i], (int) smokeY[i], this);
 
  }
 
  void ingredientPaint(Graphics g, int i) {
    g.setColor(Color.lightGray);
 
    g.fillRect( (int) ingredientX[i], (int) ingredientY[i], controller.imgs[i].getWidth(this),
               controller.imgs[i].getHeight(this));
 
    g.drawImage(controller.imgs[i + 7], (int) ingredientX[i],
                (int) ingredientY[i], this);
 
  }
 
  void agentPaint(Graphics g) {
    g.setColor(Color.lightGray);
    g.fillRect( (int) agentX, (int) agentY, controller.imgs[0].getWidth(this),
               controller.imgs[0].getHeight(this));
    g.drawImage(controller.imgs[0], (int) agentX, (int) agentY, this);
 
  }
 
  synchronized void thaw() {
    frozen = false;
    notifyAll();
  }
 
  synchronized void freeze() {
    frozen = true;
  }
 
}
 
________________________________________________
CIGAR_APPLET
 
package cigar_smoker;
 
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
 
public class CigarApplet
    extends Applet {
 
  public static final int NUM_SMOKER = 3;
  public static final int NUM_INGREDIENT = 1;
 
  public Lock lock_ = new Lock();
  public Lock matches_ = new Lock();
  public Lock paper_ = new Lock();
  public Lock tobacco_ = new Lock();
   
  Image[] imgs = new Image[5];
 
  CigarCanvas display;
  Thread[] smoke = new Thread[CigarCanvas.NUM_SMOKER];
  Thread agent = new Thread();
  Scrollbar slider;
  Button restart;
  Button freeze;
 
  boolean isStandalone;
 
  //Initialize the applet
  public void init() {
    try {
      MediaTracker mt = new MediaTracker(this);
 
 ********   imgs[0] = getImage(getDocumentBase(),"../images/agent.gif" );
    mt.addImage(imgs[0], 0);
    imgs[1] = getImage(getDocumentBase(),"../matches_waiting.gif" );
    mt.addImage(imgs[1], 1);
    imgs[2] = getImage(getDocumentBase(),"../paper_waiting.gif" );
    mt.addImage(imgs[2], 2);
    imgs[3] = getImage(getDocumentBase(),"../tobacco_waiting.gif" );
    mt.addImage(imgs[3], 3);
    imgs[4] = getImage(getDocumentBase(),"../matches_smoking.gif" );
    mt.addImage(imgs[4], 4);
    imgs[5] = getImage(getDocumentBase(),"../paper_smoking.gif" );
    mt.addImage(imgs[5], 5);
    imgs[6] = getImage(getDocumentBase(),"../tobacco_smoking.gif" );
    mt.addImage(imgs[6], 6);
    imgs[7] = getImage(getDocumentBase(),"../matches.gif" );
    mt.addImage(imgs[7], 7);
    imgs[8] = getImage(getDocumentBase(),"../paper.gif" );
    mt.addImage(imgs[8], 8);
    imgs[9] = getImage(getDocumentBase(),"../tobacco.gif" );
    mt.addImage(imgs[9], 9);
 
    try {
      mt.waitForID(0);
      mt.waitForID(1);
      mt.waitForID(2);
      mt.waitForID(3);
      mt.waitForID(4);
      mt.waitForID(5);
      mt.waitForID(6);
      mt.waitForID(7);
      mt.waitForID(8);
      mt.waitForID(9);
    }
    catch (java.lang.NullPointerException e) {
      e.printStackTrace();
    }
    display.initPlacing();
 
      JPanel p1 = new JPanel();
      setLayout(new BorderLayout());
      p1.add(slider = new Scrollbar(Scrollbar.HORIZONTAL, 50, 5, 0, 100));
      p1.add(restart = new Button("Restart" ));
      p1.add(freeze = new Button("Freeze" ));
      p1.setLayout(new BorderLayout());
      display = new CigarCanvas(this);
      display.setSize(300, 320);
      p1.add("Center", display);
 
 
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  public int sleepTime() {
    return (slider.getValue() * (int) (100 * Math.random()));
  }
 
  public int eatTime() {
    return (slider.getValue() * (int) (50 * Math.random()));
  }
 
  public void start() {
 
    agent = new Agent(matches_, paper_, tobacco_, lock_);
    for (int i = 0; i < NUM_SMOKER - 1; ++i) {
    *******smoke[i] = new Smoker(this, i, matches_, paper_, tobacco_, lock_);
      smoke[i].start();
    }
  }
 
  public void stop() {
    for (int i = 0; i < NUM_SMOKER - 1; ++i) {
      smoke[i].interrupt();
      smoke[i].stop(); //required for java 1.1
    }
  }
 
  public boolean handleEvent(Event event) {
    if (event.id != event.ACTION_EVENT) {
      return super.handleEvent(event);
    }
    else if (event.target == restart) {
      stop();
      slider.setValue(50);
      start();
 
      display.thaw();
      return true;
    }
    else if (event.target == freeze) {
      display.freeze();
      return true;
    }
    else {
      return super.handleEvent(event);
    }
  }
 
  //Main method
   public static void main(String[] args) {
     CigarApplet applet = new CigarApplet();
     applet.isStandalone = true;
     Frame frame;
     frame = new Frame();
     frame.setTitle("Cigarette smoker problem" );
     frame.add(applet, BorderLayout.CENTER);
   **********  applet.init();
   **********  applet.start();
     frame.setSize(400, 320);
     Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
     frame.setLocation( (d.width - frame.getSize().width) / 2,
                       (d.height - frame.getSize().height) / 2);
     frame.setVisible(true);
   }
}_____________________________________________
 
 
___________________________________________________
SMOKER
 
package cigar_smoker;
 
class Smoker
    extends Thread {
 
  public final static int MATCHES = 0;
  public final static int PAPER = 1;
  public final static int TOBACCO = 2;
 
  public Lock matches;
  public Lock paper;
  public Lock tobacco;
  public Lock lock;
 
  public CigarApplet controller;
  private CigarCanvas view;
 
  private int ingredient;
  private int MAX_SMOKING_TIME = 500;
 
  public Smoker(int ingredient) {
    this.ingredient = ingredient;
  }
 
  public Smoker(CigarApplet controller,int ingredient, Lock matches,Lock paper,Lock tobacco,Lock lock) {
    this.ingredient = ingredient;
    this.controller = controller;
    this.matches = matches;
    this.paper = paper;
    this.tobacco = tobacco;
    this.lock = lock;
    view.setSmoker(ingredient,ingredient);
  }
 
  /**
   * run
   */
  public void run() {
    while (!isInterrupted()) {
      if (lock.locked()) {
        try {
          if (ingredient == TOBACCO) {
            if (tobacco.locked()) {
              view.setSmoker(ingredient,ingredient+3);
              tobacco.unlock();
              smoke();
            }
          }
          if (ingredient == PAPER) {
            if (paper.locked()) {
              view.setSmoker(ingredient,ingredient+3);
              paper.unlock();
              smoke();
            }
          }
          if (ingredient == MATCHES) {
            if (matches.locked()) {
              view.setSmoker(ingredient,ingredient+3);
              matches.unlock();
              smoke();
            }
          }
        }
 
        catch (Exception ie) {
          System.out.println("probleme avec le thread Smoker " + ingredient);
          System.out.println("code erreur " + ie);
        }
      }
    }
  }
 
  synchronized void smoke() {
    long sleepTime;
    System.out.println("Starting smoking for the Smoker " + ingredient);
    sleepTime = 100;
    try {
      this.sleep(sleepTime);
      lock.unlock();
    }
    catch (InterruptedException ie) {
      // Smoking interrupted
      System.out.println("Smoker's " + ingredient +
                         " smoking brutally interrupted.\n" );
    }
    System.out.println("Fin de la methode smoke() du Smoker " + ingredient);
  }
}
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

   Problème d'affichage d'une applet

 

Sujets relatifs
[GD2] Problème conf lib|JS| souci d'affichage de sous-menu
Probléme d'un TriggerProbléme d'un Trigger
Probléme d'un TriggerProbléme d'un Trigger
Probleme de tableau a 2 dimentionproblème avec le nbre d'images survolées ds Dreamweaver?
Problème de fichier .htaccess[Lex Yacc] problème de Main()
Plus de sujets relatifs à : Problème d'affichage d'une applet


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR