package uk.org.squirm3.ui.toolbar.simulation;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.springframework.context.MessageSource;
import uk.org.squirm3.engine.ApplicationEngine;
import uk.org.squirm3.engine.ApplicationEngineEvent;
import uk.org.squirm3.listener.Listener;
import uk.org.squirm3.springframework.Messages;
import uk.org.squirm3.swing.SwingUtils;
/**
* Allows user to change the speed of the simulation.
*/
public class SpeedPanel extends JPanel implements Listener {
private static final long serialVersionUID = 1L;
private final ApplicationEngine applicationEngine;
private final JSlider speedSelector;
public SpeedPanel(final ApplicationEngine applicationEngine,
final MessageSource messageSource) {
this.applicationEngine = applicationEngine;
speedSelector = createSpeedSelector();
setupLayout(messageSource);
applicationEngine.addListener(this, ApplicationEngineEvent.SPEED);
setMaximumSize(getPreferredSize());
}
private void setupLayout(final MessageSource messageSource) {
setLayout(new GridBagLayout());
add(new JLabel(Messages.localize("parameters.speed", messageSource)),
SwingUtils.createCustomGBC(0, 0));
add(speedSelector, SwingUtils.createCustomGBC(1, 0, 80,
GridBagConstraints.HORIZONTAL));
}
private JSlider createSpeedSelector() {
final JSlider speedSelector = new JSlider(1, 8);
speedSelector.setMajorTickSpacing(1);
speedSelector.setPaintTicks(true);
speedSelector.setInverted(true);
speedSelector
.addChangeListener(new SpeedSelectorListener(speedSelector));
return speedSelector;
}
/**
* Convert non-linear mapping : selector to engine.
*/
private void updateEngineSpeed() {
applicationEngine.setSimulationSpeed((short) Math.pow(
speedSelector.getValue(), 2));
}
/**
* Convert non-linear mapping : engine to selector.
*/
@Override
public void propertyHasChanged() {
speedSelector.setValue((int) Math.sqrt(applicationEngine
.getSimulationSpeed()));
}
/**
* When the user has picked a new value for the selector, update the engine.
*/
private final class SpeedSelectorListener implements ChangeListener {
private final JSlider speedSelector;
private SpeedSelectorListener(final JSlider speedSelector) {
this.speedSelector = speedSelector;
}
/*
* (non-Javadoc)
*
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.
* ChangeEvent)
*/
@Override
public void stateChanged(final ChangeEvent e) {
final Object object = e.getSource();
if (object != speedSelector) {
return;
}
if (!speedSelector.getValueIsAdjusting()) {
updateEngineSpeed();
}
}
}
}