use of org.concord.energy3d.model.Mirror in project energy3d by concord-consortium.
the class PopupMenuForHeliostat method getPopupMenu.
static JPopupMenu getPopupMenu() {
if (popupMenuForHeliostat == null) {
final JCheckBoxMenuItem cbmiDisableEditPoint = new JCheckBoxMenuItem("Disable Edit Point");
cbmiDisableEditPoint.addItemListener(new ItemListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void itemStateChanged(final ItemEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final boolean disabled = cbmiDisableEditPoint.isSelected();
final Mirror m = (Mirror) selectedPart;
final String partInfo = m.toString().substring(0, m.toString().indexOf(')') + 1);
final JPanel gui = new JPanel(new BorderLayout(0, 20));
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.SOUTH);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final String title = "<html>" + (disabled ? "Disable" : "Enable") + " edit point for " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>Disable the edit point of a heliostat prevents it from<br>being unintentionally moved.<hr></html>";
final Object[] options = new Object[] { "OK", "Cancel" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[0]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), (disabled ? "Disable" : "Enable") + " Edit Point");
dialog.setVisible(true);
if (optionPane.getValue() == options[0]) {
if (rb1.isSelected()) {
final LockEditPointsCommand c = new LockEditPointsCommand(m);
m.setLockEdit(disabled);
SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
final Foundation foundation = m.getTopContainer();
final LockEditPointsOnFoundationCommand c = new LockEditPointsOnFoundationCommand(foundation, m.getClass());
foundation.setLockEditForClass(disabled, m.getClass());
SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
final LockEditPointsForClassCommand c = new LockEditPointsForClassCommand(m);
Scene.getInstance().setLockEditForClass(disabled, m.getClass());
SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 2;
}
SceneManager.getInstance().refresh();
Scene.getInstance().setEdited(true);
}
}
});
final JCheckBoxMenuItem cbmiDrawSunBeam = new JCheckBoxMenuItem("Draw Sun Beam");
cbmiDrawSunBeam.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final Mirror m = (Mirror) selectedPart;
final ShowSunBeamCommand c = new ShowSunBeamCommand(m);
m.setSunBeamVisible(cbmiDrawSunBeam.isSelected());
m.draw();
SceneManager.getInstance().refresh();
SceneManager.getInstance().getUndoManager().addEdit(c);
Scene.getInstance().setEdited(true);
}
});
final JMenuItem miSetHeliostat = new JMenuItem("Set Target Tower...");
miSetHeliostat.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final Mirror m = (Mirror) selectedPart;
final String partInfo = m.toString().substring(0, m.toString().indexOf(')') + 1);
final JPanel gui = new JPanel(new BorderLayout(0, 20));
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.SOUTH);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final List<Foundation> foundations = Scene.getInstance().getAllFoundations();
final JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
}
});
comboBox.addItem("None");
for (final Foundation x : foundations) {
if (!x.getChildren().isEmpty()) {
comboBox.addItem(x.getId() + "");
}
}
if (m.getReceiver() != null) {
comboBox.setSelectedItem(m.getReceiver().getId() + "");
}
gui.add(comboBox, BorderLayout.CENTER);
final String title = "<html>Select the ID of the foundation<br>of the target tower for " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>The sunlight reflected by the mirror(s) of this heliostat will<br>focus on the top of the target tower.<hr></html>";
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Heliostat Target");
while (true) {
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
Foundation target = null;
if (comboBox.getSelectedIndex() > 0) {
boolean ok = true;
int id = -1;
try {
id = Integer.parseInt((String) comboBox.getSelectedItem());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), comboBox.getSelectedItem() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
final HousePart p = Scene.getInstance().getPart(id);
if (p instanceof Foundation) {
target = (Foundation) p;
} else {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "ID must be that of a foundation.", "ID Error", JOptionPane.ERROR_MESSAGE);
}
}
}
boolean changed = target != m.getReceiver();
if (rb1.isSelected()) {
if (changed) {
final Foundation oldTarget = m.getReceiver();
final ChangeHeliostatTargetCommand c = new ChangeHeliostatTargetCommand(m);
m.setReceiver(target);
m.draw();
if (oldTarget != null) {
oldTarget.drawSolarReceiver();
}
SceneManager.getInstance().refresh();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
final Foundation foundation = m.getTopContainer();
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (target != x.getReceiver()) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationHeliostatTargetCommand c = new ChangeFoundationHeliostatTargetCommand(foundation);
foundation.setTargetForHeliostats(target);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (target != x.getReceiver()) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeTargetForAllHeliostatsCommand c = new ChangeTargetForAllHeliostatsCommand();
Scene.getInstance().setTargetForAllHeliostats(target);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
if (target != null) {
target.drawSolarReceiver();
}
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
});
final JMenuItem miZenith = new JMenuItem("Tilt Angle...");
miZenith.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final Mirror m = (Mirror) selectedPart;
final String partInfo = m.toString().substring(0, m.toString().indexOf(')') + 1);
final String title = "<html>Tilt Angle of " + partInfo + " (°)</html>";
final String footnote = "<html><hr><font size=2>The tilt angle of the mirror of a heliostat is the angle between its surface and the base surface.<br>The tilt angle must be between -90° and 90°.<hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(m.getTiltAngle()));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Heliostat Mirror Tilt Angle");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (val < -90 || val > 90) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "The tilt angle must be between -90 and 90 degrees.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
if (Util.isZero(val - 90)) {
val = 89.999;
} else if (Util.isZero(val + 90)) {
val = -89.999;
}
boolean changed = Math.abs(val - m.getTiltAngle()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeTiltAngleCommand c = new ChangeTiltAngleCommand(m);
m.setTiltAngle(val);
m.draw();
SceneManager.getInstance().refresh();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
final Foundation foundation = m.getTopContainer();
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (Math.abs(val - x.getTiltAngle()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationHeliostatTiltAngleCommand c = new ChangeFoundationHeliostatTiltAngleCommand(foundation);
foundation.setTiltAngleForHeliostats(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (Math.abs(val - x.getTiltAngle()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeTiltAngleForAllHeliostatsCommand c = new ChangeTiltAngleForAllHeliostatsCommand();
Scene.getInstance().setTiltAngleForAllHeliostats(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
final JMenuItem miAzimuth = new JMenuItem("Azimuth...");
miAzimuth.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Mirror mirror = (Mirror) selectedPart;
final Foundation foundation = mirror.getTopContainer();
final String title = "<html>Azimuth Angle (°) of " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>The azimuth angle is measured clockwise from the true north.<hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
double a = mirror.getRelativeAzimuth() + foundation.getAzimuth();
if (a > 360) {
a -= 360;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(a));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Heliostat Azimuth");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
a = val - foundation.getAzimuth();
if (a < 0) {
a += 360;
}
boolean changed = Math.abs(a - mirror.getRelativeAzimuth()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeAzimuthCommand c = new ChangeAzimuthCommand(mirror);
mirror.setRelativeAzimuth(a);
mirror.draw();
SceneManager.getInstance().refresh();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (Math.abs(a - x.getRelativeAzimuth()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationHeliostatAzimuthCommand c = new ChangeFoundationHeliostatAzimuthCommand(foundation);
foundation.setAzimuthForHeliostats(a);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (Math.abs(a - x.getRelativeAzimuth()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeAzimuthForAllHeliostatsCommand c = new ChangeAzimuthForAllHeliostatsCommand();
Scene.getInstance().setAzimuthForAllHeliostats(a);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
});
final JMenuItem miSize = new JMenuItem("Size...");
miSize.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final Mirror m = (Mirror) selectedPart;
final Foundation foundation = m.getTopContainer();
final String partInfo = m.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final JPanel gui = new JPanel(new BorderLayout());
final JPanel inputPanel = new JPanel(new GridLayout(2, 2, 5, 5));
gui.add(inputPanel, BorderLayout.CENTER);
inputPanel.add(new JLabel("Width: "));
final JTextField widthField = new JTextField(threeDecimalsFormat.format(m.getMirrorWidth()));
inputPanel.add(widthField);
inputPanel.add(new JLabel("Length: "));
final JTextField heightField = new JTextField(threeDecimalsFormat.format(m.getMirrorHeight()));
inputPanel.add(heightField);
inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
final JPanel scopePanel = new JPanel();
scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.Y_AXIS));
scopePanel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
scopePanel.add(rb1);
scopePanel.add(rb2);
scopePanel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
gui.add(scopePanel, BorderLayout.NORTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { "Set size for " + partInfo, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Heliostat Size");
while (true) {
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double w = 0, h = 0;
boolean ok = true;
try {
w = Double.parseDouble(widthField.getText());
h = Double.parseDouble(heightField.getText());
} catch (final NumberFormatException x) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid input!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (w < 1 || w > 50) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Width must be between 1 and 50 m.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else if (h < 1 || h > 50) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Height must be between 1 and 50 m.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
boolean changed = Math.abs(w - m.getMirrorWidth()) > 0.000001 || Math.abs(h - m.getMirrorHeight()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final SetPartSizeCommand c = new SetPartSizeCommand(m);
m.setMirrorWidth(w);
m.setMirrorHeight(h);
m.draw();
SceneManager.getInstance().refresh();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (Math.abs(w - x.getMirrorWidth()) > 0.000001 || Math.abs(h - x.getMirrorHeight()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final SetSizeForHeliostatsOnFoundationCommand c = new SetSizeForHeliostatsOnFoundationCommand(foundation);
foundation.setSizeForHeliostats(w, h);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (Math.abs(w - x.getMirrorWidth()) > 0.000001 || Math.abs(h - x.getMirrorHeight()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final SetSizeForAllHeliostatsCommand c = new SetSizeForAllHeliostatsCommand();
Scene.getInstance().setSizeForAllHeliostats(w, h);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
final JMenuItem miBaseHeight = new JMenuItem("Base Height...");
miBaseHeight.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Mirror m = (Mirror) selectedPart;
final Foundation foundation = m.getTopContainer();
final String title = "<html>Base Height (m) of " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(m.getBaseHeight() * Scene.getInstance().getAnnotationScale()));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Heliostat Base Height");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText()) / Scene.getInstance().getAnnotationScale();
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
boolean changed = Math.abs(val - m.getBaseHeight()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeBaseHeightCommand c = new ChangeBaseHeightCommand(m);
m.setBaseHeight(val);
m.draw();
SceneManager.getInstance().refresh();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (Math.abs(val - x.getBaseHeight()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationSolarCollectorBaseHeightCommand c = new ChangeFoundationSolarCollectorBaseHeightCommand(foundation, m.getClass());
foundation.setBaseHeightForHeliostats(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (Math.abs(val - x.getBaseHeight()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeBaseHeightForAllSolarCollectorsCommand c = new ChangeBaseHeightForAllSolarCollectorsCommand(m.getClass());
Scene.getInstance().setBaseHeightForAllHeliostats(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
});
final JMenu labelMenu = new JMenu("Label");
final JCheckBoxMenuItem miLabelNone = new JCheckBoxMenuItem("None", true);
miLabelNone.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (miLabelNone.isSelected()) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Mirror) {
final Mirror m = (Mirror) selectedPart;
final SetHeliostatLabelCommand c = new SetHeliostatLabelCommand(m);
m.clearLabels();
m.draw();
SceneManager.getInstance().getUndoManager().addEdit(c);
Scene.getInstance().setEdited(true);
SceneManager.getInstance().refresh();
}
}
}
});
labelMenu.add(miLabelNone);
final JCheckBoxMenuItem miLabelCustom = new JCheckBoxMenuItem("Custom");
miLabelCustom.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Mirror) {
final Mirror m = (Mirror) selectedPart;
final SetHeliostatLabelCommand c = new SetHeliostatLabelCommand(m);
m.setLabelCustom(miLabelCustom.isSelected());
if (m.getLabelCustom()) {
m.setLabelCustomText(JOptionPane.showInputDialog(MainFrame.getInstance(), "Custom Text", m.getLabelCustomText()));
}
m.draw();
SceneManager.getInstance().getUndoManager().addEdit(c);
Scene.getInstance().setEdited(true);
SceneManager.getInstance().refresh();
}
}
});
labelMenu.add(miLabelCustom);
final JCheckBoxMenuItem miLabelId = new JCheckBoxMenuItem("ID");
miLabelId.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Mirror) {
final Mirror m = (Mirror) selectedPart;
final SetHeliostatLabelCommand c = new SetHeliostatLabelCommand(m);
m.setLabelId(miLabelId.isSelected());
m.draw();
SceneManager.getInstance().getUndoManager().addEdit(c);
Scene.getInstance().setEdited(true);
SceneManager.getInstance().refresh();
}
}
});
labelMenu.add(miLabelId);
final JCheckBoxMenuItem miLabelEnergyOutput = new JCheckBoxMenuItem("Energy Output");
miLabelEnergyOutput.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Mirror) {
final Mirror m = (Mirror) selectedPart;
final SetHeliostatLabelCommand c = new SetHeliostatLabelCommand(m);
m.setLabelEnergyOutput(miLabelEnergyOutput.isSelected());
m.draw();
SceneManager.getInstance().getUndoManager().addEdit(c);
Scene.getInstance().setEdited(true);
SceneManager.getInstance().refresh();
}
}
});
labelMenu.add(miLabelEnergyOutput);
final JMenu textureMenu = new JMenu("Texture");
final ButtonGroup textureButtonGroup = new ButtonGroup();
final JRadioButtonMenuItem texture1MenuItem = new JRadioButtonMenuItem("Whole Mirror");
texture1MenuItem.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final ChangeHeliostatTextureCommand c = new ChangeHeliostatTextureCommand();
Scene.getInstance().setHeliostatTextureType(Mirror.TEXTURE_ONE_MIRROR);
Scene.getInstance().setEdited(true);
if (MainPanel.getInstance().getEnergyButton().isSelected()) {
MainPanel.getInstance().getEnergyButton().setSelected(false);
}
Scene.getInstance().redrawAll();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
});
textureButtonGroup.add(texture1MenuItem);
textureMenu.add(texture1MenuItem);
final JRadioButtonMenuItem texture2MenuItem = new JRadioButtonMenuItem("2 \u00D7 1 Mirrors");
texture2MenuItem.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final ChangeHeliostatTextureCommand c = new ChangeHeliostatTextureCommand();
Scene.getInstance().setHeliostatTextureType(Mirror.TEXTURE_2X1_MIRRORS);
Scene.getInstance().setEdited(true);
if (MainPanel.getInstance().getEnergyButton().isSelected()) {
MainPanel.getInstance().getEnergyButton().setSelected(false);
}
Scene.getInstance().redrawAll();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
});
textureButtonGroup.add(texture2MenuItem);
textureMenu.add(texture2MenuItem);
final JRadioButtonMenuItem texture3MenuItem = new JRadioButtonMenuItem("1 \u00D7 2 Mirrors");
texture3MenuItem.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final ChangeHeliostatTextureCommand c = new ChangeHeliostatTextureCommand();
Scene.getInstance().setHeliostatTextureType(Mirror.TEXTURE_1X2_MIRRORS);
Scene.getInstance().setEdited(true);
if (MainPanel.getInstance().getEnergyButton().isSelected()) {
MainPanel.getInstance().getEnergyButton().setSelected(false);
}
Scene.getInstance().redrawAll();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
});
textureButtonGroup.add(texture3MenuItem);
textureMenu.add(texture3MenuItem);
final JRadioButtonMenuItem texture4MenuItem = new JRadioButtonMenuItem("7 \u00D7 5 Mirrors");
texture4MenuItem.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final ChangeHeliostatTextureCommand c = new ChangeHeliostatTextureCommand();
Scene.getInstance().setHeliostatTextureType(Mirror.TEXTURE_7X5_MIRRORS);
Scene.getInstance().setEdited(true);
if (MainPanel.getInstance().getEnergyButton().isSelected()) {
MainPanel.getInstance().getEnergyButton().setSelected(false);
}
Scene.getInstance().redrawAll();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
});
textureButtonGroup.add(texture4MenuItem);
textureMenu.add(texture4MenuItem);
textureMenu.addMenuListener(new MenuListener() {
@Override
public void menuCanceled(final MenuEvent e) {
}
@Override
public void menuDeselected(final MenuEvent e) {
SceneManager.getInstance().refresh();
}
@Override
public void menuSelected(final MenuEvent e) {
switch(Scene.getInstance().getHeliostatTextureType()) {
default:
Util.selectSilently(texture1MenuItem, true);
break;
case Mirror.TEXTURE_2X1_MIRRORS:
Util.selectSilently(texture2MenuItem, true);
break;
case Mirror.TEXTURE_1X2_MIRRORS:
Util.selectSilently(texture3MenuItem, true);
break;
case Mirror.TEXTURE_7X5_MIRRORS:
Util.selectSilently(texture4MenuItem, true);
break;
}
}
});
popupMenuForHeliostat = createPopupMenu(true, true, new Runnable() {
@Override
public void run() {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final Mirror m = (Mirror) selectedPart;
if (m.getReceiver() == null) {
miZenith.setEnabled(true);
miAzimuth.setEnabled(true);
} else {
miZenith.setEnabled(false);
miAzimuth.setEnabled(false);
}
Util.selectSilently(cbmiDisableEditPoint, m.getLockEdit());
Util.selectSilently(cbmiDrawSunBeam, m.isSunBeamVisible());
Util.selectSilently(miLabelNone, !m.isLabelVisible());
Util.selectSilently(miLabelCustom, m.getLabelCustom());
Util.selectSilently(miLabelId, m.getLabelId());
Util.selectSilently(miLabelEnergyOutput, m.getLabelEnergyOutput());
}
});
final JMenuItem miReflectance = new JMenuItem("Reflectance...");
miReflectance.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Mirror m = (Mirror) selectedPart;
final String title = "<html>Reflectance (%) of " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>Reflectance can be affected by pollen and dust.<hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(m.getReflectance() * 100));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Heliostat Mirror Reflectance");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (val < 50 || val > 99) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Heliostat mirror reflectance must be between 50% and 99%.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
boolean changed = Math.abs(val * 0.01 - m.getReflectance()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeSolarReflectorReflectanceCommand c = new ChangeSolarReflectorReflectanceCommand(m);
m.setReflectance(val * 0.01);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
final Foundation foundation = m.getTopContainer();
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (Math.abs(val * 0.01 - x.getReflectance()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationSolarReflectorReflectanceCommand c = new ChangeFoundationSolarReflectorReflectanceCommand(foundation, m.getClass());
foundation.setReflectanceForHeliostatMirrors(val * 0.01);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (Math.abs(val * 0.01 - x.getReflectance()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeReflectanceForAllSolarReflectorsCommand c = new ChangeReflectanceForAllSolarReflectorsCommand(m.getClass());
Scene.getInstance().setReflectanceForAllSolarReflectors(val * 0.01, m.getClass());
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
final JMenuItem miApertureRatio = new JMenuItem("Aperture Ratio...");
miApertureRatio.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Mirror m = (Mirror) selectedPart;
final String title = "<html>Aperture percentage of " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>The percentage of the effective area for reflection<br>after deducting the area of gaps, frames, etc.<hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Heliostat", true);
final JRadioButton rb2 = new JRadioButton("All Heliostats on this Foundation");
final JRadioButton rb3 = new JRadioButton("All Heliostats");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(m.getOpticalEfficiency() * 100));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Aperture Percentage of Heliostat Surface");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (val < 70 || val > 100) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Heliostat aperature percentage must be between 70% and 100%.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
boolean changed = Math.abs(val * 0.01 - m.getOpticalEfficiency()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeSolarReflectorOpticalEfficiencyCommand c = new ChangeSolarReflectorOpticalEfficiencyCommand(m);
m.setOpticalEfficiency(val * 0.01);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
final Foundation foundation = m.getTopContainer();
if (!changed) {
for (final Mirror x : foundation.getHeliostats()) {
if (Math.abs(val * 0.01 - x.getOpticalEfficiency()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationSolarReflectorOpticalEfficiencyCommand c = new ChangeFoundationSolarReflectorOpticalEfficiencyCommand(foundation, m.getClass());
foundation.setOpticalEfficiencyForSolarReflectors(val * 0.01, m.getClass());
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Mirror x : Scene.getInstance().getAllHeliostats()) {
if (Math.abs(val * 0.01 - x.getOpticalEfficiency()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeOpticalEfficiencyForAllSolarReflectorsCommand c = new ChangeOpticalEfficiencyForAllSolarReflectorsCommand(m.getClass());
Scene.getInstance().setOpticalEfficiencyForAllSolarReflectors(val * 0.01, m.getClass());
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
final JMenuItem miConversionEfficiency = new JMenuItem("Central Receiver Conversion Efficiency...");
miConversionEfficiency.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Mirror)) {
return;
}
final Mirror m = (Mirror) selectedPart;
final Foundation receiver = m.getReceiver();
if (receiver == null) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "This heliostat does not link to a receiver.", "No Receiver", JOptionPane.ERROR_MESSAGE);
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final String title = "<html>Light-electricity conversion efficiency (%) of " + partInfo + "'s central receiver</html>";
final String footnote = "<html><hr><font size=2><hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(receiver.getSolarReceiverEfficiency() * 100));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Receiver Conversion Efficiency");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (val < 5 || val > 50) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Light-electricity conversion efficiency must be between 5% and 50%.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
final boolean changed = Math.abs(val * 0.01 - receiver.getSolarReceiverEfficiency()) > 0.000001;
if (changed) {
final ChangeSolarReceiverEfficiencyCommand c = new ChangeSolarReceiverEfficiencyCommand(receiver);
receiver.setSolarReceiverEfficiency(val * 0.01);
SceneManager.getInstance().getUndoManager().addEdit(c);
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
popupMenuForHeliostat.addSeparator();
popupMenuForHeliostat.add(miSetHeliostat);
popupMenuForHeliostat.add(miZenith);
popupMenuForHeliostat.add(miAzimuth);
popupMenuForHeliostat.add(miSize);
popupMenuForHeliostat.add(miBaseHeight);
popupMenuForHeliostat.addSeparator();
popupMenuForHeliostat.add(miReflectance);
popupMenuForHeliostat.add(miApertureRatio);
popupMenuForHeliostat.add(miConversionEfficiency);
popupMenuForHeliostat.addSeparator();
popupMenuForHeliostat.add(cbmiDisableEditPoint);
popupMenuForHeliostat.add(cbmiDrawSunBeam);
popupMenuForHeliostat.add(labelMenu);
popupMenuForHeliostat.add(textureMenu);
popupMenuForHeliostat.addSeparator();
JMenuItem mi = new JMenuItem("Daily Yield Analysis...");
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (EnergyPanel.getInstance().adjustCellSize()) {
return;
}
if (SceneManager.getInstance().getSelectedPart() instanceof Mirror) {
new HeliostatDailyAnalysis().show();
}
}
});
popupMenuForHeliostat.add(mi);
mi = new JMenuItem("Annual Yield Analysis...");
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (EnergyPanel.getInstance().adjustCellSize()) {
return;
}
if (SceneManager.getInstance().getSelectedPart() instanceof Mirror) {
new HeliostatAnnualAnalysis().show();
}
}
});
popupMenuForHeliostat.add(mi);
}
return popupMenuForHeliostat;
}
use of org.concord.energy3d.model.Mirror in project energy3d by concord-consortium.
the class MainPanel method getRotateButton.
public JButton getRotateButton() {
if (rotateButton == null) {
rotateButton = new JButton();
if (Config.isMac()) {
// for some reason, the newer version of Mac draws border for JButton (but not JToggleButton)
rotateButton.setBorderPainted(false);
}
rotateButton.addMouseListener(refreshUponMouseExit);
rotateButton.setIcon(new ImageIcon(getClass().getResource("icons/rotate_cw.png")));
rotateButton.setToolTipText("<html>Rotate in the clockwise direction (change azimuth).<br>Hold down the Ctrl key and press this button for counter-clockwise rotation.<br>Hold down the Shift key while pressing this button to rotate more slowly.<br>If a component is selected, rotate around its center. Otherwise rotate everything around the origin.</html>");
rotateButton.setFocusable(false);
addMouseOverEffect(rotateButton);
rotateButton.addMouseListener(new MouseAdapter() {
private volatile boolean mousePressed = false;
@Override
public void mousePressed(final MouseEvent e) {
energyButton.setSelected(false);
mousePressed = true;
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart == null || selectedPart instanceof Tree || selectedPart instanceof Human) {
int count = 0;
HousePart hp = null;
for (final HousePart x : Scene.getInstance().getParts()) {
if (x instanceof Foundation) {
count++;
hp = x;
}
}
if (count == 1) {
// if there is only one building, automatically select it to ensure that we always rotate around its center
SceneManager.getInstance().setSelectedPart(hp);
SceneManager.getInstance().refresh();
EnergyPanel.getInstance().updateProperties();
}
}
new Thread("Energy3D Continuous Rotation") {
private int count;
private ChangeAzimuthCommand c;
@Override
public void run() {
final HousePart part = SceneManager.getInstance().getSelectedPart();
if (part != null) {
c = new ChangeAzimuthCommand(part);
}
while (mousePressed) {
SceneManager.getTaskManager().update(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (part == null) {
SceneManager.getInstance().rotateAllFoundations(rotationAngle);
} else {
if (part instanceof Foundation) {
SceneManager.getInstance().rotateFoundation(rotationAngle, true);
} else if (part instanceof SolarPanel) {
final SolarPanel solarPanel = (SolarPanel) part;
solarPanel.setRelativeAzimuth(solarPanel.getRelativeAzimuth() + Math.toDegrees(rotationAngle));
solarPanel.draw();
} else if (part instanceof Rack) {
final Rack rack = (Rack) part;
rack.setRelativeAzimuth(rack.getRelativeAzimuth() + Math.toDegrees(rotationAngle));
rack.draw();
} else if (part instanceof Mirror) {
final Mirror mirror = (Mirror) part;
mirror.setRelativeAzimuth(mirror.getRelativeAzimuth() + Math.toDegrees(rotationAngle));
mirror.draw();
}
}
count++;
Scene.getInstance().setEdited(true);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
EnergyPanel.getInstance().updateProperties();
}
});
return null;
}
});
final int partCount = Scene.getInstance().getParts().size();
try {
// give it enough time for the above call to complete (the more parts it has, the more time it needs)
Thread.sleep(200 + partCount * 5);
} catch (final InterruptedException e) {
}
}
// undo only after the thread ends
if (part == null) {
SceneManager.getInstance().getUndoManager().addEdit(new RotateBuildingCommand(null, rotationAngle * count));
} else {
if (part instanceof Foundation) {
SceneManager.getInstance().getUndoManager().addEdit(new RotateBuildingCommand((Foundation) part, rotationAngle * count));
} else if (part instanceof SolarPanel || part instanceof Rack || part instanceof Mirror) {
if (c != null) {
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
}
}.start();
}
@Override
public void mouseReleased(final MouseEvent e) {
mousePressed = false;
}
});
}
return rotateButton;
}
use of org.concord.energy3d.model.Mirror in project energy3d by concord-consortium.
the class CspProjectInfoPanel method update.
void update(final Foundation foundation) {
final List<ParabolicTrough> troughs = foundation.getParabolicTroughs();
if (!troughs.isEmpty()) {
countBar.setValue(troughs.size());
int totalModules = 0;
for (final ParabolicTrough t : troughs) {
totalModules += t.getNumberOfModules();
}
moduleCountBar.setValue(totalModules);
countPanel.setBorder(EnergyPanel.createTitledBorder("Number of parabolic troughs", true));
double cost = 0;
double reflectingArea = 0;
double troughArea = 0;
final CspCustomPrice price = Scene.getInstance().getCspCustomPrice();
for (final ParabolicTrough t : troughs) {
troughArea = t.getTroughLength() * t.getApertureWidth();
cost += price.getParabolicTroughUnitPrice() * troughArea;
reflectingArea += troughArea;
}
cost += foundation.getArea() * price.getLandUnitPrice() * price.getLifespan();
costBar.setValue(Math.round(cost));
final CspDesignSpecs specs = Scene.getInstance().getCspDesignSpecs();
String t = "Total cost over " + price.getLifespan() + " years";
if (specs.isBudgetEnabled()) {
t += " (" + "<$" + specs.getMaximumBudget() + ")";
}
costPanel.setBorder(EnergyPanel.createTitledBorder(t, true));
packingDensityBar.setValue((float) (reflectingArea / foundation.getArea()));
} else {
final List<ParabolicDish> dishes = foundation.getParabolicDishes();
if (!dishes.isEmpty()) {
countBar.setValue(dishes.size());
moduleCountBar.setValue(dishes.size());
countPanel.setBorder(EnergyPanel.createTitledBorder("Number of parabolic dishes", true));
double cost = 0;
double reflectingArea = 0;
double rimArea = 0;
final CspCustomPrice price = Scene.getInstance().getCspCustomPrice();
for (final ParabolicDish d : dishes) {
rimArea = d.getRimRadius() * d.getRimRadius() * Math.PI;
cost += price.getHeliostatUnitPrice() * rimArea;
reflectingArea += rimArea;
}
cost += foundation.getArea() * price.getLandUnitPrice() * price.getLifespan();
costBar.setValue(Math.round(cost));
final CspDesignSpecs specs = Scene.getInstance().getCspDesignSpecs();
String t = "Total cost over " + price.getLifespan() + " years";
if (specs.isBudgetEnabled()) {
t += " (" + "<$" + specs.getMaximumBudget() + ")";
}
costPanel.setBorder(EnergyPanel.createTitledBorder(t, true));
packingDensityBar.setValue((float) (reflectingArea / foundation.getArea()));
} else {
final List<FresnelReflector> fresnels = foundation.getFresnelReflectors();
if (fresnels.isEmpty()) {
final List<Mirror> mirrors = foundation.getHeliostats();
countBar.setValue(mirrors.size());
moduleCountBar.setValue(mirrors.size());
countPanel.setBorder(EnergyPanel.createTitledBorder("Number of heliostats", true));
double cost = 0;
double reflectingArea = 0;
double mirrorArea = 0;
final CspCustomPrice price = Scene.getInstance().getCspCustomPrice();
final ArrayList<Foundation> towers = new ArrayList<Foundation>();
for (final Mirror m : mirrors) {
mirrorArea = m.getMirrorWidth() * m.getMirrorHeight();
cost += price.getHeliostatUnitPrice() * mirrorArea;
reflectingArea += mirrorArea;
if (m.getReceiver() != null) {
if (!towers.contains(m.getReceiver())) {
towers.add(m.getReceiver());
}
}
}
if (!mirrors.isEmpty()) {
cost += foundation.getArea() * price.getLandUnitPrice() * price.getLifespan();
if (!towers.isEmpty()) {
for (final Foundation tower : towers) {
cost += price.getTowerUnitPrice() * tower.getSolarReceiverHeight(0) * Scene.getInstance().getAnnotationScale();
}
}
} else {
if (foundation.hasSolarReceiver()) {
cost += price.getTowerUnitPrice() * foundation.getSolarReceiverHeight(0) * Scene.getInstance().getAnnotationScale();
}
}
costBar.setValue(Math.round(cost));
final CspDesignSpecs specs = Scene.getInstance().getCspDesignSpecs();
String t = "Total cost over " + price.getLifespan() + " years";
if (specs.isBudgetEnabled()) {
t += " (" + "<$" + specs.getMaximumBudget() + ")";
}
costPanel.setBorder(EnergyPanel.createTitledBorder(t, true));
packingDensityBar.setValue((float) (reflectingArea / foundation.getArea()));
} else {
countBar.setValue(fresnels.size());
int totalModules = 0;
for (final FresnelReflector r : fresnels) {
totalModules += r.getNumberOfModules();
}
moduleCountBar.setValue(totalModules);
countPanel.setBorder(EnergyPanel.createTitledBorder("Number of Fresnel reflectors", true));
double cost = 0;
double reflectingArea = 0;
double unitArea = 0;
final CspCustomPrice price = Scene.getInstance().getCspCustomPrice();
for (final FresnelReflector r : fresnels) {
unitArea = r.getLength() * r.getModuleWidth();
cost += price.getFresnelReflectorUnitPrice() * unitArea;
reflectingArea += unitArea;
}
cost += foundation.getArea() * price.getLandUnitPrice() * price.getLifespan();
costBar.setValue(Math.round(cost));
final CspDesignSpecs specs = Scene.getInstance().getCspDesignSpecs();
String t = "Total cost over " + price.getLifespan() + " years";
if (specs.isBudgetEnabled()) {
t += " (" + "<$" + specs.getMaximumBudget() + ")";
}
costPanel.setBorder(EnergyPanel.createTitledBorder(t, true));
packingDensityBar.setValue((float) (reflectingArea / foundation.getArea()));
}
}
}
}
use of org.concord.energy3d.model.Mirror in project energy3d by concord-consortium.
the class EnergyPanel method updateProperties.
// As this method may be called from a non-Event-Queue thread, updating GUI must be done through invokeLater.
public void updateProperties() {
// update part properties
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
final boolean energyViewShown = MainPanel.getInstance().getEnergyButton().isSelected();
final double meterToFoot;
final String lengthUnit;
switch(Scene.getInstance().getUnit()) {
case USCustomaryUnits:
meterToFoot = 3.28084;
lengthUnit = "ft";
break;
default:
meterToFoot = 1;
lengthUnit = "m";
}
final double scale = Scene.getInstance().getAnnotationScale() * meterToFoot;
final TitledBorder partPanelBorder = (TitledBorder) partPanel.getBorder();
if (selectedPart != null) {
final ReadOnlyVector3 v = selectedPart.getAbsPoint(0);
if (selectedPart instanceof Tree) {
final Tree tree = (Tree) selectedPart;
if (tree.isDrawable()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Tree (" + tree.getId() + "): " + tree.getTreeName());
partProperty1Label.setText(" Spread & Height:");
partProperty2Label.setText(" Type:");
partProperty3Label.setText(" Position:");
final double l = v.length();
double a = 90 + Math.toDegrees(Math.asin(-v.getY() / l));
if (v.getX() < 0) {
a = 360 - a;
}
if (Util.isZero(a - 360)) {
a = 0;
}
partProperty1TextField.setText(ONE_DECIMAL.format(tree.getWidth() * scale) + lengthUnit + ", " + ONE_DECIMAL.format(tree.getHeight() * scale) + lengthUnit);
partProperty2TextField.setText(tree.getTreeName() + " (" + (tree.getTreeType() == Tree.PINE ? "Evergreen" : "Deciduous") + ")");
partProperty3TextField.setText("(" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ")" + lengthUnit + " or (" + ONE_DECIMAL.format(l * scale) + lengthUnit + ", " + ONE_DECIMAL.format(a) + "\u00B0)");
partProperty1TextField.putClientProperty("tooltip", "The spread and height of the tree");
partProperty2TextField.putClientProperty("tooltip", "The type of the tree");
partProperty3TextField.putClientProperty("tooltip", "The (x, y) or polar coordinates on the land");
}
});
}
} else if (selectedPart instanceof Human) {
final Human human = (Human) selectedPart;
if (human.isDrawable()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Human (" + human.getId() + "): " + human.getHumanName());
partProperty1Label.setText(" X:");
partProperty2Label.setText(" Y:");
partProperty3Label.setText(" Z:");
partProperty1TextField.setText(ONE_DECIMAL.format(v.getX() * scale) + lengthUnit);
partProperty2TextField.setText(ONE_DECIMAL.format(v.getY() * scale) + lengthUnit);
partProperty3TextField.setText(ONE_DECIMAL.format(v.getZ() * scale) + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "X coordinate");
partProperty2TextField.putClientProperty("tooltip", "Y coordinate");
partProperty3TextField.putClientProperty("tooltip", "Z coordinate");
}
});
}
} else if (selectedPart instanceof SolarPanel) {
final SolarPanel sp = (SolarPanel) selectedPart;
if (sp.isDrawable()) {
final Foundation f = sp.getTopContainer();
if (f != null) {
double a = sp.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
final boolean flat = (sp.getContainer() instanceof Roof && Util.isZero(sp.getContainer().getHeight())) || (sp.getContainer() instanceof Foundation);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
String title = "Solar Panel (" + sp.getId() + "), " + (sp.getModelName() == null ? "" : "Model: " + sp.getModelName());
final String trackerName = sp.getTrackerName();
if (trackerName != null) {
title += ", Tracker: " + trackerName;
}
partPanelBorder.setTitle(title);
partProperty1Label.setText(" Size & Position:");
partProperty1TextField.setText(TWO_DECIMALS.format(sp.getPanelWidth() * meterToFoot) + "\u00d7" + TWO_DECIMALS.format(sp.getPanelHeight() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The length, width, and center coordinates of the solar panel");
partProperty2Label.setText(" Angles:");
partProperty2TextField.setText(flat ? "tilt: " + ONE_DECIMAL.format(Util.isZero(sp.getTiltAngle()) ? Math.toDegrees(Math.asin(sp.getNormal().getY())) : sp.getTiltAngle()) + "\u00B0, azimuth: " + ONE_DECIMAL.format(az) + "\u00B0" : " --- ");
partProperty2TextField.putClientProperty("tooltip", "The angles of the solar panel");
final String eff = ONE_DECIMAL.format(sp.getCellEfficiency() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Efficiency & Yield:");
partProperty3TextField.setText(eff + ", " + TWO_DECIMALS.format(sp.getSolarPotentialToday()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The solar cell efficiency and daily yield of the solar panel");
} else {
partProperty3Label.setText(" Efficiency:");
partProperty3TextField.setText(eff);
partProperty3TextField.putClientProperty("tooltip", "The solar cell efficiency of the solar panel");
}
}
});
}
}
} else if (selectedPart instanceof Rack) {
final Rack rack = (Rack) selectedPart;
if (rack.isDrawable()) {
final Foundation f = rack.getTopContainer();
if (f != null) {
double a = rack.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
final int n = rack.isMonolithic() ? rack.getNumberOfSolarPanels() : rack.getChildren().size();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
String title = "Rack (" + rack.getId() + ")";
final SolarPanel s = rack.getSolarPanel();
if (s.getModelName() != null) {
title += ", Model: " + s.getModelName();
}
final String trackerName = rack.getTrackerName();
if (trackerName != null) {
title += ", Tracker: " + trackerName;
}
partPanelBorder.setTitle(title);
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(rack.getRackWidth() * meterToFoot) + "\u00d7" + TWO_DECIMALS.format(rack.getRackHeight() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The length, width, and center coordinates of the rack");
partProperty2Label.setText(" Angles:");
partProperty2TextField.setText("tilt: " + ONE_DECIMAL.format(Util.isZero(rack.getTiltAngle()) ? Math.toDegrees(Math.asin(rack.getNormal().getY())) : rack.getTiltAngle()) + "\u00B0, azimuth: " + ONE_DECIMAL.format(az) + "\u00B0");
partProperty2TextField.putClientProperty("tooltip", "The angles of the rack");
partProperty3Label.setText(" Solar Panels:");
final SolarPanel sp = rack.getSolarPanel();
final String eff = ONE_DECIMAL.format(sp.getCellEfficiency() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Efficiency & Yield:");
partProperty3TextField.setText(eff + ", " + TWO_DECIMALS.format(rack.getSolarPotentialToday()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The solar cell efficiency and daily yield of the solar panel array on the rack");
} else {
if (rack.isMonolithic()) {
final int[] rnc = rack.getSolarPanelRowAndColumnNumbers();
partProperty3TextField.setText("" + n + " (" + rnc[0] + "\u00D7" + rnc[1] + "), " + s.getPanelWidth() + "\u00D7" + s.getPanelHeight() + lengthUnit + ", " + eff);
} else {
partProperty3TextField.setText("" + n);
}
partProperty3TextField.putClientProperty("tooltip", "Number and type of solar panels on this rack");
}
}
});
}
}
} else if (selectedPart instanceof Mirror) {
final Mirror m = (Mirror) selectedPart;
if (m.isDrawable()) {
final Foundation f = m.getTopContainer();
if (f != null) {
double a = m.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
final boolean flat = m.getContainer() instanceof Foundation;
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Heliostat (" + m.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(m.getMirrorWidth() * meterToFoot) + "\u00d7" + TWO_DECIMALS.format(m.getMirrorHeight() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The length, width, and center coordinates of the heliostat");
partProperty2Label.setText(" Angles:");
partProperty2TextField.setText(flat ? "tilt: " + ONE_DECIMAL.format(m.getTiltAngle()) + "\u00B0, azimuth: " + ONE_DECIMAL.format(az) + "\u00B0" : " --- ");
partProperty2TextField.putClientProperty("tooltip", "The angles of the heliostat");
final Foundation receiver = m.getReceiver();
final String s = "R=" + ONE_DECIMAL.format(m.getReflectance() * 100) + "%" + (receiver == null ? "" : ", \u03B7=" + ONE_DECIMAL.format(receiver.getSolarReceiverEfficiency() * 100) + "%");
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(s + ", " + ONE_DECIMAL.format(m.getSolarPotentialToday() * m.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The physical properties and electric yield of this heliostat");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(s);
partProperty3TextField.putClientProperty("tooltip", "The physical properties of this heliostat");
}
}
});
}
}
} else if (selectedPart instanceof ParabolicTrough) {
final ParabolicTrough t = (ParabolicTrough) selectedPart;
if (t.isDrawable()) {
final Foundation f = t.getTopContainer();
if (f != null) {
double a = t.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
// http://www.powerfromthesun.net/Book/chapter08/chapter08.html
final double focalLength = t.getSemilatusRectum() * 0.5;
final double d = t.getApertureWidth();
final double h = d * d / (16 * focalLength);
final double rimAngle = Math.toDegrees(Math.atan(1.0 / (d / (8 * h) - (2 * h) / d)));
final double b = 4 * h / d;
final double c = Math.sqrt(b * b + 1);
final double s = 0.5 * d * c + 2 * focalLength * Math.log(b + c);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Parabolic Trough (" + t.getId() + ")");
partProperty1Label.setText(" Length & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(t.getTroughLength() * meterToFoot) + lengthUnit + ", module:" + TWO_DECIMALS.format(t.getModuleLength() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit + ", azimuth:" + ONE_DECIMAL.format(az) + "\u00B0");
partProperty1TextField.putClientProperty("tooltip", "Assembly length, module length, center coordinates, and azimith of the parabolic trough");
partProperty2Label.setText(" Parabola Shape:");
partProperty2TextField.setText("f=" + ONE_DECIMAL.format(focalLength * meterToFoot) + lengthUnit + ", d=" + ONE_DECIMAL.format(t.getApertureWidth() * meterToFoot) + lengthUnit + ", h=" + ONE_DECIMAL.format(h * meterToFoot) + lengthUnit + ", \u03C6=" + ONE_DECIMAL.format(rimAngle >= 0 ? rimAngle : 180 + rimAngle) + "\u00B0");
partProperty2TextField.putClientProperty("tooltip", "Parameters of the parabolic shape");
final String str = "R=" + ONE_DECIMAL.format(t.getReflectance() * 100) + "%, s=" + ONE_DECIMAL.format(s * t.getTroughLength() * meterToFoot * meterToFoot) + lengthUnit + "\u00B2, a=" + ONE_DECIMAL.format(d * t.getTroughLength() * meterToFoot * meterToFoot) + lengthUnit + "\u00B2, \u03B1=" + ONE_DECIMAL.format(t.getAbsorptance() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(str + ", " + ONE_DECIMAL.format(t.getSolarPotentialToday() * t.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The properties and yield of this parabolic trough");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(str);
partProperty3TextField.putClientProperty("tooltip", "The properties of this parabolic trough");
}
}
});
}
}
} else if (selectedPart instanceof ParabolicDish) {
final ParabolicDish d = (ParabolicDish) selectedPart;
if (d.isDrawable()) {
final Foundation f = d.getTopContainer();
if (f != null) {
double a = d.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double focalLength = d.getFocalLength();
final double rimRadius = d.getRimRadius();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Parabolic Dish (" + d.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText("Rim radius=" + TWO_DECIMALS.format(rimRadius * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "Rim radius and center coordinates of the parabolic dish");
partProperty2Label.setText(" Parabola Shape:");
partProperty2TextField.setText("Focal length=" + ONE_DECIMAL.format(focalLength * meterToFoot) + lengthUnit);
partProperty2TextField.putClientProperty("tooltip", "Parameters of the parabolic shape");
final String str = "R=" + ONE_DECIMAL.format(d.getReflectance() * 100) + "%, \u03B1=" + ONE_DECIMAL.format(d.getAbsorptance() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(str + ", " + ONE_DECIMAL.format(d.getSolarPotentialToday() * d.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The properties and yield of this parabolic dish");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(str);
partProperty3TextField.putClientProperty("tooltip", "The properties of this parabolic dish");
}
}
});
}
}
} else if (selectedPart instanceof FresnelReflector) {
final FresnelReflector r = (FresnelReflector) selectedPart;
if (r.isDrawable()) {
final Foundation f = r.getTopContainer();
if (f != null) {
double a = r.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Fresnel Reflector (" + r.getId() + ")");
partProperty1Label.setText(" Center & Azimuth:");
partProperty1TextField.setText("(" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit + ", azimuth:" + ONE_DECIMAL.format(az) + "\u00B0");
partProperty1TextField.putClientProperty("tooltip", "Center coordinates and azimuth of the Fresnel reflector");
partProperty2Label.setText(" Length & Width:");
partProperty2TextField.setText(TWO_DECIMALS.format(r.getLength() * meterToFoot) + lengthUnit + ", module:" + TWO_DECIMALS.format(r.getModuleLength() * meterToFoot) + lengthUnit + ", " + ONE_DECIMAL.format(r.getModuleWidth() * meterToFoot) + lengthUnit);
partProperty2TextField.putClientProperty("tooltip", "Assembly length, module length, and width of the Fresnel reflector");
final Foundation receiver = r.getReceiver();
final String str = "R=" + ONE_DECIMAL.format(r.getReflectance() * 100) + "%, a=" + ONE_DECIMAL.format(r.getModuleWidth() * r.getLength() * meterToFoot * meterToFoot) + lengthUnit + "\u00B2" + (receiver == null ? "" : ", \u03B7=" + ONE_DECIMAL.format(receiver.getSolarReceiverEfficiency() * 100) + "%");
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(str + ", " + ONE_DECIMAL.format(r.getSolarPotentialToday() * r.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The properties and yield of this Fresnel reflector");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(str);
partProperty3TextField.putClientProperty("tooltip", "The properties of this Fresnel reflector");
}
}
});
}
}
} else if (selectedPart instanceof Sensor) {
final Sensor sensor = (Sensor) selectedPart;
if (sensor.isDrawable()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Sensor (" + sensor.getId() + ")");
partProperty1Label.setText(" Position:");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Light:");
partProperty1TextField.setText("(" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty2TextField.setText(TWO_DECIMALS.format(-sensor.getTotalHeatLoss() / sensor.getArea()) + " kWh/day/m\u00B2");
partProperty3TextField.setText(TWO_DECIMALS.format(sensor.getSolarPotentialToday() / sensor.getArea()) + " kWh/day/m\u00B2");
partProperty1TextField.putClientProperty("tooltip", "The (x, y, z) coordinates of the sensor");
partProperty2TextField.putClientProperty("tooltip", "The heat flux measured by the sensor");
partProperty3TextField.putClientProperty("tooltip", "The light intensity measured by the sensor");
}
});
}
} else if (selectedPart instanceof Foundation) {
final Foundation foundation = (Foundation) selectedPart;
if (foundation.isDrawable()) {
final Vector3 v1 = foundation.getAbsPoint(1);
final Vector3 v2 = foundation.getAbsPoint(2);
final Vector3 v3 = foundation.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double lx = v.distance(v2);
final double ly = v.distance(v1);
final double lz = foundation.getHeight();
final double az = foundation.getAzimuth();
final String landArea;
final FoundationPolygon polygon = foundation.getPolygon();
if (polygon != null && polygon.isVisible()) {
landArea = " (inset:" + ONE_DECIMAL.format(polygon.getArea()) + ")";
} else {
landArea = "";
}
final Mesh selectedMesh;
final Node selectedNode;
final OrientedBoundingBox nodeBox, meshBox;
final List<Node> nodes = foundation.getImportedNodes();
if (nodes != null) {
selectedMesh = foundation.getSelectedMesh();
if (selectedMesh != null) {
selectedNode = selectedMesh.getParent();
nodeBox = Util.getOrientedBoundingBox(selectedNode);
meshBox = Util.getOrientedBoundingBox(selectedMesh);
} else {
selectedNode = null;
nodeBox = null;
meshBox = null;
}
} else {
selectedMesh = null;
selectedNode = null;
nodeBox = null;
meshBox = null;
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (selectedNode != null) {
final double xNodeBox = 2 * nodeBox.getExtent().getX() * scale;
final double yNodeBox = 2 * nodeBox.getExtent().getY() * scale;
final double zNodeBox = 2 * nodeBox.getExtent().getZ() * scale;
final double xMeshBox = 2 * meshBox.getExtent().getX() * scale;
final double yMeshBox = 2 * meshBox.getExtent().getY() * scale;
final double zMeshBox = 2 * meshBox.getExtent().getZ() * scale;
final ReadOnlyVector3 meshBoxCenter = meshBox.getCenter();
final NodeState ns = foundation.getNodeState(selectedNode);
final Vector3 position = ns.getRelativePosition().add(foundation.getAbsCenter(), null);
Vector3 meshNormal = null;
int meshIndex = -1;
if (selectedMesh.getUserData() instanceof UserData) {
final UserData ud = (UserData) selectedMesh.getUserData();
meshIndex = ud.getMeshIndex();
meshNormal = (Vector3) ud.getNormal();
if (!Util.isZero(az)) {
selectedNode.getRotation().applyPost(meshNormal, meshNormal);
}
}
// System.out.println(">>>" + Util.computeFirstNormal(selectedMesh) + ", " + Util.getFirstNormalFromBuffer(selectedMesh));
final String meshBoxString = TWO_DECIMALS.format(xMeshBox) + "\u00d7" + (TWO_DECIMALS.format(yMeshBox)) + "\u00d7" + (TWO_DECIMALS.format(zMeshBox)) + lengthUnit;
final String meshCenterString = "(" + ONE_DECIMAL.format(meshBoxCenter.getX() * scale) + ", " + ONE_DECIMAL.format(meshBoxCenter.getY() * scale) + ", " + ONE_DECIMAL.format(meshBoxCenter.getZ() * scale) + ")" + lengthUnit;
final String meshNormalString = meshNormal != null ? "(" + TWO_DECIMALS.format(meshNormal.getX()) + ", " + TWO_DECIMALS.format(meshNormal.getY()) + ", " + TWO_DECIMALS.format(meshNormal.getZ()) + ")" : "";
partPanelBorder.setTitle("Node #" + foundation.getImportedNodes().indexOf(selectedNode) + " (" + Util.getFileName(ns.getSourceURL().getPath()).replace("%20", " ") + "), Mesh #" + meshIndex + ", Base #" + foundation.getId());
partProperty1Label.setText(" Node:");
partProperty2Label.setText(" Mesh:");
partProperty1TextField.setText(TWO_DECIMALS.format(xNodeBox) + "\u00d7" + (TWO_DECIMALS.format(yNodeBox)) + "\u00d7" + (TWO_DECIMALS.format(zNodeBox)) + lengthUnit + ", (" + TWO_DECIMALS.format(position.getX() * scale) + ", " + TWO_DECIMALS.format(position.getY() * scale) + ")" + lengthUnit);
partProperty2TextField.setText(meshBoxString + ", " + meshCenterString);
partProperty1TextField.putClientProperty("tooltip", "Dimension and location of the bounding box of the selected node<br>File:" + ns.getSourceURL().getFile());
partProperty2TextField.putClientProperty("tooltip", "Dimension and location of the bounding box of the selected mesh");
if (energyViewShown) {
double dailyMeshSolarPotential = 0;
final double[] meshSolarPotential = SolarRadiation.getInstance().getSolarPotential(selectedMesh);
for (final double x : meshSolarPotential) {
dailyMeshSolarPotential += x;
}
partProperty3Label.setText(" Solar:");
partProperty3TextField.setText("\u2191" + meshNormalString + ", " + TWO_DECIMALS.format(dailyMeshSolarPotential) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "Normal vector and solar potential of the selected mesh");
} else {
partProperty3Label.setText(" Normal:");
partProperty3TextField.setText("\u2191" + meshNormalString + ", " + selectedMesh.getMeshData().getVertexCount() + " vertices");
partProperty3TextField.putClientProperty("tooltip", "Normal vector and vertex count of the selected mesh");
}
} else {
partPanelBorder.setTitle("Foundation (" + foundation.getId() + ")");
partProperty1Label.setText(" Size:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx * scale) + "\u00d7" + (TWO_DECIMALS.format(ly * scale)) + "\u00d7" + (TWO_DECIMALS.format(lz * scale)) + lengthUnit + ", Area\u2248" + ONE_DECIMAL.format(lx * ly * scale * scale) + landArea + lengthUnit + "\u00B2");
partProperty1TextField.putClientProperty("tooltip", "The length and width of the foundation");
partProperty2Label.setText(" Position:");
partProperty2TextField.setText("(" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ")" + lengthUnit);
partProperty2TextField.putClientProperty("tooltip", "The (x, y) coordinate of the center of the foundation");
partProperty3Label.setText(" Azimuth:");
partProperty3TextField.setText(TWO_DECIMALS.format(az) + "\u00B0");
partProperty3TextField.putClientProperty("tooltip", "The azimuth of the reference edge");
}
}
});
}
} else if (selectedPart instanceof Roof) {
final Roof roof = (Roof) selectedPart;
if (roof.isDrawable()) {
final double area = roof.getArea();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Roof (" + roof.getId() + ")");
partProperty1Label.setText(" Area & Rise:");
partProperty1TextField.setText("Area = " + TWO_DECIMALS.format(area) + lengthUnit + "\u00B2, Rise = " + TWO_DECIMALS.format(roof.getHeight() * scale) + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The total area and the rise of the roof<br>(The rise is the highest point of the roof to the top of the walls.)");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String rval = ONE_DECIMAL.format(Util.toUsRValue(roof.getUValue()));
final boolean isBuildingProject = Scene.getInstance().getProjectType() == Foundation.TYPE_BUILDING;
final float absorptance = 1 - roof.getAlbedo();
if (energyViewShown) {
partProperty2TextField.setText("R-value = " + rval + ", Gain = " + TWO_DECIMALS.format(-roof.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The R-value and daily thermal gain of the roof");
if (isBuildingProject) {
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance) + ", Absorption = " + TWO_DECIMALS.format(roof.getSolarPotentialToday() * absorptance) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The absorptance and daily solar heat gain of the roof surface");
} else {
partProperty3TextField.setText("Radiation energy = " + TWO_DECIMALS.format(roof.getSolarPotentialToday()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The solar radiation energy onto this roof surface");
}
} else {
partProperty2TextField.setText("R-value = " + rval + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The R-value of the roof");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance));
partProperty3TextField.putClientProperty("tooltip", "The absorptance of the roof surface");
}
}
});
}
} else if (selectedPart instanceof Window) {
final Window window = (Window) selectedPart;
if (window.isDrawable()) {
final double lx = window.getWindowWidth();
final double ly = window.getWindowHeight();
final Vector3 v1 = window.getAbsPoint(1);
final Vector3 v2 = window.getAbsPoint(2);
final Vector3 v3 = window.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double cz = 0.25 * (v.getZ() + v1.getZ() + v2.getZ() + v3.getZ());
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Window (" + window.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx) + "\u00d7" + (TWO_DECIMALS.format(ly)) + lengthUnit + " \u2248 " + TWO_DECIMALS.format(lx * ly) + lengthUnit + "\u00B2, (" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ", " + TWO_DECIMALS.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The width, height, and center of the window");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String shgc = TWO_DECIMALS.format(window.getSolarHeatGainCoefficient());
if (energyViewShown) {
partProperty2TextField.setText("U-Value = " + TWO_DECIMALS.format(Util.toUsUValue(window.getUValue())) + ", Gain = " + TWO_DECIMALS.format(-window.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The U-value and daily thermal gain of the window");
partProperty3TextField.setText("SHGC = " + shgc + ", Gain = " + TWO_DECIMALS.format(window.getSolarPotentialToday() * window.getSolarHeatGainCoefficient()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The SHGC value and daily solar gain of the window");
} else {
partProperty2TextField.setText("U-Value = " + TWO_DECIMALS.format(Util.toUsUValue(window.getUValue())) + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The U-value of the window");
partProperty3TextField.setText("SHGC = " + shgc);
partProperty3TextField.putClientProperty("tooltip", "The solar heat gain coefficient (SHGC) of the window");
}
}
});
}
} else if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
if (wall.isDrawable()) {
final Vector3 v1 = wall.getAbsPoint(1);
final Vector3 v2 = wall.getAbsPoint(2);
final Vector3 v3 = wall.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double cz = 0.25 * (v.getZ() + v1.getZ() + v2.getZ() + v3.getZ());
final double lx = v.distance(v2);
final double ly = v.distance(v1);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Wall (" + wall.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx * scale) + "\u00d7" + (TWO_DECIMALS.format(ly * scale)) + lengthUnit + " \u2248 " + TWO_DECIMALS.format(lx * ly * scale * scale) + lengthUnit + " \u00B2, " + "(" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ", " + TWO_DECIMALS.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The width, height, and center of the wall");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String rval = ONE_DECIMAL.format(Util.toUsRValue(wall.getUValue()));
final float absorptance = 1 - wall.getAlbedo();
if (energyViewShown) {
partProperty2TextField.setText("R-Value = " + rval + ", Gain = " + TWO_DECIMALS.format(-wall.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The R-value and daily thermal gain of the wall");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance) + ", Absorption = " + TWO_DECIMALS.format(wall.getSolarPotentialToday() * absorptance) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The absorptance and daily solar heat gain of the wall surface");
} else {
partProperty2TextField.setText("R-Value = " + rval + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The R-value of the wall");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance));
partProperty3TextField.putClientProperty("tooltip", "The absorptance of the wall surface");
}
}
});
}
} else if (selectedPart instanceof Door) {
final Door door = (Door) selectedPart;
if (door.isDrawable()) {
final Vector3 v1 = door.getAbsPoint(1);
final Vector3 v2 = door.getAbsPoint(2);
final Vector3 v3 = door.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double cz = 0.25 * (v.getZ() + v1.getZ() + v2.getZ() + v3.getZ());
final double lx = v.distance(v2);
final double ly = v.distance(v1);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Door (" + door.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx * scale) + "\u00d7" + (TWO_DECIMALS.format(ly * scale)) + lengthUnit + " \u2248 " + TWO_DECIMALS.format(lx * ly * scale * scale) + lengthUnit + "\u00B2, (" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ", " + TWO_DECIMALS.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The width, height, and center of the door");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String uval = TWO_DECIMALS.format(Util.toUsUValue(door.getUValue()));
final float absorptance = 1 - door.getAlbedo();
if (energyViewShown) {
partProperty2TextField.setText("U-Value = " + uval + ", Gain = " + TWO_DECIMALS.format(-door.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The R-value and daily thermal gain of the door");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance) + ", Absorption = " + TWO_DECIMALS.format(door.getSolarPotentialToday() * absorptance) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The absorptance and daily solar heat gain of the door surface");
} else {
partProperty2TextField.setText("U-Value = " + uval + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The U-value of the door");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance));
partProperty3TextField.putClientProperty("tooltip", "The absorptance of the door surface");
}
}
});
}
} else if (selectedPart instanceof Floor) {
final Floor floor = (Floor) selectedPart;
if (floor.isDrawable()) {
final double cx, cy;
final double cz = v.getZ();
if (floor.getPoints().size() > 1) {
final Vector3 v1 = floor.getAbsPoint(1);
final Vector3 v2 = floor.getAbsPoint(2);
final Vector3 v3 = floor.getAbsPoint(3);
cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
} else {
cx = v.getX();
cy = v.getY();
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Floor (" + floor.getId() + ")");
partProperty1Label.setText(" Area & Center");
partProperty1TextField.setText(ONE_DECIMAL.format(floor.getArea()) + lengthUnit + "\u00B2, (" + ONE_DECIMAL.format(cx * scale) + ", " + ONE_DECIMAL.format(cy * scale) + ", " + ONE_DECIMAL.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The area and center of the floor");
partProperty2Label.setText(" Thermal:");
partProperty2TextField.setText("N.A.");
partProperty2TextField.putClientProperty("tooltip", "Not applicable to thermal analysis");
partProperty3Label.setText(" Solar:");
partProperty3TextField.setText("N.A.");
partProperty3TextField.putClientProperty("tooltip", "Not applicable to solar analysis");
}
});
}
}
} else {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final int numberOfSolarPanels = Scene.getInstance().countSolarPanels();
if (numberOfSolarPanels > 0) {
partPanelBorder.setTitle("Solar Panels");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfSolarPanels);
partProperty1TextField.putClientProperty("tooltip", "Total number of solar panels");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(PvProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of solar panels");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfHeliostats = Scene.getInstance().countParts(Mirror.class);
if (numberOfHeliostats > 0) {
partPanelBorder.setTitle("Heliostats");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfHeliostats);
partProperty1TextField.putClientProperty("tooltip", "Total number of heliostats");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of heliostats");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfParabolicTroughs = Scene.getInstance().countParts(ParabolicTrough.class);
if (numberOfParabolicTroughs > 0) {
partPanelBorder.setTitle("Parabolic Troughs");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfParabolicTroughs);
partProperty1TextField.putClientProperty("tooltip", "Total number of parabolic troughs");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of parabolic troughs");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfParabolicDishes = Scene.getInstance().countParts(ParabolicDish.class);
if (numberOfParabolicDishes > 0) {
partPanelBorder.setTitle("Parabolic Dishes");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfParabolicDishes);
partProperty1TextField.putClientProperty("tooltip", "Total number of parabolic dishes");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of parabolic dishes");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfFresnelReflectors = Scene.getInstance().countParts(FresnelReflector.class);
if (numberOfFresnelReflectors > 0) {
partPanelBorder.setTitle("Fresnel Reflectors");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfFresnelReflectors);
partProperty1TextField.putClientProperty("tooltip", "Total number of Fresnel reflectors");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of Fresnel reflectors");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfNodes = Scene.getInstance().countNodes();
if (numberOfNodes > 0) {
partPanelBorder.setTitle("Structures");
partProperty1Label.setText(" Total Nodes:");
partProperty1TextField.setText("" + numberOfNodes);
partProperty1TextField.putClientProperty("tooltip", "Total number of structure nodes");
partProperty2Label.setText(" Total Meshes:");
partProperty2TextField.setText("" + Scene.getInstance().countMeshes());
partProperty2TextField.putClientProperty("tooltip", "Total number of structure meshes");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
partPanelBorder.setTitle(" -");
partProperty1Label.setText(" -");
partProperty1TextField.setText("");
partProperty1TextField.putClientProperty("tooltip", null);
partProperty2Label.setText(" -");
partProperty2TextField.setText("");
partProperty2TextField.putClientProperty("tooltip", null);
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
}
}
}
}
}
}
}
});
}
partPanel.repaint();
// update building properties
final Foundation selectedFoundation;
if (selectedPart == null) {
selectedFoundation = null;
} else if (selectedPart instanceof Foundation) {
selectedFoundation = (Foundation) selectedPart;
} else {
selectedFoundation = selectedPart.getTopContainer();
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (selectedFoundation != null) {
switch(selectedFoundation.getProjectType()) {
case Foundation.TYPE_BUILDING:
dataPanel.remove(instructionPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.remove(cspProjectPanel);
dataPanel.add(buildingPanel, 2);
final Calendar c = Heliodon.getInstance().getCalendar();
final int temp = selectedFoundation.getThermostat().getTemperature(c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, c.get(Calendar.HOUR_OF_DAY));
switch(Scene.getInstance().getUnit()) {
case InternationalSystemOfUnits:
thermostatTemperatureField.setText(temp + " \u00B0C");
break;
case USCustomaryUnits:
thermostatTemperatureField.setText(Math.round(32.0 + 9.0 * temp / 5.0) + " \u00B0F");
break;
}
thermostatPanel.add(adjustThermostatButton, BorderLayout.EAST);
String s2 = selectedFoundation.toString();
s2 = s2.substring(0, s2.indexOf(')') + 1);
final int i1 = s2.indexOf('(');
final int i2 = s2.indexOf(')');
((TitledBorder) buildingPanel.getBorder()).setTitle("Building #" + s2.substring(i1 + 1, i2));
buildingInfoPanel.update(selectedFoundation);
break;
case Foundation.TYPE_PV_PROJECT:
dataPanel.remove(instructionPanel);
dataPanel.remove(buildingPanel);
dataPanel.remove(cspProjectPanel);
dataPanel.add(pvProjectPanel, 2);
pvProjectInfoPanel.update(selectedFoundation);
break;
case Foundation.TYPE_CSP_PROJECT:
dataPanel.remove(instructionPanel);
dataPanel.remove(buildingPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.add(cspProjectPanel, 2);
cspProjectInfoPanel.update(selectedFoundation);
break;
case -1:
dataPanel.remove(instructionPanel);
dataPanel.remove(buildingPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.remove(cspProjectPanel);
break;
}
} else {
dataPanel.remove(buildingPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.remove(cspProjectPanel);
dataPanel.add(instructionPanel, 2);
for (int i = 0; i < instructionSheets.length; i++) {
final String contentType = Scene.getInstance().getInstructionSheetTextType(i);
instructionSheets[i].setContentType(contentType == null ? "text/plain" : contentType);
if (!instructionSheets[i].getText().equals(Scene.getInstance().getInstructionSheetText(i))) {
instructionSheets[i].setText(Scene.getInstance().getInstructionSheetText(i));
}
}
}
dataPanel.validate();
dataPanel.repaint();
}
});
}
use of org.concord.energy3d.model.Mirror in project energy3d by concord-consortium.
the class PopupMenuForWall method getPopupMenuForWall.
static JPopupMenu getPopupMenuForWall() {
if (popupMenuForWall == null) {
final JMenuItem miPaste = new JMenuItem("Paste");
miPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Config.isMac() ? KeyEvent.META_MASK : InputEvent.CTRL_MASK));
miPaste.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
SceneManager.getTaskManager().update(new Callable<Object>() {
@Override
public Object call() throws Exception {
Scene.getInstance().pasteToPickedLocationOnWall();
Scene.getInstance().setEdited(true);
return null;
}
});
}
});
final JMenuItem miClear = new JMenuItem("Clear");
miClear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
SceneManager.getTaskManager().update(new Callable<Object>() {
@Override
public Object call() throws Exception {
Scene.getInstance().removeAllChildren(SceneManager.getInstance().getSelectedPart());
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MainPanel.getInstance().getEnergyButton().setSelected(false);
Scene.getInstance().setEdited(true);
}
});
return null;
}
});
}
});
final JMenuItem miDeleteAllConnectedWalls = new JMenuItem("Delete All Connected Walls");
miDeleteAllConnectedWalls.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
Scene.getInstance().deleteAllConnectedWalls((Wall) selectedPart);
}
}
});
final JMenuItem miThickness = new JMenuItem("Thickness...");
miThickness.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Wall)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Wall w = (Wall) selectedPart;
final String title = "<html>Thickness of " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>Thickness of wall is in meters.<hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Wall", true);
final JRadioButton rb2 = new JRadioButton("All Walls on This Foundation");
final JRadioButton rb3 = new JRadioButton("All Walls");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(w.getThickness() * Scene.getInstance().getAnnotationScale()));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Wall Thickness");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
double val = 0;
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (val < 0.1 || val > 10) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "The thickness of a wall must be between 0.1 and 10 meters.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
val /= Scene.getInstance().getAnnotationScale();
Wall.setDefaultThickess(val);
boolean changed = Math.abs(val - w.getThickness()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeWallThicknessCommand c = new ChangeWallThicknessCommand(w);
w.setThickness(val);
w.draw();
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
final Foundation foundation = w.getTopContainer();
if (!changed) {
for (final Wall x : foundation.getWalls()) {
if (Math.abs(val - x.getThickness()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationWallThicknessCommand c = new ChangeFoundationWallThicknessCommand(foundation);
foundation.setThicknessOfWalls(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
if (!changed) {
for (final Wall x : Scene.getInstance().getAllWalls()) {
if (Math.abs(val - x.getThickness()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeThicknessForAllWallsCommand c = new ChangeThicknessForAllWallsCommand(w);
Scene.getInstance().setThicknessForAllWalls(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
final JMenuItem miHeight = new JMenuItem("Height...");
miHeight.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
private boolean changed;
private double val;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Wall)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Wall w = (Wall) selectedPart;
final String title = "<html>Height of " + partInfo + "</html>";
final String footnote = "<html><hr><font size=2>Height of wall is in meters.<hr></html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Wall", true);
final JRadioButton rb2 = new JRadioButton("All Walls Connected to This One (Direct and Indirect)");
final JRadioButton rb3 = new JRadioButton("All Walls on This Foundation");
final JRadioButton rb4 = new JRadioButton("All Walls");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
panel.add(rb4);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
bg.add(rb4);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
case 3:
rb4.setSelected(true);
break;
}
final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(w.getHeight() * Scene.getInstance().getAnnotationScale()));
gui.add(inputField, BorderLayout.SOUTH);
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Wall Height");
while (true) {
inputField.selectAll();
inputField.requestFocusInWindow();
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
boolean ok = true;
try {
val = Double.parseDouble(inputField.getText());
} catch (final NumberFormatException exception) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if (ok) {
if (val < 1 || val > 1000) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "The height of a wall must be between 1 and 1000 meters.", "Range Error", JOptionPane.ERROR_MESSAGE);
} else {
val /= Scene.getInstance().getAnnotationScale();
changed = Math.abs(val - w.getHeight()) > 0.000001;
if (rb1.isSelected()) {
if (changed) {
final ChangeWallHeightCommand c = new ChangeWallHeightCommand(w);
w.setHeight(val, true);
Scene.getInstance().redrawAllWallsNow();
SceneManager.getInstance().getUndoManager().addEdit(c);
final Foundation foundation = w.getTopContainer();
if (foundation.hasSolarReceiver()) {
foundation.drawSolarReceiver();
for (final HousePart x : Scene.getInstance().getParts()) {
if (x instanceof FresnelReflector) {
final FresnelReflector reflector = (FresnelReflector) x;
if (foundation == reflector.getReceiver() && reflector.isSunBeamVisible()) {
reflector.drawSunBeam();
}
} else if (x instanceof Mirror) {
final Mirror heliostat = (Mirror) x;
if (foundation == heliostat.getReceiver() && heliostat.isSunBeamVisible()) {
heliostat.drawSunBeam();
}
}
}
}
}
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
if (!changed) {
w.visitNeighbors(new WallVisitor() {
@Override
public void visit(final Wall currentWall, final Snap prev, final Snap next) {
if (Math.abs(val - currentWall.getHeight()) > 0.000001) {
changed = true;
}
}
});
}
if (changed) {
final ChangeHeightForConnectedWallsCommand c = new ChangeHeightForConnectedWallsCommand(w);
Scene.getInstance().setHeightOfConnectedWalls(w, val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
final Foundation foundation = w.getTopContainer();
if (!changed) {
for (final Wall x : foundation.getWalls()) {
if (Math.abs(val - x.getHeight()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeFoundationWallHeightCommand c = new ChangeFoundationWallHeightCommand(foundation);
foundation.setHeightOfWalls(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 2;
} else if (rb4.isSelected()) {
if (!changed) {
for (final Wall x : Scene.getInstance().getAllWalls()) {
if (Math.abs(val - x.getHeight()) > 0.000001) {
changed = true;
break;
}
}
}
if (changed) {
final ChangeHeightForAllWallsCommand c = new ChangeHeightForAllWallsCommand(w);
Scene.getInstance().setHeightForAllWalls(val);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
selectedScopeIndex = 3;
}
if (changed) {
updateAfterEdit();
}
if (choice == options[0]) {
break;
}
}
}
}
}
}
});
final JCheckBoxMenuItem miOutline = new JCheckBoxMenuItem("Outline...", true);
miOutline.addActionListener(new ActionListener() {
// remember the scope selection as the next action will likely be applied to the same scope
private int selectedScopeIndex = 0;
@Override
public void actionPerformed(final ActionEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (!(selectedPart instanceof Wall)) {
return;
}
final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
final Wall w = (Wall) selectedPart;
final String title = "<html>Outline of " + partInfo + "</html>";
final String footnote = "<html>Hiding outline may create a continuous effect of a polygon<br>formed by many walls.</html>";
final JPanel gui = new JPanel(new BorderLayout());
final JPanel panel = new JPanel();
gui.add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
final JRadioButton rb1 = new JRadioButton("Only this Wall", true);
final JRadioButton rb2 = new JRadioButton("All Walls Connected to This One (Direct and Indirect)");
final JRadioButton rb3 = new JRadioButton("All Walls on This Foundation");
final JRadioButton rb4 = new JRadioButton("All Walls");
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
panel.add(rb4);
final ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
bg.add(rb4);
switch(selectedScopeIndex) {
case 0:
rb1.setSelected(true);
break;
case 1:
rb2.setSelected(true);
break;
case 2:
rb3.setSelected(true);
break;
case 3:
rb4.setSelected(true);
break;
}
final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Wall Outline");
while (true) {
dialog.setVisible(true);
final Object choice = optionPane.getValue();
if (choice == options[1] || choice == null) {
break;
} else {
if (rb1.isSelected()) {
// final ChangeWallHeightCommand c = new ChangeWallHeightCommand(w);
w.showOutline(miOutline.isSelected());
w.draw();
// SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 0;
} else if (rb2.isSelected()) {
// final ChangeHeightForConnectedWallsCommand c = new ChangeHeightForConnectedWallsCommand(w);
Scene.getInstance().showOutlineOfConnectedWalls(w, miOutline.isSelected());
// SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 1;
} else if (rb3.isSelected()) {
final Foundation foundation = w.getTopContainer();
// final ChangeFoundationWallHeightCommand c = new ChangeFoundationWallHeightCommand(foundation);
foundation.showOutlineOfWalls(miOutline.isSelected());
// SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 2;
} else if (rb4.isSelected()) {
// final ChangeHeightForAllWallsCommand c = new ChangeHeightForAllWallsCommand(w);
Scene.getInstance().showOutlineForAllWalls(miOutline.isSelected());
// SceneManager.getInstance().getUndoManager().addEdit(c);
selectedScopeIndex = 3;
}
updateAfterEdit();
if (choice == options[0]) {
break;
}
}
}
}
});
popupMenuForWall = createPopupMenu(false, false, new Runnable() {
@Override
public void run() {
final HousePart copyBuffer = Scene.getInstance().getCopyBuffer();
miPaste.setEnabled(copyBuffer instanceof Window || copyBuffer instanceof SolarPanel || copyBuffer instanceof Rack);
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall w = (Wall) selectedPart;
Util.selectSilently(miOutline, w.outlineShown());
}
}
});
popupMenuForWall.add(miPaste);
popupMenuForWall.add(miDeleteAllConnectedWalls);
popupMenuForWall.add(miClear);
popupMenuForWall.addSeparator();
popupMenuForWall.add(colorAction);
popupMenuForWall.add(miOutline);
popupMenuForWall.add(miThickness);
popupMenuForWall.add(miHeight);
popupMenuForWall.add(createInsulationMenuItem(false));
popupMenuForWall.add(createVolumetricHeatCapacityMenuItem());
popupMenuForWall.addSeparator();
final JMenu textureMenu = new JMenu("Texture");
popupMenuForWall.add(textureMenu);
final ButtonGroup textureGroup = new ButtonGroup();
final JRadioButtonMenuItem rbmiTextureNone = new JRadioButtonMenuItem("No Texture");
rbmiTextureNone.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final ChangeBuildingTextureCommand c = new ChangeBuildingTextureCommand();
Scene.getInstance().setTextureMode(TextureMode.None);
Scene.getInstance().setEdited(true);
if (MainPanel.getInstance().getEnergyButton().isSelected()) {
MainPanel.getInstance().getEnergyButton().setSelected(false);
}
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
});
textureGroup.add(rbmiTextureNone);
textureMenu.add(rbmiTextureNone);
final JRadioButtonMenuItem rbmiTextureOutline = new JRadioButtonMenuItem("Outline Texture");
rbmiTextureOutline.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final ChangeBuildingTextureCommand c = new ChangeBuildingTextureCommand();
Scene.getInstance().setTextureMode(TextureMode.Simple);
Scene.getInstance().setEdited(true);
if (MainPanel.getInstance().getEnergyButton().isSelected()) {
MainPanel.getInstance().getEnergyButton().setSelected(false);
}
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
});
textureGroup.add(rbmiTextureOutline);
textureMenu.add(rbmiTextureOutline);
textureMenu.addSeparator();
final JRadioButtonMenuItem rbmiTexture01 = MainFrame.getInstance().createWallTextureMenuItem(Wall.TEXTURE_01, "icons/wall_01.png");
final JRadioButtonMenuItem rbmiTexture02 = MainFrame.getInstance().createWallTextureMenuItem(Wall.TEXTURE_02, "icons/wall_02.png");
final JRadioButtonMenuItem rbmiTexture03 = MainFrame.getInstance().createWallTextureMenuItem(Wall.TEXTURE_03, "icons/wall_03.png");
final JRadioButtonMenuItem rbmiTexture04 = MainFrame.getInstance().createWallTextureMenuItem(Wall.TEXTURE_04, "icons/wall_04.png");
final JRadioButtonMenuItem rbmiTexture05 = MainFrame.getInstance().createWallTextureMenuItem(Wall.TEXTURE_05, "icons/wall_05.png");
final JRadioButtonMenuItem rbmiTexture06 = MainFrame.getInstance().createWallTextureMenuItem(Wall.TEXTURE_06, "icons/wall_06.png");
textureGroup.add(rbmiTexture01);
textureGroup.add(rbmiTexture02);
textureGroup.add(rbmiTexture03);
textureGroup.add(rbmiTexture04);
textureGroup.add(rbmiTexture05);
textureGroup.add(rbmiTexture06);
textureMenu.add(rbmiTexture01);
textureMenu.add(rbmiTexture02);
textureMenu.add(rbmiTexture03);
textureMenu.add(rbmiTexture04);
textureMenu.add(rbmiTexture05);
textureMenu.add(rbmiTexture06);
textureMenu.addMenuListener(new MenuListener() {
@Override
public void menuSelected(final MenuEvent e) {
if (Scene.getInstance().getTextureMode() == TextureMode.None) {
Util.selectSilently(rbmiTextureNone, true);
return;
}
if (Scene.getInstance().getTextureMode() == TextureMode.Simple) {
Util.selectSilently(rbmiTextureOutline, true);
return;
}
switch(Scene.getInstance().getWallTextureType()) {
case Wall.TEXTURE_01:
Util.selectSilently(rbmiTexture01, true);
break;
case Wall.TEXTURE_02:
Util.selectSilently(rbmiTexture02, true);
break;
case Wall.TEXTURE_03:
Util.selectSilently(rbmiTexture03, true);
break;
case Wall.TEXTURE_04:
Util.selectSilently(rbmiTexture04, true);
break;
case Wall.TEXTURE_05:
Util.selectSilently(rbmiTexture05, true);
break;
case Wall.TEXTURE_06:
Util.selectSilently(rbmiTexture06, true);
break;
}
}
@Override
public void menuDeselected(final MenuEvent e) {
textureMenu.setEnabled(true);
}
@Override
public void menuCanceled(final MenuEvent e) {
textureMenu.setEnabled(true);
}
});
final JMenu typeMenu = new JMenu("Type");
popupMenuForWall.add(typeMenu);
popupMenuForWall.addSeparator();
final ButtonGroup typeGroup = new ButtonGroup();
final JRadioButtonMenuItem rbmiSolidWall = new JRadioButtonMenuItem("Solid Wall");
rbmiSolidWall.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.SOLID_WALL);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiSolidWall);
typeGroup.add(rbmiSolidWall);
final JRadioButtonMenuItem rbmiEmpty = new JRadioButtonMenuItem("Empty");
rbmiEmpty.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.EMPTY);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiEmpty);
typeGroup.add(rbmiEmpty);
final JRadioButtonMenuItem rbmiEdges = new JRadioButtonMenuItem("Vertical Edges");
rbmiEdges.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.VERTICAL_EDGES_ONLY);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiEdges);
typeGroup.add(rbmiEdges);
final JRadioButtonMenuItem rbmiColumns = new JRadioButtonMenuItem("Columns");
rbmiColumns.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.COLUMNS_ONLY);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiColumns);
typeGroup.add(rbmiColumns);
final JRadioButtonMenuItem rbmiRails = new JRadioButtonMenuItem("Rails");
rbmiRails.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.RAILS_ONLY);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiRails);
typeGroup.add(rbmiRails);
final JRadioButtonMenuItem rbmiColumnsAndRailings = new JRadioButtonMenuItem("Columns & Railings");
rbmiColumnsAndRailings.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.COLUMNS_RAILS);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiColumnsAndRailings);
typeGroup.add(rbmiColumnsAndRailings);
final JRadioButtonMenuItem rbmiFence = new JRadioButtonMenuItem("Fence");
rbmiFence.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.FENCE);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiFence);
typeGroup.add(rbmiFence);
final JRadioButtonMenuItem rbmiSteelFrame = new JRadioButtonMenuItem("Steel Frame");
rbmiSteelFrame.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
final ChangeWallTypeCommand c = new ChangeWallTypeCommand(wall);
wall.setType(Wall.STEEL_FRAME);
wall.draw();
Scene.getInstance().setEdited(true);
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
});
typeMenu.add(rbmiSteelFrame);
typeGroup.add(rbmiSteelFrame);
typeMenu.addMenuListener(new MenuListener() {
@Override
public void menuSelected(final MenuEvent e) {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
switch(wall.getType()) {
case Wall.SOLID_WALL:
Util.selectSilently(rbmiSolidWall, true);
break;
case Wall.EMPTY:
Util.selectSilently(rbmiEmpty, true);
break;
case Wall.VERTICAL_EDGES_ONLY:
Util.selectSilently(rbmiEdges, true);
break;
case Wall.COLUMNS_ONLY:
Util.selectSilently(rbmiColumns, true);
break;
case Wall.RAILS_ONLY:
Util.selectSilently(rbmiRails, true);
break;
case Wall.COLUMNS_RAILS:
Util.selectSilently(rbmiColumnsAndRailings, true);
break;
case Wall.STEEL_FRAME:
Util.selectSilently(rbmiSteelFrame, true);
break;
}
}
}
@Override
public void menuDeselected(final MenuEvent e) {
typeMenu.setEnabled(true);
}
@Override
public void menuCanceled(final MenuEvent e) {
typeMenu.setEnabled(true);
}
});
JMenuItem mi = new JMenuItem("Daily Energy Analysis...");
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (EnergyPanel.getInstance().adjustCellSize()) {
return;
}
if (SceneManager.getInstance().getSelectedPart() instanceof Wall) {
new EnergyDailyAnalysis().show("Daily Energy for Wall");
}
}
});
popupMenuForWall.add(mi);
mi = new JMenuItem("Annual Energy Analysis...");
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (EnergyPanel.getInstance().adjustCellSize()) {
return;
}
if (SceneManager.getInstance().getSelectedPart() instanceof Wall) {
new EnergyAnnualAnalysis().show("Annual Energy for Wall");
}
}
});
popupMenuForWall.add(mi);
}
return popupMenuForWall;
}
Aggregations