/* * Home3DAttributesPanel.java 25 juin 07 * * Sweet Home 3D, Copyright (c) 2007 Emmanuel PUYBARET / eTeks <info@eteks.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.eteks.sweethome3d.swing; import java.awt.BorderLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.ButtonGroup; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JSlider; import javax.swing.KeyStroke; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.eteks.sweethome3d.model.UserPreferences; import com.eteks.sweethome3d.tools.OperatingSystem; import com.eteks.sweethome3d.viewcontroller.DialogView; import com.eteks.sweethome3d.viewcontroller.Home3DAttributesController; import com.eteks.sweethome3d.viewcontroller.View; /** * Home 3D attributes editing panel. * @author Emmanuel Puybaret */ public class Home3DAttributesPanel extends JPanel implements DialogView { private final Home3DAttributesController controller; private JRadioButton groundColorRadioButton; private ColorButton groundColorButton; private JRadioButton groundTextureRadioButton; private JComponent groundTextureComponent; private JRadioButton skyColorRadioButton; private ColorButton skyColorButton; private JRadioButton skyTextureRadioButton; private JComponent skyTextureComponent; private JLabel brightnessLabel; private JSlider brightnessSlider; private JLabel darkBrightnessLabel; private JLabel brightBrightnessLabel; private JLabel wallsTransparencyLabel; private JLabel opaqueWallsTransparencyLabel; private JLabel invisibleWallsTransparencyLabel; private JSlider wallsTransparencySlider; private String dialogTitle; /** * Creates a panel that displays home 3D attributes data. * @param preferences user preferences * @param controller the controller of this panel */ public Home3DAttributesPanel(UserPreferences preferences, Home3DAttributesController controller) { super(new GridBagLayout()); this.controller = controller; createComponents(preferences, controller); setMnemonics(preferences); layoutComponents(preferences); } /** * Creates and initializes components and spinners model. */ private void createComponents(UserPreferences preferences, final Home3DAttributesController controller) { // Ground color and texture buttons bound to ground controller properties this.groundColorRadioButton = new JRadioButton(SwingTools.getLocalizedLabelText(preferences, Home3DAttributesPanel.class, "groundColorRadioButton.text")); this.groundColorRadioButton.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { if (groundColorRadioButton.isSelected()) { controller.setGroundPaint(Home3DAttributesController.EnvironmentPaint.COLORED); } } }); controller.addPropertyChangeListener(Home3DAttributesController.Property.GROUND_PAINT, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { updateGroundRadioButtons(controller); } }); this.groundColorButton = new ColorButton(preferences); this.groundColorButton.setColorDialogTitle(preferences.getLocalizedString( Home3DAttributesPanel.class, "groundColorDialog.title")); this.groundColorButton.setColor(controller.getGroundColor()); this.groundColorButton.addPropertyChangeListener(ColorButton.COLOR_PROPERTY, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { controller.setGroundColor(groundColorButton.getColor()); } }); controller.addPropertyChangeListener(Home3DAttributesController.Property.GROUND_COLOR, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { groundColorButton.setColor(controller.getGroundColor()); } }); this.groundTextureRadioButton = new JRadioButton(SwingTools.getLocalizedLabelText(preferences, Home3DAttributesPanel.class, "groundTextureRadioButton.text")); this.groundTextureRadioButton.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { if (groundTextureRadioButton.isSelected()) { controller.setGroundPaint(Home3DAttributesController.EnvironmentPaint.TEXTURED); } } }); this.groundTextureComponent = (JComponent)controller.getGroundTextureController().getView(); ButtonGroup groundGroup = new ButtonGroup(); groundGroup.add(this.groundColorRadioButton); groundGroup.add(this.groundTextureRadioButton); updateGroundRadioButtons(controller); // Sky color and texture buttons bound to sky controller properties this.skyColorRadioButton = new JRadioButton(SwingTools.getLocalizedLabelText(preferences, Home3DAttributesPanel.class, "skyColorRadioButton.text")); this.skyColorRadioButton.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { if (skyColorRadioButton.isSelected()) { controller.setSkyPaint(Home3DAttributesController.EnvironmentPaint.COLORED); } } }); controller.addPropertyChangeListener(Home3DAttributesController.Property.SKY_PAINT, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { updateSkyRadioButtons(controller); } }); this.skyColorButton = new ColorButton(preferences); this.skyColorButton.setColorDialogTitle(preferences.getLocalizedString( Home3DAttributesPanel.class, "skyColorDialog.title")); this.skyColorButton.setColor(controller.getSkyColor()); this.skyColorButton.addPropertyChangeListener(ColorButton.COLOR_PROPERTY, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { controller.setSkyColor(skyColorButton.getColor()); } }); controller.addPropertyChangeListener(Home3DAttributesController.Property.SKY_COLOR, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { skyColorButton.setColor(controller.getSkyColor()); } }); this.skyTextureRadioButton = new JRadioButton(SwingTools.getLocalizedLabelText(preferences, Home3DAttributesPanel.class, "skyTextureRadioButton.text")); this.skyTextureRadioButton.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { if (skyTextureRadioButton.isSelected()) { controller.setSkyPaint(Home3DAttributesController.EnvironmentPaint.TEXTURED); } } }); this.skyTextureComponent = (JComponent)controller.getSkyTextureController().getView(); ButtonGroup skyGroup = new ButtonGroup(); skyGroup.add(this.skyColorRadioButton); skyGroup.add(this.skyTextureRadioButton); updateSkyRadioButtons(controller); // Brightness label and slider bound to LIGHT_COLOR controller property this.brightnessLabel = new JLabel(SwingTools.getLocalizedLabelText(preferences, Home3DAttributesPanel.class, "brightnessLabel.text")); this.brightnessSlider = new JSlider(0, 255); this.darkBrightnessLabel = new JLabel(preferences.getLocalizedString( Home3DAttributesPanel.class, "darkLabel.text")); this.brightBrightnessLabel = new JLabel(preferences.getLocalizedString( Home3DAttributesPanel.class, "brightLabel.text")); this.brightnessSlider.setPaintTicks(true); this.brightnessSlider.setMajorTickSpacing(17); this.brightnessSlider.setValue(controller.getLightColor() & 0xFF); this.brightnessSlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { int brightness = brightnessSlider.getValue(); controller.setLightColor((brightness << 16) + (brightness << 8) + brightness); } }); controller.addPropertyChangeListener(Home3DAttributesController.Property.LIGHT_COLOR, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { brightnessSlider.setValue(controller.getLightColor() & 0xFF); } }); // Walls transparency label and slider bound to WALLS_ALPHA controller property this.wallsTransparencyLabel = new JLabel(SwingTools.getLocalizedLabelText(preferences, Home3DAttributesPanel.class, "wallsTransparencyLabel.text")); this.wallsTransparencySlider = new JSlider(0, 255); this.opaqueWallsTransparencyLabel = new JLabel(preferences.getLocalizedString( Home3DAttributesPanel.class, "opaqueLabel.text")); this.invisibleWallsTransparencyLabel = new JLabel(preferences.getLocalizedString( Home3DAttributesPanel.class, "invisibleLabel.text")); this.wallsTransparencySlider.setPaintTicks(true); this.wallsTransparencySlider.setMajorTickSpacing(17); this.wallsTransparencySlider.setValue((int)(controller.getWallsAlpha() * 255)); this.wallsTransparencySlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { controller.setWallsAlpha(wallsTransparencySlider.getValue() / 255f); } }); controller.addPropertyChangeListener(Home3DAttributesController.Property.WALLS_ALPHA, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { wallsTransparencySlider.setValue((int)(controller.getWallsAlpha() * 255)); } }); this.dialogTitle = preferences.getLocalizedString( Home3DAttributesPanel.class, "home3DAttributes.title"); } /** * Updates ground radio buttons. */ private void updateGroundRadioButtons(Home3DAttributesController controller) { if (controller.getGroundPaint() == Home3DAttributesController.EnvironmentPaint.COLORED) { this.groundColorRadioButton.setSelected(true); } else { this.groundTextureRadioButton.setSelected(true); } } /** * Updates sky radio buttons. */ private void updateSkyRadioButtons(Home3DAttributesController controller) { if (controller.getSkyPaint() == Home3DAttributesController.EnvironmentPaint.COLORED) { this.skyColorRadioButton.setSelected(true); } else { this.skyTextureRadioButton.setSelected(true); } } /** * Sets components mnemonics and label / component associations. */ private void setMnemonics(UserPreferences preferences) { if (!OperatingSystem.isMacOSX()) { this.groundColorRadioButton.setMnemonic( KeyStroke.getKeyStroke(preferences.getLocalizedString( Home3DAttributesPanel.class,"groundColorRadioButton.mnemonic")).getKeyCode()); this.groundTextureRadioButton.setMnemonic( KeyStroke.getKeyStroke(preferences.getLocalizedString( Home3DAttributesPanel.class,"groundTextureRadioButton.mnemonic")).getKeyCode()); this.skyColorRadioButton.setMnemonic( KeyStroke.getKeyStroke(preferences.getLocalizedString( Home3DAttributesPanel.class,"skyColorRadioButton.mnemonic")).getKeyCode()); this.skyTextureRadioButton.setMnemonic( KeyStroke.getKeyStroke(preferences.getLocalizedString( Home3DAttributesPanel.class,"skyTextureRadioButton.mnemonic")).getKeyCode()); this.brightnessLabel.setDisplayedMnemonic( KeyStroke.getKeyStroke(preferences.getLocalizedString( Home3DAttributesPanel.class,"brightnessLabel.mnemonic")).getKeyCode()); this.brightnessLabel.setLabelFor(this.brightnessSlider); this.wallsTransparencyLabel.setDisplayedMnemonic( KeyStroke.getKeyStroke(preferences.getLocalizedString( Home3DAttributesPanel.class,"wallsTransparencyLabel.mnemonic")).getKeyCode()); this.wallsTransparencyLabel.setLabelFor(this.wallsTransparencySlider); } } /** * Layouts panel components in panel with their labels. */ private void layoutComponents(UserPreferences preferences) { int labelAlignment = OperatingSystem.isMacOSX() ? GridBagConstraints.LINE_END : GridBagConstraints.LINE_START; JPanel groundPanel = SwingTools.createTitledPanel(preferences.getLocalizedString( Home3DAttributesPanel.class, "groundPanel.title")); // First row Insets labelInsets = new Insets(0, 0, 2, 5); groundPanel.add(this.groundColorRadioButton, new GridBagConstraints( 0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, labelInsets, 0, 0)); groundPanel.add(this.groundColorButton, new GridBagConstraints( 1, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0)); // Second row groundPanel.add(this.groundTextureRadioButton, new GridBagConstraints( 0, 1, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); groundPanel.add(this.groundTextureComponent, new GridBagConstraints( 1, 1, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); Insets rowInsets; if (OperatingSystem.isMacOSXLeopardOrSuperior()) { // User smaller insets for Mac OS X 10.5 rowInsets = new Insets(0, 0, 0, 0); } else { rowInsets = new Insets(0, 0, 5, 0); } add(groundPanel, new GridBagConstraints( 0, 1, 1, 1, 0.5, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, rowInsets, 0, 0)); JPanel skyPanel = SwingTools.createTitledPanel(preferences.getLocalizedString( Home3DAttributesPanel.class, "skyPanel.title")); skyPanel.add(this.skyColorRadioButton, new GridBagConstraints( 0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, labelInsets, 0, 0)); skyPanel.add(this.skyColorButton, new GridBagConstraints( 1, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0)); skyPanel.add(this.skyTextureRadioButton, new GridBagConstraints( 0, 1, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); skyPanel.add(this.skyTextureComponent, new GridBagConstraints( 1, 1, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); add(skyPanel, new GridBagConstraints( 1, 1, 1, 1, 0.5, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, rowInsets, 0, 0)); JPanel renderingPanel = SwingTools.createTitledPanel(preferences.getLocalizedString( Home3DAttributesPanel.class, "renderingPanel.title")); // Third row renderingPanel.add(this.brightnessLabel, new GridBagConstraints( 0, 0, 1, 1, 0, 0, labelAlignment, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); renderingPanel.add(this.brightnessSlider, new GridBagConstraints( 1, 0, 3, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); JPanel brightnessLabelsPanel = new JPanel(new BorderLayout(20, 0)); brightnessLabelsPanel.setOpaque(false); brightnessLabelsPanel.add(this.darkBrightnessLabel, BorderLayout.WEST); brightnessLabelsPanel.add(this.brightBrightnessLabel, BorderLayout.EAST); renderingPanel.add(brightnessLabelsPanel, new GridBagConstraints( 1, 1, 3, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(OperatingSystem.isWindows() ? 0 : -3, 0, 3, 0), 0, 0)); // Last row renderingPanel.add(this.wallsTransparencyLabel, new GridBagConstraints( 0, 2, 1, 1, 0, 0, labelAlignment, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); renderingPanel.add(this.wallsTransparencySlider, new GridBagConstraints( 1, 2, 3, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); JPanel wallsTransparencyLabelsPanel = new JPanel(new BorderLayout(20, 0)); wallsTransparencyLabelsPanel.setOpaque(false); wallsTransparencyLabelsPanel.add(this.opaqueWallsTransparencyLabel, BorderLayout.WEST); wallsTransparencyLabelsPanel.add(this.invisibleWallsTransparencyLabel, BorderLayout.EAST); renderingPanel.add(wallsTransparencyLabelsPanel, new GridBagConstraints( 1, 3, 3, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(OperatingSystem.isWindows() ? 0 : -3, 0, 10, 0), 0, 0)); add(renderingPanel, new GridBagConstraints( 0, 2, 2, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); } /** * Displays this panel in a modal dialog box. */ public void displayView(View parentView) { if (SwingTools.showConfirmDialog((JComponent)parentView, this, this.dialogTitle, this.wallsTransparencySlider) == JOptionPane.OK_OPTION && this.controller != null) { this.controller.modify3DAttributes(); } } }