/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <https://www.compadre.org/osp/> */ package org.opensourcephysics.display3d.core; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.NumberFormat; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import org.opensourcephysics.display3d.core.interaction.InteractionEvent; import org.opensourcephysics.display3d.core.interaction.InteractionListener; import org.opensourcephysics.tools.ToolsRes; /** * <p>Title: CameraInspector</p> * <p>Description: This class creates an inspector for the camera. * The inspector is provided in a javax.swing.JPanel, so that * it can be used in other applications. A convenience class * is provided to create a JFrame that contains the inspector. * </p> * * @author Francisco Esquembre * @version July 2005 * @see Camera */ public class CameraInspector extends JPanel implements InteractionListener { private DrawingPanel3D panel = null; private Camera camera = null; private NumberFormat format = new java.text.DecimalFormat("0.000"); //$NON-NLS-1$ private JTextField xField, yField, zField; private JTextField focusxField, focusyField, focuszField; private JTextField azimuthField, altitudeField; private JTextField rotationField, distanceField; private JRadioButton perspectiveRB, noperspectiveRB, planarxyRB, planarxzRB, planaryzRB; private java.util.AbstractList<ActionListener> listeners = new java.util.ArrayList<ActionListener>(); /** * Creates a frame and, inside it, a CameraInspector. * @param panel DrawingPanel3D The drawing panel 3D with the inspected camera * @return JFrame */ static public JFrame createFrame(DrawingPanel3D panel) { return new CameraInspectorFrame(ToolsRes.getString("CameraInspector.FrameTitle"), new CameraInspector(panel)); //$NON-NLS-1$ } /** * Creates a frame with the given CameraInspector. * @param inspector CameraInspector The inspector provided * @return JFrame */ static public JFrame createFrame(CameraInspector inspector) { return new CameraInspectorFrame(ToolsRes.getString("CameraInspector.FrameTitle"), inspector); //$NON-NLS-1$ } /** * Creates a JPanel with a CameraInspector * @param panel DrawingPanel3D The drawing panel 3D with the inspected camera */ public CameraInspector(DrawingPanel3D panel) { this.panel = panel; this.camera = panel.getCamera(); panel.addInteractionListener(this); ActionListener fieldListener = new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { String cmd = evt.getActionCommand(); JTextField field = (JTextField) evt.getSource(); double value = 0.0; try { value = format.parse(field.getText()).doubleValue(); } catch(java.text.ParseException exc) { value = 0.0; } if(cmd.equals("x")) { //$NON-NLS-1$ camera.setXYZ(value, camera.getY(), camera.getZ()); } else if(cmd.equals("y")) { //$NON-NLS-1$ camera.setXYZ(camera.getX(), value, camera.getZ()); } else if(cmd.equals("z")) { //$NON-NLS-1$ camera.setXYZ(camera.getX(), camera.getY(), value); } else if(cmd.equals("focusx")) { //$NON-NLS-1$ camera.setFocusXYZ(value, camera.getFocusY(), camera.getFocusZ()); } else if(cmd.equals("focusy")) { //$NON-NLS-1$ camera.setFocusXYZ(camera.getFocusX(), value, camera.getFocusZ()); } else if(cmd.equals("focusz")) { //$NON-NLS-1$ camera.setFocusXYZ(camera.getFocusX(), camera.getFocusY(), value); } else if(cmd.equals("azimuth")) { //$NON-NLS-1$ camera.setAzimuth(value); } else if(cmd.equals("altitude")) { //$NON-NLS-1$ camera.setAltitude(value); } else if(cmd.equals("rotation")) { //$NON-NLS-1$ camera.setRotation(value); } else if(cmd.equals("screen")) { //$NON-NLS-1$ camera.setDistanceToScreen(value); } CameraInspector.this.panel.repaint(); updateFields(); ActionEvent event = new ActionEvent(CameraInspector.this, ActionEvent.ACTION_PERFORMED, "FieldChange"); //$NON-NLS-1$ for(java.util.Iterator<ActionListener> it = listeners.iterator(); it.hasNext(); ) { (it.next()).actionPerformed(event); } } }; ActionListener buttonListener = new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { String cmd = evt.getActionCommand(); if(cmd.equals("reset")) { //$NON-NLS-1$ camera.reset(); CameraInspector.this.panel.repaint(); updateFields(); } else if(cmd.equals("perspective")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_PERSPECTIVE); } else if(cmd.equals("perspective_on")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_PERSPECTIVE_ON); } else if(cmd.equals("no_perspective")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_NO_PERSPECTIVE); } else if(cmd.equals("perspective_off")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_PERSPECTIVE_OFF); } else if(cmd.equals("planarXY")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_PLANAR_XY); } else if(cmd.equals("planarXZ")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_PLANAR_XZ); } else if(cmd.equals("planarYZ")) { //$NON-NLS-1$ camera.setProjectionMode(Camera.MODE_PLANAR_YZ); } camera.reset(); ActionEvent event = new ActionEvent(CameraInspector.this, ActionEvent.ACTION_PERFORMED, "ButtonChange"); //$NON-NLS-1$ for(java.util.Iterator<ActionListener> it = listeners.iterator(); it.hasNext(); ) { (it.next()).actionPerformed(event); } } }; setLayout(new BorderLayout()); JPanel projectionPanel = new JPanel(new GridLayout(2, 3)); projectionPanel.setBorder(new TitledBorder(ToolsRes.getString("CameraInspector.ProjectionMode"))); //$NON-NLS-1$ ButtonGroup group = new ButtonGroup(); perspectiveRB = new JRadioButton(ToolsRes.getString("CameraInspector.Perspective")); //$NON-NLS-1$ perspectiveRB.setActionCommand("perspective"); //$NON-NLS-1$ perspectiveRB.addActionListener(buttonListener); projectionPanel.add(perspectiveRB); group.add(perspectiveRB); planarxyRB = new JRadioButton(ToolsRes.getString("CameraInspector.PlanarXY")); //$NON-NLS-1$ planarxyRB.setActionCommand("planarXY"); //$NON-NLS-1$ planarxyRB.addActionListener(buttonListener); projectionPanel.add(planarxyRB); group.add(planarxyRB); planaryzRB = new JRadioButton(ToolsRes.getString("CameraInspector.PlanarYZ")); //$NON-NLS-1$ planaryzRB.setActionCommand("planarYZ"); //$NON-NLS-1$ planaryzRB.addActionListener(buttonListener); projectionPanel.add(planaryzRB); group.add(planaryzRB); noperspectiveRB = new JRadioButton(ToolsRes.getString("CameraInspector.NoPerspective")); //$NON-NLS-1$ noperspectiveRB.setActionCommand("no_perspective"); //$NON-NLS-1$ noperspectiveRB.addActionListener(buttonListener); projectionPanel.add(noperspectiveRB); group.add(noperspectiveRB); planarxzRB = new JRadioButton(ToolsRes.getString("CameraInspector.PlanarXZ")); //$NON-NLS-1$ planarxzRB.setActionCommand("planarXZ"); //$NON-NLS-1$ planarxzRB.addActionListener(buttonListener); projectionPanel.add(planarxzRB); group.add(planarxzRB); JPanel topPanel = new JPanel(new BorderLayout()); topPanel.add(projectionPanel, BorderLayout.CENTER); add(projectionPanel, BorderLayout.NORTH); JPanel labelPanel = new JPanel(new GridLayout(0, 1)); JPanel fieldPanel = new JPanel(new GridLayout(0, 1)); JPanel label2Panel = new JPanel(new GridLayout(0, 1)); JPanel field2Panel = new JPanel(new GridLayout(0, 1)); xField = createRow(labelPanel, fieldPanel, "X", fieldListener); //$NON-NLS-1$ yField = createRow(labelPanel, fieldPanel, "Y", fieldListener); //$NON-NLS-1$ zField = createRow(labelPanel, fieldPanel, "Z", fieldListener); //$NON-NLS-1$ focusxField = createRow(label2Panel, field2Panel, "FocusX", fieldListener); //$NON-NLS-1$ focusyField = createRow(label2Panel, field2Panel, "FocusY", fieldListener); //$NON-NLS-1$ focuszField = createRow(label2Panel, field2Panel, "FocusZ", fieldListener); //$NON-NLS-1$ azimuthField = createRow(labelPanel, fieldPanel, "Azimuth", fieldListener); //$NON-NLS-1$ altitudeField = createRow(labelPanel, fieldPanel, "Altitude", fieldListener); //$NON-NLS-1$ // createRow (label2Panel, field2Panel, null,fieldListener); // emptyrow rotationField = createRow(label2Panel, field2Panel, "Rotation", fieldListener); //$NON-NLS-1$ distanceField = createRow(label2Panel, field2Panel, "Screen", fieldListener); //$NON-NLS-1$ // createRow (label2Panel, field2Panel, null,fieldListener); // emptyrow JPanel leftPanel = new JPanel(new BorderLayout()); leftPanel.add(labelPanel, BorderLayout.WEST); leftPanel.add(fieldPanel, BorderLayout.CENTER); JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.add(label2Panel, BorderLayout.WEST); rightPanel.add(field2Panel, BorderLayout.CENTER); JPanel centerPanel = new JPanel(new GridLayout(1, 0)); centerPanel.setBorder(new TitledBorder(ToolsRes.getString("CameraInspector.CameraParameters"))); //$NON-NLS-1$ centerPanel.add(leftPanel); centerPanel.add(rightPanel); add(centerPanel, BorderLayout.CENTER); JButton resetButton = new JButton(ToolsRes.getString("CameraInspector.ResetCamera")); //$NON-NLS-1$ resetButton.setActionCommand("reset"); //$NON-NLS-1$ resetButton.addActionListener(buttonListener); add(resetButton, BorderLayout.SOUTH); updateFields(); } /** * Sets the format for the fields in the inspector * @param format NumberFormat */ public void setFormat(NumberFormat format) { this.format = format; } /** * Adds a listener to any change in the camera settings * @param defaultFormat NumberFormat */ public void addActionListener(ActionListener listener) { listeners.add(listener); } /** * Removes a listener to any change in the camera settings * @param defaultFormat NumberFormat */ public void removeActionListener(ActionListener listener) { listeners.remove(listener); } /** * Public as result of the implementation. Not to be used directly by final users. * @param _event InteractionEvent */ public void interactionPerformed(InteractionEvent _event) { if(_event.getSource()!=panel) { return; } if(_event.getInfo()!=null) { return; // It is not changing the camera } updateFields(); } public void updateFields() { switch(camera.getProjectionMode()) { default : case Camera.MODE_PERSPECTIVE : case Camera.MODE_PERSPECTIVE_ON : perspectiveRB.setSelected(true); break; case Camera.MODE_NO_PERSPECTIVE : case Camera.MODE_PERSPECTIVE_OFF : noperspectiveRB.setSelected(true); break; case Camera.MODE_PLANAR_XY : planarxyRB.setSelected(true); break; case Camera.MODE_PLANAR_XZ : planarxzRB.setSelected(true); break; case Camera.MODE_PLANAR_YZ : planaryzRB.setSelected(true); break; } xField.setText(format.format(camera.getX())); yField.setText(format.format(camera.getY())); zField.setText(format.format(camera.getZ())); focusxField.setText(format.format(camera.getFocusX())); focusyField.setText(format.format(camera.getFocusY())); focuszField.setText(format.format(camera.getFocusZ())); azimuthField.setText(format.format(camera.getAzimuth())); altitudeField.setText(format.format(camera.getAltitude())); rotationField.setText(format.format(camera.getRotation())); distanceField.setText(format.format(camera.getDistanceToScreen())); } static private JTextField createRow(JPanel labelParent, JPanel fieldParent, String labelText, ActionListener listener) { if(labelText==null) { // create an empty row labelParent.add(new JLabel()); fieldParent.add(new JLabel()); return null; } // if(labelText.length()<14) {} JLabel label = new JLabel(ToolsRes.getString("CameraInspector."+labelText)); //$NON-NLS-1$ label.setHorizontalAlignment(SwingConstants.CENTER); label.setBorder(new EmptyBorder(0, 3, 0, 3)); JTextField field = new JTextField(4); field.setActionCommand(labelText.toLowerCase()); field.addActionListener(listener); labelParent.add(label); fieldParent.add(field); return field; } } class CameraInspectorFrame extends JFrame { private CameraInspector inspector; /** * Constructor CameraInspectorFrame * @param title * @param anInspector */ public CameraInspectorFrame(String title, CameraInspector anInspector) { super(title); inspector = anInspector; getContentPane().setLayout(new BorderLayout()); getContentPane().add(inspector, BorderLayout.CENTER); pack(); } public void setVisible(boolean vis) { super.setVisible(vis); if(vis) { inspector.updateFields(); } } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2019 The Open Source Physics project * https://www.compadre.org/osp */