/*
* See COPYING in top-level directory.
*/
package com.monkygames.wox.health.gui;
// === java imports === //
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// === miglayout imports === //
import net.miginfocom.swing.MigLayout;
// === wox imports === //
import com.monkygames.wox.health.io.*;
import com.monkygames.wox.health.data.Weight;
/**
* Displays the "primitive" scale gui.
* Note, this works by using a thread to initialize the scale
* due to blocking issues as well as getting the weight.
* The callgraph should look like this<br>
* init -- ScaleThread -- turnOn -- weightUpdate -- scaleThread --
* @version 1.0
*/
public class ScaleGUI extends JFrame implements ScaleInterface, ActionListener{
// ============= Class variables ============== //
/**
* The root panel.
**/
private JPanel rootPanel;
/**
* Contains information to notify the user with.
**/
private JLabel infoLabel;
/**
* Used for the user to cancel or accept.
**/
private JButton actionB;
/**
* The progress (indeterminate) of the measurement.
**/
private JProgressBar progressBar;
/**
* The current state of the measurement.
**/
private ScaleThread.State state;
/**
* Handles measuring the weight of the user.
**/
private Scale scale;
/**
* Used for notifying when the weight has been calc.
**/
private HealthGUI healthGUI;
/**
* The number of samples recieved from the scale.
**/
private int sampleNum;
/**
* True if measurements should be accepted and false otherwise.
**/
private boolean acceptMeasurements = false;
private boolean isKG = true;
// ============= Constructors ============== //
public ScaleGUI(HealthGUI healthGUI){
this.healthGUI = healthGUI;
int w = 300;
int h = 200;
setSize(w,h);
// moves window to center of screen
setLocationRelativeTo(null);
setTitle("Measure Weight");
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
setup();
getContentPane().add(rootPanel);
}
// ============= Public Methods ============== //
/**
* Sets the scale to be used.
* @param scale the scale to be used.
**/
public void setScale(Scale scale){
this.scale.removeScaleInterface(this);
this.scale = scale;
this.scale.addScaleInterface(this);
}
/**
* Initialises the gui and pops open.
* @param isKG true if using KG and false if bls.
**/
public void init(boolean isKG){
this.isKG = isKG;
actionB.setText("Cancel");
if(scale.balanceBoardFound()){
initComplete();
}else{
infoLabel.setText("Turn On Wii Balance Board");
state = ScaleThread.State.TURN_ON;
progressBar.setString("");
updateGUI();
}
setVisible(true);
ScaleThread scaleThread = new ScaleThread(state,scale,this);
scaleThread.start();
}
/**
*
**/
public void initComplete(){
acceptMeasurements = true;
// scale is now on
state = ScaleThread.State.STEP_ON;
infoLabel.setText("Step On");
updateGUI();
}
public void scaleFailed(){
infoLabel.setText("Unable to connect to Scale");
updateGUI();
}
/**
* Handles measuring.
**/
public void measuringComplete(Weight weight){
if(acceptMeasurements){
state = ScaleThread.State.DONE;
healthGUI.updateWeight(weight);
rootPanel.remove(progressBar);
String weightS = "";
if(isKG){
weightS = weight.weightInkg+"kg";
}else{
weightS = weight.getPounds()+"bls";
}
infoLabel.setText("All Done: "+weightS);
actionB.setText("OK");
updateGUI();
}
}
/**
* Notifies that the tare process is complete.
**/
public void tareComplete(float tare){
}
// ============= Protected Methods ============== //
// ============= Private Methods ============== //
private void setup(){
//rootPanel = new JPanel(new MigLayout("","grow","grow"));
rootPanel = new JPanel(new MigLayout("fill"));
infoLabel = new JLabel("");
actionB = new JButton("Cancel");
actionB.addActionListener(this);
progressBar = new JProgressBar();
progressBar.setOrientation(SwingConstants.HORIZONTAL);
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
rootPanel.add(infoLabel,"dock north");
rootPanel.add(actionB,"dock south");
scale = new Scale();
scale.addScaleInterface(this);
}
/**
* Handles repating the graphics.
**/
private void updateGUI(){
rootPanel.repaint();
rootPanel.revalidate();
}
// ============= Implemented Methods ============== //
public void actionPerformed(ActionEvent evt){
Object src = evt.getSource();
// make sure scale gets terminted
if(state == ScaleThread.State.MEASURING){
acceptMeasurements = false;
// inform thread to stop
scale.removeScaleInterface(this);
//scale.shutdown();
rootPanel.remove(progressBar);
// need to make sure that we do not record the measurements!
try{
// wait for the scale to be dropped
Thread.sleep(1000);
}catch(Exception e){}
scale.addScaleInterface(this);
}else if(state == ScaleThread.State.DONE){
// do nothing for now
}else{
//scale.shutdown();
}
setVisible(false);
}
/**
* The current weight reported from the scale.
* @param weight the new weight.
**/
public void weightUpdate(float weight){
if(state == ScaleThread.State.STEP_ON && weight > 2){
// change state to measuring
state = ScaleThread.State.MEASURING;
infoLabel.setText("Measuring ...");
rootPanel.add(progressBar,"dock center");
ScaleThread scaleThread = new ScaleThread(state,scale,this);
scaleThread.start();
}
sampleNum++;
if(sampleNum == 100){
// update every n samples
if(isKG){
progressBar.setString(weight+"kg");
}else{
progressBar.setString(weight*2.2f+"bls");
}
sampleNum = 0;
}
}
// ============= Extended Methods ============== //
// ============= Internal Classes ============== //
// ============= Static Methods ============== //
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ts=8 sts=4 sw=4 noexpandtab
*/