/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Flemming N. Larsen * - Initial API and implementation *******************************************************************************/ package net.sf.robocode.ui.dialog; import net.sf.robocode.settings.ISettingsManager; import javax.sound.sampled.*; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Vector; /** * @author Flemming N. Larsen (original) */ @SuppressWarnings("serial") public class PreferencesSoundOptionsTab extends WizardPanel { private final ISettingsManager properties; private final EventHandler eventHandler = new EventHandler(); private JPanel soundOptionsPanel; private JPanel mixerOptionsPanel; private JCheckBox enableSoundCheckBox; private JCheckBox enableGunshotCheckBox; private JCheckBox enableBulletHitCheckBox; private JCheckBox enableRobotDeathCheckBox; private JCheckBox enableWallCollisionCheckBox; private JCheckBox enableRobotCollisionCheckBox; private JButton enableAllSoundsButton; private JButton disableAllSoundsButton; private JComboBox mixerComboBox; private JButton mixerDefaultButton; private JCheckBox enableMixerVolumeCheckBox; private JCheckBox enableMixerPanCheckBox; public PreferencesSoundOptionsTab(ISettingsManager properties) { super(); this.properties = properties; initialize(); } private void initialize() { setLayout(new GridLayout(1, 2)); add(getSoundOptionsPanel()); add(getMixerOptionsPanel()); loadPreferences(properties); } private JPanel getSoundOptionsPanel() { if (soundOptionsPanel == null) { soundOptionsPanel = new JPanel(); soundOptionsPanel.setBorder( BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Sound Effects")); soundOptionsPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = 1; c.weightx = 1; c.anchor = GridBagConstraints.NORTHWEST; c.gridwidth = GridBagConstraints.REMAINDER; soundOptionsPanel.add(getEnableSoundCheckBox(), c); soundOptionsPanel.add(getEnableGunshotCheckBox(), c); soundOptionsPanel.add(getEnableBulletHitCheckBox(), c); soundOptionsPanel.add(getEnableRobotDeathCheckBox(), c); soundOptionsPanel.add(getEnableWallCollisionCheckBox(), c); soundOptionsPanel.add(getEnableRobotCollisionCheckBox(), c); c.insets = new Insets(10, 0, 0, 10); c.gridwidth = 1; c.fill = 0; c.weighty = 1; c.weightx = 0; soundOptionsPanel.add(getEnableAllSoundsButton(), c); c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER; soundOptionsPanel.add(getDisableAllSoundsButton(), c); if (AudioSystem.getMixerInfo().length == 0) { for (Component child : soundOptionsPanel.getComponents()) { child.setEnabled(false); } } } return soundOptionsPanel; } private JCheckBox getEnableSoundCheckBox() { if (enableSoundCheckBox == null) { enableSoundCheckBox = new JCheckBox("Enable Sound"); enableSoundCheckBox.setMnemonic('E'); } return enableSoundCheckBox; } private JCheckBox getEnableGunshotCheckBox() { if (enableGunshotCheckBox == null) { enableGunshotCheckBox = new JCheckBox("Gun Shots"); enableGunshotCheckBox.setMnemonic('G'); } return enableGunshotCheckBox; } private JCheckBox getEnableBulletHitCheckBox() { if (enableBulletHitCheckBox == null) { enableBulletHitCheckBox = new JCheckBox("Bullet Hit"); enableBulletHitCheckBox.setMnemonic('H'); enableBulletHitCheckBox.setDisplayedMnemonicIndex(7); } return enableBulletHitCheckBox; } private JCheckBox getEnableRobotDeathCheckBox() { if (enableRobotDeathCheckBox == null) { enableRobotDeathCheckBox = new JCheckBox("Robot Death Explosions"); enableRobotDeathCheckBox.setMnemonic('x'); enableRobotDeathCheckBox.setDisplayedMnemonicIndex(13); } return enableRobotDeathCheckBox; } private JCheckBox getEnableRobotCollisionCheckBox() { if (enableRobotCollisionCheckBox == null) { enableRobotCollisionCheckBox = new JCheckBox("Robot Collisions"); enableRobotCollisionCheckBox.setMnemonic('t'); enableRobotCollisionCheckBox.setDisplayedMnemonicIndex(4); } return enableRobotCollisionCheckBox; } private JCheckBox getEnableWallCollisionCheckBox() { if (enableWallCollisionCheckBox == null) { enableWallCollisionCheckBox = new JCheckBox("Wall Collisions"); enableWallCollisionCheckBox.setMnemonic('l'); enableWallCollisionCheckBox.setDisplayedMnemonicIndex(2); } return enableWallCollisionCheckBox; } private JButton getEnableAllSoundsButton() { if (enableAllSoundsButton == null) { enableAllSoundsButton = new JButton("Enable all"); enableAllSoundsButton.setMnemonic('a'); enableAllSoundsButton.setDisplayedMnemonicIndex(7); enableAllSoundsButton.addActionListener(eventHandler); } return enableAllSoundsButton; } private JButton getDisableAllSoundsButton() { if (disableAllSoundsButton == null) { disableAllSoundsButton = new JButton("Disable all"); disableAllSoundsButton.setMnemonic('i'); disableAllSoundsButton.setDisplayedMnemonicIndex(1); disableAllSoundsButton.addActionListener(eventHandler); } return disableAllSoundsButton; } private JPanel getMixerOptionsPanel() { if (mixerOptionsPanel == null) { mixerOptionsPanel = new JPanel(); mixerOptionsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Mixer")); mixerOptionsPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.NONE; c.weightx = 1; c.insets = new Insets(8, 4, 0, 0); mixerOptionsPanel.add(new JLabel("Select mixer:"), c); c.gridy = 1; mixerOptionsPanel.add(getMixerComboBox(), c); c.gridy = 2; mixerOptionsPanel.add(getMixerDefaultButton(), c); c.insets = new Insets(16, 4, 0, 0); c.gridy = 3; mixerOptionsPanel.add(new JLabel("Enable mixer features:"), c); c.insets = new Insets(6, 0, 0, 0); c.gridy = 4; mixerOptionsPanel.add(getEnableMixerVolumeCheckBox(), c); c.insets = new Insets(0, 0, 0, 0); c.gridy = 5; mixerOptionsPanel.add(getEnableMixerPanCheckBox(), c); if (AudioSystem.getMixerInfo().length == 0) { for (Component child : mixerOptionsPanel.getComponents()) { child.setEnabled(false); } } } return mixerOptionsPanel; } private JComboBox getMixerComboBox() { if (mixerComboBox == null) { Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); Line.Info clipLineInfo = new Line.Info(Clip.class); Vector<Mixer.Info> mixers = new Vector<Mixer.Info>(); for (Mixer.Info mi : mixerInfo) { if (AudioSystem.getMixer(mi).getSourceLineInfo(clipLineInfo).length > 0) { mixers.add(mi); } } mixerComboBox = new JComboBox(mixers); mixerComboBox.setRenderer(new MixerInfoCellRenderer()); mixerComboBox.addActionListener(eventHandler); } return mixerComboBox; } private JButton getMixerDefaultButton() { if (mixerDefaultButton == null) { mixerDefaultButton = new JButton("Default"); mixerDefaultButton.setMnemonic('u'); mixerDefaultButton.setDisplayedMnemonicIndex(4); mixerDefaultButton.addActionListener(eventHandler); } return mixerDefaultButton; } private JCheckBox getEnableMixerVolumeCheckBox() { if (enableMixerVolumeCheckBox == null) { enableMixerVolumeCheckBox = new JCheckBox("Volume"); enableMixerVolumeCheckBox.setMnemonic('V'); enableMixerVolumeCheckBox.addActionListener(eventHandler); } return enableMixerVolumeCheckBox; } private JCheckBox getEnableMixerPanCheckBox() { if (enableMixerPanCheckBox == null) { enableMixerPanCheckBox = new JCheckBox("Pan"); enableMixerPanCheckBox.setMnemonic('P'); enableMixerPanCheckBox.addActionListener(eventHandler); } return enableMixerPanCheckBox; } private void loadPreferences(ISettingsManager robocodeProperties) { getEnableSoundCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableSound()); getEnableGunshotCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableGunshot()); getEnableBulletHitCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableBulletHit()); getEnableRobotDeathCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableRobotDeath()); getEnableRobotCollisionCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableRobotCollision()); getEnableWallCollisionCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableWallCollision()); getEnableMixerVolumeCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableMixerVolume()); getEnableMixerPanCheckBox().setSelected(robocodeProperties.getOptionsSoundEnableMixerPan()); setMixerCompoBox(robocodeProperties.getOptionsSoundMixer()); } public void storePreferences() { ISettingsManager props = properties; props.setOptionsSoundEnableSound(getEnableSoundCheckBox().isSelected()); props.setOptionsSoundEnableGunshot(getEnableGunshotCheckBox().isSelected()); props.setOptionsSoundEnableBulletHit(getEnableBulletHitCheckBox().isSelected()); props.setOptionsSoundEnableRobotDeath(getEnableRobotDeathCheckBox().isSelected()); props.setOptionsSoundEnableRobotCollision(getEnableRobotCollisionCheckBox().isSelected()); props.setOptionsSoundEnableWallCollision(getEnableWallCollisionCheckBox().isSelected()); props.setOptionsSoundEnableMixerVolume(getEnableMixerVolumeCheckBox().isSelected()); props.setOptionsSoundEnableMixerPan(getEnableMixerPanCheckBox().isSelected()); String mixerClassName = null; Mixer.Info mixerInfo = (Mixer.Info) getMixerComboBox().getSelectedItem(); if (mixerInfo != null) { Mixer mixer = AudioSystem.getMixer((Mixer.Info) getMixerComboBox().getSelectedItem()); if (mixer != null) { mixerClassName = mixer.getClass().getSimpleName(); } } if (mixerClassName != null) { props.setOptionsSoundMixer(mixerClassName); } properties.saveProperties(); } @Override public boolean isReady() { return true; } private void setMixerCompoBox(String mixerName) { for (Mixer.Info mi : AudioSystem.getMixerInfo()) { if (AudioSystem.getMixer(mi).getClass().getSimpleName().equals(mixerName)) { getMixerComboBox().setSelectedItem(mi); break; } } } private class EventHandler implements ActionListener { public void actionPerformed(ActionEvent e) { Object src = e.getSource(); if (src == enableAllSoundsButton) { setAllSoundsButtonsEnabled(true); } else if (src == disableAllSoundsButton) { setAllSoundsButtonsEnabled(false); } else if (src == mixerComboBox) { mixerComboBoxActionPerformed(); } else if (src == mixerDefaultButton) { mixerDefaultButtonActionPerformed(); } } } private void setAllSoundsButtonsEnabled(boolean enabled) { enableSoundCheckBox.setSelected(enabled); enableGunshotCheckBox.setSelected(enabled); enableBulletHitCheckBox.setSelected(enabled); enableRobotDeathCheckBox.setSelected(enabled); enableWallCollisionCheckBox.setSelected(enabled); enableRobotCollisionCheckBox.setSelected(enabled); } private void mixerComboBoxActionPerformed() { Mixer mixer = AudioSystem.getMixer((Mixer.Info) mixerComboBox.getSelectedItem()); Line.Info lineInfo = mixer.getSourceLineInfo(new Line.Info(Clip.class))[0]; boolean volumeSupported; boolean panSupported; try { Line line = mixer.getLine(lineInfo); volumeSupported = line.isControlSupported(FloatControl.Type.MASTER_GAIN); panSupported = line.isControlSupported(FloatControl.Type.PAN); } catch (LineUnavailableException e) { volumeSupported = false; panSupported = false; } enableMixerVolumeCheckBox.setEnabled(volumeSupported); enableMixerPanCheckBox.setEnabled(panSupported); } private void mixerDefaultButtonActionPerformed() { setMixerCompoBox("DirectAudioDevice"); } private static class MixerInfoCellRenderer extends javax.swing.plaf.basic.BasicComboBoxRenderer { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Mixer.Info mi = (Mixer.Info) value; if (mi != null) { String text = mi.getName(); if (!"Unknown Version".equals(mi.getVersion())) { text += ' ' + mi.getVersion(); } if (!"Unknown Vendor".equals(mi.getVendor())) { text += " by " + mi.getVendor(); } setText(text); } return component; } } }