package com.roboclub.robobuggy.ui; import com.roboclub.robobuggy.main.RobobuggyConfigFile; import com.roboclub.robobuggy.main.RobobuggyLogicNotification; import com.roboclub.robobuggy.main.RobobuggyMessageLevel; import com.roboclub.robobuggy.messages.EncoderResetMessage; import com.roboclub.robobuggy.messages.GuiLoggingButtonMessage; import com.roboclub.robobuggy.ros.NodeChannel; import com.roboclub.robobuggy.ros.Publisher; import javax.swing.JButton; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.Timer; import java.awt.Color; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimerTask; /** * {@link RobobuggyGUIContainer} used for logging information */ public class LoggingPanel extends RobobuggyGUIContainer { //TODO: test to make sure all these dont need to be static private JButton resetBtn; private JButton playBtn; private JFormattedTextField timeLbl; private static final int TIME_ZONE_OFFSET = 18000000;//5 hours private Date startTime; private Timer timer; private Publisher loggingButtonPub; //to make logging panel accessible to button callbacks private LoggingPanel thisLoggingPanel = this; private JLabel filenameLabel; private JTextField playbackSpeed; private Publisher encoderResetPub; /** * Construct a new {@link LoggingPanel} object */ public LoggingPanel() { name = "LoggingPanel"; loggingButtonPub = new Publisher(NodeChannel.GUI_LOGGING_BUTTON.getMsgPath()); encoderResetPub = new Publisher(NodeChannel.ENCODER_RESET.getMsgPath()); timer = new Timer(10, new TimerHandler());// updates every .01 seconds timer.setDelay(100); timer.setRepeats(true); // timer needs to be setup before startpause_btn //should be the time that we start the system at startTime = new Date(); playBtn = new JButton("START"); playBtn.setFont(new Font("serif", Font.PLAIN, 25)); playBtn.addActionListener(new PlayButtonHandler()); playBtn.setEnabled(true); playBtn.setBackground(Color.BLUE); resetBtn = new JButton("RESET ENCODER"); resetBtn.setFont(new Font("seif", Font.PLAIN, 25)); resetBtn.addActionListener(new ResetEncoderButtonHandler()); resetBtn.setEnabled(true); resetBtn.setBackground(Color.BLUE); filenameLabel = new JLabel("File: ", SwingConstants.CENTER); filenameLabel.setFont(new Font("sanserif", Font.PLAIN, 15)); timeLbl = new JFormattedTextField(new SimpleDateFormat("HH:mm:ss.S")); timeLbl.setHorizontalAlignment(SwingConstants.CENTER); timeLbl.setFont(new Font("sanserif", Font.PLAIN, 50)); timeLbl.setEditable(false); timeLbl.setColumns(7); timeLbl.setValue(startTime); playbackSpeed = new JTextField("1"); playbackSpeed.setHorizontalAlignment(JTextField.CENTER); this.addComponent(playBtn, 0, 0, 1.0, .25); this.addComponent(resetBtn, 0, .25, 1.0, 0.25); this.addComponent(filenameLabel, 0, .5, 0.5, .25); this.addComponent(playbackSpeed, .5, .5, 0.5, .25); this.addComponent(timeLbl, 0, .75, 1, .25); //uses pulling to make sure that the play back speed is up to date java.util.Timer t = new java.util.Timer(); t.schedule(new TimerTask() { @Override public void run() { updatePlaybackSpeed(); } }, 0, 100); } /** * Sets the label for which file we are currently logging to * * @param fileName the filepath we're logging to */ public void setFileName(String fileName) { filenameLabel.setText("File: " + fileName); } /** * safe returns the speed * * @return the speed, or 1 if the text in the field can't be serialized */ private void updatePlaybackSpeed() { String speedStr = playbackSpeed.getText(); if (speedStr.equals("")) { new RobobuggyLogicNotification("input playback was ", RobobuggyMessageLevel.EXCEPTION); } try { RobobuggyConfigFile.setPlayBackSpeed(Double.valueOf(speedStr)); } catch (NumberFormatException e) { new RobobuggyLogicNotification("input playback could not be parsed ", RobobuggyMessageLevel.EXCEPTION); } } /** * ResetEncoderButtonHandler * * @author Sean * <p> * Sends a reset request message to low level when the "Reset Encoder" * button on the gui is pressed */ private class ResetEncoderButtonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { encoderResetPub.publish(new EncoderResetMessage()); } } /** * Class that implements what the clicking the start and stop button should d */ private class PlayButtonHandler implements ActionListener { private boolean isLogging = false; @Override public void actionPerformed(ActionEvent e) { // inverts the state of the system every time the button is pressed new RobobuggyLogicNotification("start/stop button was pressed", RobobuggyMessageLevel.NOTE); if (!isLogging) { isLogging = true; enableLogging(); } else { isLogging = false; disableLogging(); }//end if else thisLoggingPanel.validate(); Gui.getInstance().fixPaint(); //if this line is not here then the gui will not display correctly after the button is pressed } } /** * This class handles timers, what that does is still a mystery.... */ private class TimerHandler implements ActionListener { @Override public void actionPerformed(ActionEvent ae) { Date currentTime = new Date(); timeLbl.setValue(currentTime.getTime() - startTime.getTime() + TIME_ZONE_OFFSET); Gui.getInstance().fixPaint(); } } /* Update Methods */ /** * Enable logging */ public void enableLogging() { timer.start(); playBtn.setBackground(Color.RED); playBtn.setText("STOP"); loggingButtonPub.publish(new GuiLoggingButtonMessage(GuiLoggingButtonMessage.LoggingMessage.START)); startTime = new Date(); } /** * Disable logging */ public void disableLogging() { playBtn.setBackground(Color.GREEN); playBtn.setText("START"); loggingButtonPub.publish(new GuiLoggingButtonMessage(GuiLoggingButtonMessage.LoggingMessage.STOP)); timer.stop(); } }