Files
secondo/Javagui/viewer/spatial3D/LightPanel.java
2026-01-23 17:03:45 +08:00

556 lines
17 KiB
Java

//This file is part of SECONDO.
//Copyright (C) 2004, University in Hagen, Department of Computer Science,
//Database Systems for New Applications.
//SECONDO 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.
//SECONDO 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 SECONDO; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package viewer.spatial3D;
import tools.Reporter;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.media.j3d.PointLight;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.*;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.vecmath.Color3f;
import viewer.Spatial3DViewer;
/**
* a SWING panel class for lighting in Spatial3DViewer
*
*/
public class LightPanel extends JPanel{
private final int SPINNER_COLUMN_SIZE = 10;
private final int MAX_LIGHT_NUM = 10;
public final int STARTING_RADIUS = 500;
private double xChangeFactor;
private double yChangeFactor;
private double zChangeFactor;
private Spatial3DViewer sv;
private JCheckBox enableBox;
private JComboBox lightsBox;
private JSlider radiusSlider;
private JLabel radiusLabel;
private JButton colorButton;
private JButton delButton;
private JButton delAllButton;
private JSpinner verticalSpinner;
private JSpinner horizontalSpinner;
private JSpinner depthSpinner;
private JLabel xPosLabel;
private JLabel yPosLabel;
private JLabel zPosLabel;
private JLabel brightnessLabel;
private JCheckBox mainSW;
private JButton mainColorButton;
private JSlider brightnessSlider;
/**
* constructor
* @param Spatial3Dviewer object as parent
*/
public LightPanel(final Spatial3DViewer _sv){
this.setLayout(new GridBagLayout());
sv = _sv;
xChangeFactor = sv.getTranslateFactor();
yChangeFactor = sv.getTranslateFactor();
zChangeFactor = sv.getZoomFactor();
GridBagConstraints constraint = new GridBagConstraints();
constraint.anchor = GridBagConstraints.LINE_START;
constraint.fill = GridBagConstraints.HORIZONTAL;
//label for main light
constraint.gridx = 0;
constraint.gridy = 0;
this.add(new JLabel("global light"),constraint);
// on/off switch for the ambient light
mainSW = new JCheckBox();
mainSW.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
sv.setMainLightSwitch(mainSW.isSelected());
}
});
mainSW.setText("on / off");
mainSW.setSelected(true);
constraint.gridx = 0;
constraint.gridy = 1;
this.add(mainSW,constraint);
//color chooser for the ambient light
mainColorButton = new JButton("light color");
mainColorButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
Color3f curColor = sv.getLightColor();
Color newColor = JColorChooser.showDialog(sv.getMainFrame(),"Choose the light's color",curColor.get()) ;
if(newColor==null){
Reporter.showError("Please choose a color!");
return;
}
sv.setLightColor(newColor);
}
});
constraint.gridx = 1;
constraint.gridy = 1;
this.add(mainColorButton,constraint);
constraint.gridx=0;
constraint.gridy=2;
this.add(new JSeparator(JSeparator.HORIZONTAL),constraint);
// individual lights
constraint.gridx = 0;
constraint.gridy = 3;
this.add(new JLabel("Indiv. lights"),constraint);
constraint.gridx = 1;
constraint.gridy = 3;
lightsBox = new JComboBox();
lightsBox.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
JComboBox cb = (JComboBox)event.getSource();
int index = cb.getSelectedIndex();
setPanel(index);
}
});
this.add(lightsBox,constraint);
constraint.gridx = 0;
constraint.gridy = 4;
this.add(new JLabel("Enable"),constraint);
enableBox = new JCheckBox();
enableBox.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
LightBranchGroup light = sv.getLight(lightsBox.getSelectedIndex());
if(light==null){
Reporter.showError("wrong light lindex!");
return;
}
light.setEnable(enableBox.isSelected());
}
});
enableBox.setEnabled(false);
constraint.gridx = 1;
constraint.gridy = 4;
this.add(enableBox,constraint);
JButton addButton = new JButton("Add");
addButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0){
if(lightsBox.getItemCount()> MAX_LIGHT_NUM){
Reporter.showError("There are already 10 lights. Please reduce!");
return;
}
sv.addLight();
lightsBox.addItem(makeObj("light " + lightsBox.getItemCount()));
setVisible(true);
activate(true);
lightsBox.setSelectedIndex(lightsBox.getItemCount()-1);
//reset();
}
});
constraint.gridx = 0;
constraint.gridy = 5;
this.add(addButton,constraint);
colorButton = new JButton("Change Color");
colorButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
if(lightsBox.countComponents() == 0) return;
int index = lightsBox.getSelectedIndex();
LightBranchGroup light = sv.getLight(index);
if(light==null){
Reporter.showError("wrong light lindex!");
return;
}
Color lastColor = light.getColor();
Color newColor = JColorChooser.showDialog(sv.getMainFrame(),"Choose the light's color",lastColor) ;
if(newColor==null){
Reporter.showError("Please choose a color!");
return;
}
light.setColor(newColor);
light.setEnable(true);
enableBox.setSelected(true);
//sv.setLightColor(newColor, index);
}
});
colorButton.setEnabled(false);
constraint.gridx = 1;
constraint.gridy = 5;
this.add(colorButton,constraint);
delButton = new JButton("Delete");
delButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0){
if(lightsBox.countComponents() == 0) return;
int index = lightsBox.getSelectedIndex();
sv.delLight(index);
lightsBox.removeItemAt(index);
if(lightsBox.getItemCount()==0) activate(false);
}
});
delButton.setEnabled(false);
constraint.gridx = 0;
constraint.gridy = 6;
this.add(delButton,constraint);
delAllButton = new JButton("Delete All");
delAllButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0){
if(lightsBox.countComponents() == 0) return;
int indeces = lightsBox.getItemCount();
sv.delAllLight(indeces);
lightsBox.removeAllItems();
//reset();
activate(false);
}
});
delAllButton.setEnabled(false);
constraint.gridx = 1;
constraint.gridy = 6;
this.add(delAllButton,constraint);
// slide bar for X position change
constraint.gridwidth = 2;
constraint.gridx = 0;
constraint.gridy = 7;
this.add(new JLabel("X-Pos"),constraint);
SpinnerNumberModel hSpModel = new SpinnerNumberModel(0, Math.round(-Double.MAX_VALUE), Math.round(Double.MAX_VALUE),1);
horizontalSpinner = new JSpinner(hSpModel);
horizontalSpinner.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e){
JSpinner source = (JSpinner)e.getSource();
//Reporter.writeInfo("X-Pos changed");
//if(source.isFocusOwner()){
double xps=((SpinnerNumberModel)source.getModel()).getNumber().doubleValue();
int index = lightsBox.getSelectedIndex();
LightBranchGroup light = sv.getLight(index);
if(light==null){
//Reporter.writeError("wrong light lindex!");
return;
}
light.setX(xps);
light.setEnable(true);
enableBox.setSelected(true);
//sv.setLightX(xps,index);
//Reporter.writeInfo("X-Pos focused");
//}
}
});
((JSpinner.NumberEditor)horizontalSpinner.getEditor()).getTextField().setColumns(SPINNER_COLUMN_SIZE);
constraint.gridy = 8;
horizontalSpinner.setEnabled(false);
this.add(horizontalSpinner,constraint);
// Spinner for Y position change
constraint.gridy = 9;
this.add(new JLabel("Y-Pos"),constraint);
SpinnerNumberModel vSpModel = new SpinnerNumberModel(0, Math.round(-Double.MAX_VALUE), Math.round(Double.MAX_VALUE),1);
verticalSpinner = new JSpinner(vSpModel);
verticalSpinner.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e){
JSpinner source = (JSpinner)e.getSource();
//Reporter.writeInfo("Y-Pos changed");
//if(source.isFocusOwner()){
double yps=((SpinnerNumberModel)source.getModel()).getNumber().doubleValue();
int index = lightsBox.getSelectedIndex();
LightBranchGroup light = sv.getLight(index);
if(light==null){
//Reporter.writeError("wrong light lindex!");
return;
}
light.setY(yps);
light.setEnable(true);
enableBox.setSelected(true);
//sv.setLightY(yps,index);
//Reporter.writeInfo("Y-Pos focused");
//}
}
});
((JSpinner.NumberEditor)verticalSpinner.getEditor()).getTextField().setColumns(SPINNER_COLUMN_SIZE);
constraint.gridy = 10;
verticalSpinner.setEnabled(false);
this.add(verticalSpinner,constraint);
// Spinner for Z position change
constraint.gridy = 11;
this.add(new JLabel("Z-Pos"),constraint);
SpinnerNumberModel dSpModel = new SpinnerNumberModel(0, Math.round(-Double.MAX_VALUE), Math.round(Double.MAX_VALUE),1);
depthSpinner = new JSpinner(dSpModel);
depthSpinner.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e){
JSpinner source = (JSpinner)e.getSource();
//Reporter.writeInfo("Z-Pos changed");
//if(source.isFocusOwner()){
double zps=(int)((SpinnerNumberModel)source.getModel()).getNumber().doubleValue();
int index = lightsBox.getSelectedIndex();
LightBranchGroup light = sv.getLight(index);
if(light==null){
//Reporter.writeError("wrong light lindex!");
return;
}
light.setZ(zps);
light.setEnable(true);
enableBox.setSelected(true);
//sv.setLightZ(zps,index);
//Reporter.writeInfo("Z-Pos focused");
//}
}
});
((JSpinner.NumberEditor)depthSpinner.getEditor()).getTextField().setColumns(SPINNER_COLUMN_SIZE);
constraint.gridy = 12;
depthSpinner.setEnabled(false);
this.add(depthSpinner,constraint);
constraint.gridy = 13;
this.add(new JLabel("Position: 'Ctrl + mouse drag'"),constraint);
// Brightness adjuster
brightnessSlider = new JSlider(JSlider.HORIZONTAL, 0, LightBranchGroup.MAX_LEVEL, (LightBranchGroup.MAX_LEVEL/2));
brightnessSlider.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e){
JSlider source = (JSlider)e.getSource();
if(!source.getValueIsAdjusting()){
int index = lightsBox.getSelectedIndex();
int brightness = (int)source.getValue();
LightBranchGroup light = sv.getLight(index);
if(light==null){
Reporter.showError("wrong light lindex!");
return;
}
light.setEnable(true);
enableBox.setSelected(true);
light.setBrightness(brightness);
//sv.setBrightness(brightness, index);
brightnessLabel.setText("Brightness: " + brightness);
}
}
});
constraint.gridy = 14;
brightnessSlider.setEnabled(false);
this.add(brightnessSlider,constraint);
constraint.gridy = 15;
brightnessLabel = new JLabel("Brightness: " + LightBranchGroup.MAX_LEVEL/2);
this.add(brightnessLabel,constraint);
radiusSlider = new JSlider(JSlider.HORIZONTAL, 0, Integer.MAX_VALUE, STARTING_RADIUS);
radiusSlider.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
int fps = (int)source.getValue();
int index = lightsBox.getSelectedIndex();
LightBranchGroup light = sv.getLight(index);
if(light==null){
Reporter.showError("wrong light lindex!");
return;
}
light.setArea(fps);
//sv.setLightArea(fps,index);
light.setEnable(true);
enableBox.setSelected(true);
radiusLabel.setText("radius: " + (int)light.getArea());
}
}
});
constraint.gridy = 16;
radiusSlider.setEnabled(false);
this.add(radiusSlider,constraint);
constraint.gridy = 17;
radiusLabel = new JLabel("radius: " + STARTING_RADIUS);
this.add(radiusLabel,constraint);
}
private Object makeObj(final String item) {
return new Object() { public String toString() { return item; } };
}
private void reset(){
enableBox.setSelected(true);
radiusSlider.setValue(STARTING_RADIUS);
brightnessSlider.setValue(LightBranchGroup.MAX_LEVEL/2);
verticalSpinner.setValue(0);
horizontalSpinner.setValue(0);
depthSpinner.setValue(0);
radiusLabel.setText("radius: " + STARTING_RADIUS);
brightnessLabel.setText("Brightness: " + LightBranchGroup.MAX_LEVEL/2);
}
private void setPanel(int index){
LightBranchGroup light = sv.getLight(index);
if(light==null)return;
sv.setLightMouseMove(index);
if(light==null){
Reporter.showError("wrong light lindex!");
return;
}
enableBox.setSelected(light.getEnable());
radiusSlider.setValue((int)light.getArea());
radiusLabel.setText("radius: " + (int)light.getArea());
brightnessSlider.setValue(light.getBrightness());
brightnessLabel.setText("Brightness: " + light.getBrightness());
verticalSpinner.setValue(light.getPosition().y);
horizontalSpinner.setValue(light.getPosition().x);
depthSpinner.setValue(light.getPosition().z);
}
/**
* set activate/deactivate panel
* @para on/off
*/
public void activate(boolean act){
enableBox.setEnabled(act);
//lightsBox.setEditable(act);
radiusSlider.setEnabled(act);
brightnessSlider.setEnabled(act);
colorButton.setEnabled(act);
delButton.setEnabled(act);
delAllButton.setEnabled(act);
verticalSpinner.setEnabled(act);
horizontalSpinner.setEnabled(act);
depthSpinner.setEnabled(act);
}
/**
* to set x-position value the light
* @param x value
*/
public void setX(double value){
((SpinnerNumberModel)horizontalSpinner.getModel()).setValue((double)value);
}
/**
* to set y-position value the light
* @param y value
*/
public void setY(double value){
((SpinnerNumberModel)verticalSpinner.getModel()).setValue((double)value);
}
/**
* to set z-position value the light
* @param z value
*/
public void setZ(double value){
((SpinnerNumberModel)depthSpinner.getModel()).setValue((double)value);
}
/**
* to set changefactor of x-movement
* @param factor
*/
public void setXChangeFactor(double factor){
xChangeFactor = factor;
}
/**
* to set changefactor of y-movement
* @param factor
*/
public void setYChangeFactor(double factor){
yChangeFactor = factor;
}
/**
* to set changefactor of z-movement
* @param factor
*/
public void setZChangeFactor(double factor){
zChangeFactor = factor;
}
/**
* getter changefactor of X
* @return change factor of x-movement
*/
public double getXChangeFactor(){
return xChangeFactor;
}
/**
* getter changefactor of Y movement
* @return change factor of y-movement
*/
public double getYChangeFactor(){
return yChangeFactor;
}
/**
* getter changefactor of Z movement
* @return change factor of z-movement
*/
public double getZChangeFactor(){
return zChangeFactor;
}
}