package plugins.kernel.canvas; import icy.gui.component.IcyTextField; import icy.gui.component.IcyTextField.TextChangeListener; import icy.gui.component.NumberTextField; import icy.gui.component.button.ColorChooserButton; import icy.gui.component.button.ColorChooserButton.ColorChangeListener; import icy.vtk.VtkImageVolume.VtkVolumeBlendType; import icy.vtk.VtkImageVolume.VtkVolumeMapperType; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.util.EventListener; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; public class VtkSettingPanel extends JPanel implements ActionListener, TextChangeListener, ColorChangeListener { /** * */ private static final long serialVersionUID = 6433369095311474470L; public static final String PROPERTY_BG_COLOR = "renderBGColor"; public static final String PROPERTY_MAPPER = "volumeMapper"; public static final String PROPERTY_BLENDING = "volumeBlending"; public static final String PROPERTY_SAMPLE = "volumeSample"; public static final String PROPERTY_INTERPOLATION = "volumeInterpolation"; public static final String PROPERTY_AMBIENT = "volumeAmbient"; public static final String PROPERTY_DIFFUSE = "volumeDiffuse"; public static final String PROPERTY_SPECULAR = "volumeSpecular"; /** * GUI */ private ColorChooserButton bgColorButton; private JComboBox volumeMapperComboBox; private JComboBox volumeBlendingComboBox; private JComboBox volumeSampleComboBox; private JComboBox volumeInterpolationComboBox; private NumberTextField volumeAmbientField; private NumberTextField volumeSpecularField; private NumberTextField volumeDiffuseField; /** * Create the panel. */ public VtkSettingPanel() { super(); initialize(); updateState(); bgColorButton.addColorChangeListener(this); volumeMapperComboBox.addActionListener(this); volumeBlendingComboBox.addActionListener(this); volumeInterpolationComboBox.addActionListener(this); volumeSampleComboBox.addActionListener(this); volumeAmbientField.addTextChangeListener(this); volumeDiffuseField.addTextChangeListener(this); volumeSpecularField.addTextChangeListener(this); } protected void initialize() { setBorder(new EmptyBorder(2, 0, 2, 0)); GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[] {0, 0, 0, 0, 0}; gridBagLayout.rowHeights = new int[] {0, 0, 0, 0, 0, 0, 0}; gridBagLayout.columnWeights = new double[] {0.0, 1.0, 1.0, 1.0, Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE}; setLayout(gridBagLayout); final JLabel lblBackground = new JLabel("Background color"); lblBackground.setToolTipText("Change background color"); GridBagConstraints gbc_lblBackground = new GridBagConstraints(); gbc_lblBackground.anchor = GridBagConstraints.WEST; gbc_lblBackground.insets = new Insets(0, 0, 5, 5); gbc_lblBackground.gridx = 0; gbc_lblBackground.gridy = 0; add(lblBackground, gbc_lblBackground); bgColorButton = new ColorChooserButton(); bgColorButton.setToolTipText("Change background color"); GridBagConstraints gbc_bgColorButton = new GridBagConstraints(); gbc_bgColorButton.anchor = GridBagConstraints.WEST; gbc_bgColorButton.insets = new Insets(0, 0, 5, 5); gbc_bgColorButton.gridx = 1; gbc_bgColorButton.gridy = 0; add(bgColorButton, gbc_bgColorButton); final JLabel lblMapper = new JLabel("Mapper"); lblMapper.setToolTipText("Select volume rendering method"); GridBagConstraints gbc_lblMapper = new GridBagConstraints(); gbc_lblMapper.anchor = GridBagConstraints.WEST; gbc_lblMapper.insets = new Insets(0, 0, 5, 5); gbc_lblMapper.gridx = 0; gbc_lblMapper.gridy = 1; add(lblMapper, gbc_lblMapper); volumeMapperComboBox = new JComboBox(); volumeMapperComboBox.setToolTipText("Select volume rendering method"); volumeMapperComboBox.setModel(new DefaultComboBoxModel(VtkVolumeMapperType.values())); GridBagConstraints gbc_volumeMapperComboBox = new GridBagConstraints(); gbc_volumeMapperComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeMapperComboBox.gridwidth = 3; gbc_volumeMapperComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeMapperComboBox.gridx = 1; gbc_volumeMapperComboBox.gridy = 1; add(volumeMapperComboBox, gbc_volumeMapperComboBox); final JLabel lblInterpolation = new JLabel("Interpolation "); lblInterpolation.setToolTipText("Select volume rendering interpolation method"); GridBagConstraints gbc_lblInterpolation = new GridBagConstraints(); gbc_lblInterpolation.anchor = GridBagConstraints.WEST; gbc_lblInterpolation.insets = new Insets(0, 0, 5, 5); gbc_lblInterpolation.gridx = 0; gbc_lblInterpolation.gridy = 2; add(lblInterpolation, gbc_lblInterpolation); volumeInterpolationComboBox = new JComboBox(); volumeInterpolationComboBox.setToolTipText("Select volume rendering interpolation method"); volumeInterpolationComboBox.setMaximumRowCount(7); volumeInterpolationComboBox.setModel(new DefaultComboBoxModel(new String[] {"Nearest (Fast)", "Linear", "Cubic (Slow)"})); volumeInterpolationComboBox.setSelectedIndex(1); GridBagConstraints gbc_volumeInterpolationComboBox = new GridBagConstraints(); gbc_volumeInterpolationComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeInterpolationComboBox.gridwidth = 3; gbc_volumeInterpolationComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeInterpolationComboBox.gridx = 1; gbc_volumeInterpolationComboBox.gridy = 2; add(volumeInterpolationComboBox, gbc_volumeInterpolationComboBox); JLabel lblBlending = new JLabel("Blending"); lblBlending.setToolTipText("Select volume rendering blending method"); GridBagConstraints gbc_lblBlending = new GridBagConstraints(); gbc_lblBlending.anchor = GridBagConstraints.WEST; gbc_lblBlending.insets = new Insets(0, 0, 5, 5); gbc_lblBlending.gridx = 0; gbc_lblBlending.gridy = 3; add(lblBlending, gbc_lblBlending); volumeBlendingComboBox = new JComboBox(); volumeBlendingComboBox.setToolTipText("Select volume rendering blending method"); volumeBlendingComboBox.setModel(new DefaultComboBoxModel(VtkVolumeBlendType.values())); GridBagConstraints gbc_volumeBlendingComboBox = new GridBagConstraints(); gbc_volumeBlendingComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeBlendingComboBox.gridwidth = 3; gbc_volumeBlendingComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeBlendingComboBox.gridx = 1; gbc_volumeBlendingComboBox.gridy = 3; add(volumeBlendingComboBox, gbc_volumeBlendingComboBox); final JLabel lblSample = new JLabel("Sample"); lblSample.setToolTipText("Set volume sample resolution (raycaster mapper only)"); GridBagConstraints gbc_lblSample = new GridBagConstraints(); gbc_lblSample.anchor = GridBagConstraints.WEST; gbc_lblSample.insets = new Insets(0, 0, 5, 5); gbc_lblSample.gridx = 0; gbc_lblSample.gridy = 4; add(lblSample, gbc_lblSample); volumeSampleComboBox = new JComboBox(); volumeSampleComboBox .setToolTipText("Use low value for fine (but slow) rendering and high value for fast (but coarse) rendering"); volumeSampleComboBox.setMaximumRowCount(11); volumeSampleComboBox.setModel(new DefaultComboBoxModel(new String[] {"Auto", "1 (Slow)", "2", "3", "4", "5", "6", "7", "8", "9", "10 (Fast)"})); volumeSampleComboBox.setSelectedIndex(0); GridBagConstraints gbc_volumeSampleComboBox = new GridBagConstraints(); gbc_volumeSampleComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeSampleComboBox.gridwidth = 3; gbc_volumeSampleComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeSampleComboBox.gridx = 1; gbc_volumeSampleComboBox.gridy = 4; add(volumeSampleComboBox, gbc_volumeSampleComboBox); JLabel lblShading = new JLabel("Light"); lblShading.setToolTipText("Set volume light properties"); GridBagConstraints gbc_lblShading = new GridBagConstraints(); gbc_lblShading.insets = new Insets(0, 0, 0, 5); gbc_lblShading.anchor = GridBagConstraints.WEST; gbc_lblShading.gridx = 0; gbc_lblShading.gridy = 5; add(lblShading, gbc_lblShading); volumeAmbientField = new NumberTextField(); volumeAmbientField.setToolTipText("Ambient lighting coefficient"); GridBagConstraints gbc_volumeAmbientField = new GridBagConstraints(); gbc_volumeAmbientField.fill = GridBagConstraints.HORIZONTAL; gbc_volumeAmbientField.insets = new Insets(0, 0, 0, 5); gbc_volumeAmbientField.gridx = 1; gbc_volumeAmbientField.gridy = 5; add(volumeAmbientField, gbc_volumeAmbientField); volumeAmbientField.setColumns(4); volumeDiffuseField = new NumberTextField(); volumeDiffuseField.setToolTipText("Diffuse lighting coefficient"); GridBagConstraints gbc_volumeDiffuseField = new GridBagConstraints(); gbc_volumeDiffuseField.insets = new Insets(0, 0, 0, 5); gbc_volumeDiffuseField.fill = GridBagConstraints.HORIZONTAL; gbc_volumeDiffuseField.gridx = 2; gbc_volumeDiffuseField.gridy = 5; add(volumeDiffuseField, gbc_volumeDiffuseField); volumeDiffuseField.setColumns(4); volumeSpecularField = new NumberTextField(); volumeSpecularField.setToolTipText("Specular lighting coefficient"); GridBagConstraints gbc_volumeSpecularField = new GridBagConstraints(); gbc_volumeSpecularField.fill = GridBagConstraints.HORIZONTAL; gbc_volumeSpecularField.gridx = 3; gbc_volumeSpecularField.gridy = 5; add(volumeSpecularField, gbc_volumeSpecularField); volumeSpecularField.setColumns(4); } protected void updateState() { // if (isBoundingBoxVisible()) // { // boundingBoxGridCheckBox.setEnabled(true); // boundingBoxRulerCheckBox.setEnabled(true); // } // else // { // boundingBoxGridCheckBox.setEnabled(false); // boundingBoxRulerCheckBox.setEnabled(false); // } switch (getVolumeMapperType()) { case RAYCAST_CPU_FIXEDPOINT: case RAYCAST_GPU_OPENGL: volumeSampleComboBox.setEnabled(true); volumeBlendingComboBox.setEnabled(true); break; case TEXTURE2D_OPENGL: case TEXTURE3D_OPENGL: volumeSampleComboBox.setEnabled(false); volumeBlendingComboBox.setEnabled(false); break; } } public Color getBackgroundColor() { return bgColorButton.getColor(); } public void setBackgroundColor(Color value) { bgColorButton.setColor(value); } public VtkVolumeMapperType getVolumeMapperType() { if (volumeMapperComboBox.getSelectedIndex() == -1) return null; return (VtkVolumeMapperType) volumeMapperComboBox.getSelectedItem(); } public void setVolumeMapperType(VtkVolumeMapperType value) { volumeMapperComboBox.setSelectedItem(value); } public int getVolumeInterpolation() { return volumeInterpolationComboBox.getSelectedIndex(); } public void setVolumeInterpolation(int value) { volumeInterpolationComboBox.setSelectedIndex(value); } public VtkVolumeBlendType getVolumeBlendingMode() { if (volumeBlendingComboBox.getSelectedIndex() == -1) return null; return (VtkVolumeBlendType) volumeBlendingComboBox.getSelectedItem(); } public void setVolumeBlendingMode(VtkVolumeBlendType value) { volumeBlendingComboBox.setSelectedItem(value); } public int getVolumeSample() { return volumeSampleComboBox.getSelectedIndex(); } public void setVolumeSample(int value) { volumeSampleComboBox.setSelectedIndex(value); } public double getVolumeAmbient() { return volumeAmbientField.getNumericValue(); } public void setVolumeAmbient(double value) { volumeAmbientField.setNumericValue(value); } public double getVolumeDiffuse() { return volumeDiffuseField.getNumericValue(); } public void setVolumeDiffuse(double value) { volumeDiffuseField.setNumericValue(value); } public double getVolumeSpecular() { return volumeSpecularField.getNumericValue(); } public void setVolumeSpecular(double value) { volumeSpecularField.setNumericValue(value); } /** * Add a SettingChange listener */ public void addSettingChangeListener(SettingChangeListener listener) { listenerList.add(SettingChangeListener.class, listener); } /** * Remove a SettingChange listener */ public void removeSettingChangeListener(SettingChangeListener listener) { listenerList.remove(SettingChangeListener.class, listener); } public void fireSettingChange(Object source, String propertyName, Object oldValue, Object newValue) { if ((oldValue != null) && (newValue != null) && oldValue.equals(newValue)) return; final PropertyChangeEvent event = new PropertyChangeEvent(source, propertyName, oldValue, newValue); final SettingChangeListener[] listeners = getListeners(SettingChangeListener.class); for (int i = 0; i < listeners.length; i++) listeners[i].settingChange(event); } @Override public void colorChanged(ColorChooserButton source) { if (source == bgColorButton) fireSettingChange(source, PROPERTY_BG_COLOR, null, source.getColor()); } @Override public void actionPerformed(ActionEvent e) { final Object source = e.getSource(); if (source == volumeMapperComboBox) fireSettingChange(source, PROPERTY_MAPPER, null, volumeMapperComboBox.getSelectedItem()); else if (source == volumeBlendingComboBox) fireSettingChange(source, PROPERTY_BLENDING, null, volumeBlendingComboBox.getSelectedItem()); else if (source == volumeSampleComboBox) fireSettingChange(source, PROPERTY_SAMPLE, Integer.valueOf(-1), Integer.valueOf(volumeSampleComboBox.getSelectedIndex())); else if (source == volumeInterpolationComboBox) fireSettingChange(source, PROPERTY_INTERPOLATION, Integer.valueOf(-1), Integer.valueOf(volumeInterpolationComboBox.getSelectedIndex())); updateState(); } @Override public void textChanged(IcyTextField source, boolean validate) { if (!validate) return; if (source == volumeAmbientField) fireSettingChange(source, PROPERTY_AMBIENT, Double.valueOf(-1d), Double.valueOf(volumeAmbientField.getNumericValue())); else if (source == volumeDiffuseField) fireSettingChange(source, PROPERTY_DIFFUSE, Double.valueOf(-1d), Double.valueOf(volumeDiffuseField.getNumericValue())); else if (source == volumeSpecularField) fireSettingChange(source, PROPERTY_SPECULAR, Double.valueOf(-1d), Double.valueOf(volumeSpecularField.getNumericValue())); updateState(); } public static interface SettingChangeListener extends EventListener { public void settingChange(PropertyChangeEvent evt); } }