1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.ui;
39
40 import static ffx.potential.bonded.RendererCache.pickingColor;
41 import static ffx.potential.bonded.RendererCache.selectionColor;
42 import static ffx.potential.bonded.RendererCache.userColor;
43 import static java.lang.String.format;
44
45 import ffx.potential.MolecularAssembly;
46 import ffx.potential.bonded.MSNode;
47 import ffx.potential.bonded.RendererCache;
48 import ffx.potential.bonded.RendererCache.ColorModel;
49 import ffx.potential.bonded.RendererCache.ViewModel;
50
51 import java.awt.Color;
52 import java.awt.Font;
53 import java.awt.GraphicsConfiguration;
54 import java.awt.GraphicsEnvironment;
55 import java.awt.Rectangle;
56 import java.awt.Toolkit;
57 import java.awt.event.ActionEvent;
58 import java.awt.event.ActionListener;
59 import java.awt.image.BufferedImage;
60 import java.io.File;
61 import java.io.IOException;
62 import java.util.ArrayList;
63 import java.util.HashMap;
64 import java.util.logging.Level;
65 import java.util.logging.Logger;
66 import java.util.prefs.Preferences;
67 import javax.imageio.ImageIO;
68 import javax.swing.JButton;
69 import javax.swing.JCheckBoxMenuItem;
70 import javax.swing.JColorChooser;
71 import javax.swing.JFileChooser;
72 import javax.swing.JLabel;
73 import javax.swing.JOptionPane;
74
75 import org.jogamp.java3d.AmbientLight;
76 import org.jogamp.java3d.Background;
77 import org.jogamp.java3d.BoundingSphere;
78 import org.jogamp.java3d.Bounds;
79 import org.jogamp.java3d.BranchGroup;
80 import org.jogamp.java3d.Canvas3D;
81 import org.jogamp.java3d.DirectionalLight;
82 import org.jogamp.java3d.GraphicsConfigTemplate3D;
83 import org.jogamp.java3d.GraphicsContext3D;
84 import org.jogamp.java3d.ImageComponent;
85 import org.jogamp.java3d.ImageComponent2D;
86 import org.jogamp.java3d.J3DGraphics2D;
87 import org.jogamp.java3d.Raster;
88 import org.jogamp.java3d.Transform3D;
89 import org.jogamp.java3d.TransformGroup;
90 import org.jogamp.java3d.View;
91 import org.jogamp.java3d.utils.universe.SimpleUniverse;
92 import org.jogamp.vecmath.Color3f;
93 import org.jogamp.vecmath.Point3d;
94 import org.jogamp.vecmath.Point3f;
95 import org.jogamp.vecmath.Vector3d;
96 import org.jogamp.vecmath.Vector3f;
97
98
99
100
101
102
103
104 @SuppressWarnings("serial")
105 public class GraphicsCanvas extends Canvas3D implements ActionListener {
106
107 private static final Logger logger = Logger.getLogger(GraphicsCanvas.class.getName());
108
109
110
111 private static final HashMap<String, ImageFormat> imageFormatHash = new HashMap<>();
112
113
114
115 private static final Preferences prefs = Preferences.userNodeForPackage(GraphicsCanvas.class);
116
117 static {
118 ImageFormat[] values = ImageFormat.values();
119 for (ImageFormat value : values) {
120 imageFormatHash.put(value.toString(), value);
121 }
122 }
123
124
125 private ffx.potential.Renderer renderer;
126 private GraphicsEvents graphicsEvents;
127 private GraphicsPicking rendererPicking;
128 private MainPanel mainPanel;
129 private GraphicsAxis graphicsAxis;
130 private GraphicsFullScreen fullScreenWindow;
131
132 private SimpleUniverse universe;
133 private Background background;
134 private BranchGroup baseBranchGroup;
135 private TransformGroup baseTransformGroup;
136 private Transform3D baseTransform3D = new Transform3D();
137 private Bounds bounds;
138
139 private GraphicsPrefs graphics3DPrefs = null;
140 private MouseMode mouseMode = MouseMode.ACTIVESYSTEM;
141 private ImageFormat imageFormat = ImageFormat.PNG;
142 private LeftButtonMode leftButtonMode = LeftButtonMode.ROTATE;
143 private boolean imageCapture = false;
144 private File imageName;
145
146
147
148
149
150
151
152 GraphicsCanvas(GraphicsConfiguration config, MainPanel mainPanel) {
153 super(config);
154 this.mainPanel = mainPanel;
155 initialize();
156 }
157
158
159
160
161
162
163 public GraphicsCanvas(MainPanel mainlPanel) {
164 this(
165 GraphicsEnvironment.getLocalGraphicsEnvironment()
166 .getDefaultScreenDevice()
167 .getBestConfiguration(new GraphicsConfigTemplate3D()),
168 mainlPanel);
169 }
170
171
172
173
174
175
176 @Override
177 public void actionPerformed(ActionEvent evt) {
178 String arg = evt.getActionCommand();
179
180 if (arg.equals("LabelSelectedAtoms")) {
181 labelSelectedAtoms();
182 } else if (arg.equals("LabelSelectedResidues")) {
183 labelSelectedResidues();
184 } else if (arg.equals("SetLabelFontColor")) {
185 setLabelFontColor();
186 } else if (arg.equals("SetLabelFontSize")) {
187 setLabelFontSize();
188
189 } else if (RendererCache.viewModelHash.containsKey(arg.toUpperCase())) {
190 setViewModel(arg);
191 } else if (arg.equals("Preferences")) {
192 preferences();
193
194 } else if (RendererCache.colorModelHash.containsKey(arg.toUpperCase())) {
195 setColorModel(arg);
196 } else if (arg.equals("SetSelectionColor")) {
197 setSelectionColor();
198 } else if (arg.equals("SetUserColor")) {
199 setUserColor();
200
201 } else if (arg.equals("SystemBelowMouse")) {
202 mouseMode = MouseMode.SYSTEMBELOWMOUSE;
203 } else if (arg.equals("ActiveSystem")) {
204 mouseMode = MouseMode.ACTIVESYSTEM;
205 } else if (arg.equals("Rotate")) {
206 leftButtonMode = LeftButtonMode.ROTATE;
207 } else if (arg.equals("Translate")) {
208 leftButtonMode = LeftButtonMode.TRANSLATE;
209 } else if (arg.equals("Zoom")) {
210 leftButtonMode = LeftButtonMode.ZOOM;
211 } else if (arg.equals("ResetRotation")) {
212 resetRotation();
213 } else if (arg.equals("ResetTranslation")) {
214 resetTranslation();
215 } else if (arg.equals("ResetRotationAndTranslation")) {
216 resetRotationAndTranslation();
217 } else if (arg.equalsIgnoreCase("RotateAboutPick")) {
218 rotateAboutPick();
219 } else if (arg.equalsIgnoreCase("RotateAboutCenter")) {
220 rotateAboutCenter();
221 } else if (arg.equalsIgnoreCase("ResetGlobalTranslation")) {
222 resetGlobalTranslation();
223 } else if (arg.equalsIgnoreCase("ResetGlobalRotation")) {
224 resetGlobalRotation();
225 } else if (arg.equalsIgnoreCase("ResetGlobalZoom")) {
226 resetGlobalZoom();
227 } else if (arg.equalsIgnoreCase("ResetGlobalView")) {
228 resetGlobalView();
229 } else if (arg.equals("FullScreen")) {
230 fullScreen();
231 } else if (arg.equals("SetBackgroundColor")) {
232 setBackgroundColor();
233 } else if (arg.equalsIgnoreCase("ZoomIn")) {
234 zoomIn();
235 } else if (arg.equalsIgnoreCase("ZoomOut")) {
236 zoomOut();
237
238 } else if (arg.equalsIgnoreCase("GraphicsPicking")) {
239 graphicsPicking(evt);
240 } else if (imageFormatHash.containsKey(arg.toUpperCase())) {
241 setImageFormat(arg);
242 } else if (arg.equals("CaptureGraphics")) {
243 captureGraphics();
244 } else if (GraphicsPicking.pickLevelHash.containsKey(arg.toUpperCase())) {
245 setPickingLevel(arg);
246 } else if (arg.equals("SetGraphicsPickingColor")) {
247 setGraphicsPickingColor();
248 } else {
249 logger.warning(format("Graphics Menu command not found: %s.", arg));
250 }
251 }
252
253
254
255
256
257
258 public void colorWait(String colorMode) {
259 if (colorMode == null) {
260 logger.info("Null color.");
261 return;
262 }
263 try {
264 ColorModel colorModel = ColorModel.valueOf(colorMode.toUpperCase());
265 colorWait(colorModel);
266 } catch (Exception e) {
267 logger.info("Unknown color command.");
268 }
269 }
270
271
272
273
274
275
276 public GraphicsAxis getNavigation() {
277 return graphicsAxis;
278 }
279
280
281
282
283 @Override
284 public void paint(java.awt.Graphics g) {
285 super.paint(g);
286 Toolkit.getDefaultToolkit().sync();
287 }
288
289
290
291
292
293
294 @Override
295 public void postRender() {
296 if (RendererCache.labelAtoms || RendererCache.labelResidues) {
297 J3DGraphics2D g2D = getGraphics2D();
298 synchronized (mainPanel.getHierarchy()) {
299 ArrayList<MSNode> nodes = mainPanel.getHierarchy().getActiveNodes();
300 if (nodes != null && !nodes.isEmpty()) {
301 for (MSNode node : nodes) {
302 MolecularAssembly sys = node.getMSNode(MolecularAssembly.class);
303 if (sys != null) {
304 node.drawLabel(this, g2D, sys.getWireFrame());
305 }
306 }
307 } else {
308 return;
309 }
310 }
311 g2D.flush(true);
312 }
313 }
314
315
316
317
318
319
320 @Override
321 public void postSwap() {
322 if (!imageCapture || mainPanel.getHierarchy().getActive() == null) {
323 return;
324 }
325 GraphicsContext3D ctx = getGraphicsContext3D();
326 Rectangle rect = getBounds();
327 BufferedImage img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_RGB);
328 ImageComponent2D comp = new ImageComponent2D(ImageComponent.FORMAT_RGB, img);
329 Raster ras = new Raster(new Point3f(-1.0f, -1.0f, -1.0f),
330 Raster.RASTER_COLOR, 0, 0, rect.width, rect.height, comp, null);
331 ctx.readRaster(ras);
332 img = ras.getImage().getImage();
333 try {
334 if (!ImageIO.write(img, imageFormat.toString(), imageName)) {
335 logger.warning(
336 format(
337 " No image writer was found for %s.\n Please try a different image format.\n",
338 imageFormat.toString()));
339 imageName.delete();
340 } else {
341 logger.info(format(" %s was captured.", imageName));
342 }
343 } catch (IOException e) {
344 logger.warning(e.getMessage());
345 }
346 imageCapture = false;
347 }
348
349
350
351
352 public void selected() {
353 validate();
354 repaint();
355 }
356
357
358
359
360
361
362 public void setCaptures(boolean c) {
363 imageCapture = c;
364 }
365
366
367
368
369
370
371 public void setColor(String model) {
372 setColorModel(model);
373 }
374
375
376
377
378
379
380
381 public void setColorModel(String model, MSNode node) {
382 if (node == null) {
383 return;
384 }
385 if (!RendererCache.colorModelHash.containsKey(model.toUpperCase())) {
386 return;
387 }
388 ColorModel colorModel = RendererCache.colorModelHash.get(model.toUpperCase());
389 renderer.arm(node, false, false, null, true, colorModel);
390 }
391
392
393
394
395 public void setPosition() {
396 setPosition(mainPanel.getHierarchy().getActive());
397 }
398
399
400
401
402
403
404 public void setPosition(MSNode node) {
405 updateScene(node, true, false, null, true, null);
406 }
407
408
409
410
411 public void setView(String model) {
412 setViewModel(model);
413 }
414
415
416
417
418
419
420
421 public void setViewModel(String model, MSNode node) {
422 if (node == null) {
423 return;
424 }
425 if (!RendererCache.viewModelHash.containsKey(model.toUpperCase())) {
426 return;
427 }
428 RendererCache.ViewModel viewModel = RendererCache.viewModelHash.get(model.toUpperCase());
429 renderer.arm(node, false, true, viewModel, false, null);
430 }
431
432
433
434
435 @Override
436 public String toString() {
437 return "3D Graphics";
438 }
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453 public void updateScene(
454 ArrayList<MSNode> n,
455 boolean t,
456 boolean v,
457 ViewModel newViewModel,
458 boolean c,
459 ColorModel newColorModel) {
460 if (n != null) {
461 renderer.arm(n, t, v, newViewModel, c, newColorModel);
462 }
463 }
464
465
466
467
468
469
470
471
472
473
474
475 public void updateScene(
476 MSNode n, boolean t, boolean v, ViewModel newViewModel, boolean c, ColorModel newColorModel) {
477 if (n != null) {
478 renderer.arm(n, t, v, newViewModel, c, newColorModel);
479 }
480 }
481
482
483
484
485
486
487
488
489
490 public void viewWait(String viewMode) {
491 if (viewMode == null) {
492 logger.info("Null view.");
493 return;
494 }
495 try {
496 ViewModel viewModel = ViewModel.valueOf(viewMode.toUpperCase());
497 viewWait(viewModel);
498 } catch (Exception e) {
499 logger.info("Unknown view command.");
500 }
501 }
502
503
504
505
506
507
508 void attachModel(MolecularAssembly s) {
509 if (s == null) {
510 return;
511 }
512 synchronized (this) {
513 BranchGroup bg = s.getBranchGroup();
514 resetGlobalView();
515 baseBranchGroup.addChild(bg);
516 }
517 }
518
519 private void captureGraphics() {
520 MolecularAssembly active = mainPanel.getHierarchy().getActive();
521 if (active == null) {
522 return;
523 }
524 imageName = null;
525 String name = active.getName();
526 JFileChooser fileChooser = MainPanel.resetFileChooser();
527 fileChooser.setAcceptAllFileFilterUsed(true);
528 if (mainPanel.getHierarchy().getActive() != null) {
529 imageName = mainPanel.getHierarchy().getActive().getFile();
530 } else {
531 imageName = null;
532 }
533 if (imageName != null) {
534 if (name.indexOf(".") > 0) {
535 name = name.substring(0, name.indexOf("."));
536 }
537 imageName = new File(imageName.getParentFile() + File.separator + name + "." + imageFormat);
538 fileChooser.setSelectedFile(imageName);
539 }
540 fileChooser.setDialogTitle("Select Name for Screen Capture " + "(" + imageFormat + ")");
541 fileChooser.setCurrentDirectory(MainPanel.getPWD());
542 int result = fileChooser.showSaveDialog(this);
543 if (result == JFileChooser.APPROVE_OPTION) {
544 imageName = fileChooser.getSelectedFile();
545 mainPanel.setCWD(fileChooser.getCurrentDirectory());
546 imageCapture = true;
547 repaint();
548 }
549 }
550
551
552
553
554 private void fullScreen() {
555 if (fullScreenWindow == null) {
556 fullScreenWindow = new GraphicsFullScreen(mainPanel.getFrame(), this);
557 }
558 fullScreenWindow.enterFullScreen();
559 }
560
561
562
563
564
565
566 MouseMode getMouseMode() {
567 return mouseMode;
568 }
569
570
571
572
573
574
575 LeftButtonMode getLeftButtonMode() {
576 return leftButtonMode;
577 }
578
579
580
581
582
583
584 private JLabel getStatusBar() {
585 return mainPanel.getStatusBar();
586 }
587
588
589
590
591
592
593 private void graphicsPicking(ActionEvent evt) {
594 if (evt.getSource() instanceof JButton) {
595 MainMenu m = mainPanel.getMainMenu();
596 boolean picking = m.getPicking();
597 if (picking) {
598 rendererPicking.clear();
599 rendererPicking.setPicking(false);
600 m.setPickBehavior(false);
601 } else {
602 rendererPicking.setPicking(true);
603 m.setPickBehavior(true);
604 }
605 } else if (evt.getSource() instanceof JCheckBoxMenuItem) {
606 JCheckBoxMenuItem jcbmi = (JCheckBoxMenuItem) evt.getSource();
607 if (jcbmi.isSelected()) {
608 rendererPicking.setPicking(true);
609 } else {
610 rendererPicking.setPicking(false);
611 }
612 }
613 }
614
615
616
617
618
619
620
621 private void initialize() {
622 setBackground(Color.black);
623 universe = new SimpleUniverse(this);
624 SimpleUniverse.setJ3DThreadPriority(Thread.MAX_PRIORITY);
625 universe.getViewingPlatform().setNominalViewingTransform();
626
627 BranchGroup objRoot = new BranchGroup();
628 baseTransformGroup = new TransformGroup();
629 Transform3D t3d = new Transform3D();
630 t3d.setScale(0.1d);
631 baseTransformGroup.setTransform(t3d);
632 baseTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
633 baseTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
634
635 background = new Background(RendererCache.BLACK);
636 background.setCapability(Background.ALLOW_COLOR_READ);
637 background.setCapability(Background.ALLOW_COLOR_WRITE);
638 bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 2000.0);
639 background.setApplicationBounds(bounds);
640
641 AmbientLight aLgt =
642 new AmbientLight(new Color3f(Color.darkGray.getRGBColorComponents(new float[3])));
643 aLgt.setInfluencingBounds(bounds);
644 Vector3f dir = new Vector3f(0.0f, -1.0f, -1.0f);
645 Color3f dLgtColor = new Color3f(Color.lightGray.getRGBColorComponents(new float[3]));
646 DirectionalLight dLgt = new DirectionalLight(dLgtColor, dir);
647 dLgt.setInfluencingBounds(bounds);
648 dir = new Vector3f(0.0f, 1.0f, -1.0f);
649 dLgtColor = new Color3f(0.1f, 0.1f, 0.1f);
650 DirectionalLight dLgt2 = new DirectionalLight(dLgtColor, dir);
651 dLgt2.setInfluencingBounds(bounds);
652
653 baseBranchGroup = new BranchGroup();
654 baseBranchGroup.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
655 baseBranchGroup.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
656 baseBranchGroup.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
657 baseBranchGroup.setCapability(BranchGroup.ALLOW_BOUNDS_READ);
658
659 baseTransformGroup.addChild(background);
660 baseTransformGroup.addChild(baseBranchGroup);
661 objRoot.addChild(baseTransformGroup);
662
663 View v = universe.getViewer().getView();
664 v.setProjectionPolicy(View.PARALLEL_PROJECTION);
665 v.setFrontClipPolicy(View.VIRTUAL_EYE);
666 v.setFrontClipDistance(1.0);
667 v.setBackClipPolicy(View.VIRTUAL_EYE);
668 v.setBackClipDistance(10.0);
669 v.setTransparencySortingPolicy(View.TRANSPARENCY_SORT_NONE);
670 Transform3D trans = new Transform3D();
671 trans.set(new Vector3d(0.0d, 0.0d, 2.0d));
672 TransformGroup vptg = universe.getViewingPlatform().getViewPlatformTransform();
673 vptg.setTransform(trans);
674 BranchGroup viewBranch = new BranchGroup();
675 viewBranch.addChild(aLgt);
676 viewBranch.addChild(dLgt);
677 viewBranch.addChild(dLgt2);
678 vptg.addChild(viewBranch);
679
680 graphicsAxis = new GraphicsAxis(universe.getViewingPlatform(), bounds);
681 graphicsEvents =
682 new GraphicsEvents(
683 mainPanel, this, graphicsAxis, universe, bounds, baseBranchGroup, baseTransformGroup);
684 baseBranchGroup.addChild(graphicsEvents);
685 rendererPicking = new GraphicsPicking(baseBranchGroup, bounds, this, mainPanel);
686 baseBranchGroup.addChild(rendererPicking);
687 renderer = new ffx.potential.Renderer(bounds, mainPanel.getStatusBar());
688 baseBranchGroup.addChild(renderer);
689
690 objRoot.compile();
691 universe.addBranchGraph(objRoot);
692 }
693
694
695
696
697
698
699 boolean isCacheFull() {
700 return renderer.isCacheFull();
701 }
702
703
704
705
706
707
708 boolean isSceneRendering() {
709 return renderer.isArmed();
710 }
711
712
713
714
715 private void labelSelectedAtoms() {
716 if (RendererCache.labelAtoms) {
717 RendererCache.labelAtoms = false;
718 getStatusBar().setText(" Atom Labeling Turned Off");
719 } else {
720 RendererCache.labelAtoms = true;
721 getStatusBar().setText(" Atom Labeling Turned On");
722 }
723 repaint();
724 }
725
726
727
728
729 private void labelSelectedResidues() {
730 if (RendererCache.labelResidues) {
731 RendererCache.labelResidues = false;
732 getStatusBar().setText(" Residue Labeling Turned Off");
733 } else {
734 RendererCache.labelResidues = true;
735 getStatusBar().setText(" Residue Labeling Turned On");
736 }
737 repaint();
738 }
739
740
741
742
743
744
745
746 void loadPrefs() {
747 String c = GraphicsCanvas.class.getName();
748 RendererCache.bondwidth = prefs.getInt(c + ".bondwidth", 3);
749 RendererCache.detail = prefs.getInt(c + ".detail", 3);
750 RendererCache.radius = prefs.getDouble(c + ".radius", 1.0d);
751 String s = prefs.get(c + ".mouse", MouseMode.ACTIVESYSTEM.name());
752 if (s.equalsIgnoreCase("ACTIVESYSTEM") || s.equalsIgnoreCase("SYSTEMBELOWMOUSE")) {
753 mouseMode = MouseMode.valueOf(s);
754 } else {
755 mouseMode = MouseMode.ACTIVESYSTEM;
756 }
757 mainPanel.getMainMenu().setMouseMode(mouseMode);
758 RendererCache.highlightSelections = prefs.getBoolean(c + ".highlight", false);
759 mainPanel.getMainMenu().setHighlighting(RendererCache.highlightSelections);
760 String[] hlColor = prefs.get(c + ".highlightColor", "153 153 255").trim().split(" +");
761 selectionColor =
762 new Color3f(
763 Float.parseFloat(hlColor[0]),
764 Float.parseFloat(hlColor[1]),
765 Float.parseFloat(hlColor[2]));
766 RendererCache.labelAtoms = prefs.getBoolean(c + ".labelAtoms", false);
767 mainPanel.getMainMenu().setAtomLabels(RendererCache.labelAtoms);
768 RendererCache.labelResidues = prefs.getBoolean(c + ".labelResidues", false);
769 mainPanel.getMainMenu().setResidueLabels(RendererCache.labelResidues);
770
771
772
773
774
775
776
777
778
779
780
781 String[] pickColor = prefs.get(c + ".pickColor", "102 255 102").trim().split(" +");
782 pickingColor =
783 new Color3f(
784 Float.parseFloat(pickColor[0]),
785 Float.parseFloat(pickColor[1]),
786 Float.parseFloat(pickColor[2]));
787 String pickLevel = prefs.get(c + ".pickLevel", "PickAtom");
788 mainPanel.getMainMenu().setPickLevel(pickLevel);
789 boolean pickMode = prefs.getBoolean(c + ".picking", false);
790 if (pickMode) {
791 rendererPicking.setPicking(true);
792 }
793 mainPanel.getMainMenu().setPickBehavior(pickMode);
794 String[] userColor = prefs.get(c + ".userColor", "255 255 255").trim().split(" +");
795 RendererCache.userColor =
796 new Color3f(
797 Float.parseFloat(userColor[0]),
798 Float.parseFloat(userColor[1]),
799 Float.parseFloat(userColor[2]));
800
801
802
803
804
805
806
807 }
808
809
810
811
812 void preferences() {
813 if (graphics3DPrefs == null) {
814 graphics3DPrefs = new GraphicsPrefs(mainPanel.getFrame(), mainPanel.getDataRoot());
815 graphics3DPrefs.setModal(false);
816 }
817 graphics3DPrefs.setVisible(true);
818 graphics3DPrefs.toFront();
819 }
820
821
822
823
824 private void resetGlobalRotation() {
825 graphicsEvents.centerView(true, false, false);
826 }
827
828
829
830
831 private void resetGlobalTranslation() {
832 graphicsEvents.centerView(false, true, false);
833 }
834
835
836
837
838 private void resetGlobalView() {
839 double radius = mainPanel.getDataRoot().getExtent();
840 Transform3D t3d = new Transform3D();
841 t3d.setScale(1.0d / (1.2d * radius));
842 baseTransformGroup.setTransform(t3d);
843 graphicsEvents.centerView(true, true, true);
844 }
845
846
847
848
849 private void resetGlobalZoom() {
850 double radius = mainPanel.getDataRoot().getExtent();
851 baseTransformGroup.getTransform(baseTransform3D);
852 baseTransform3D.setScale(1.0d / (1.2d * radius));
853 baseTransformGroup.setTransform(baseTransform3D);
854 }
855
856
857
858
859 private void resetRotation() {
860 MolecularAssembly sys = mainPanel.getHierarchy().getActive();
861 if (sys != null) {
862 sys.centerView(true, false);
863 }
864 }
865
866
867
868
869
870
871
872 private void resetRotationAndTranslation() {
873 MolecularAssembly sys = mainPanel.getHierarchy().getActive();
874 if (sys != null) {
875 sys.centerView(true, true);
876 }
877 }
878
879
880
881
882 private void resetTranslation() {
883 MolecularAssembly sys = mainPanel.getHierarchy().getActive();
884 if (sys != null) {
885 sys.centerView(false, true);
886 }
887 }
888
889
890
891
892 private void rotateAboutCenter() {
893 MolecularAssembly sys = mainPanel.getHierarchy().getActive();
894 double[] center = sys.getMultiScaleCenter(false);
895 sys.rotateAbout(new Vector3d(center));
896 }
897
898
899
900
901
902
903
904 private void rotateAboutPick() {
905 MSNode node = rendererPicking.getPick();
906 if (node != null) {
907 double[] center = node.getCenter(false);
908 MolecularAssembly m = node.getMSNode(MolecularAssembly.class);
909 m.rotateAbout(new Vector3d(center));
910 }
911 }
912
913
914
915
916 void savePrefs() {
917 String c = GraphicsCanvas.class.getName();
918 prefs.putInt(c + ".bondwidth", RendererCache.bondwidth);
919 prefs.putInt(c + ".detail", RendererCache.detail);
920 prefs.putDouble(c + ".radius", RendererCache.radius);
921 prefs.put(c + ".mouse", mouseMode.name());
922 prefs.putBoolean(c + ".highlight", RendererCache.highlightSelections);
923 prefs.put(c + ".highlightColor", selectionColor.x + " " + selectionColor.y + " " + selectionColor.z);
924 prefs.putBoolean(c + ".labelAtoms", RendererCache.labelAtoms);
925 prefs.putBoolean(c + ".labelResidues", RendererCache.labelResidues);
926 prefs.putInt(c + ".labelSize", getGraphics2D().getFont().getSize());
927 Color fontColor = getGraphics2D().getColor();
928 prefs.put(c + ".labelColor", fontColor.getRed() + " " + fontColor.getGreen() + " " + fontColor.getBlue());
929 prefs.put(c + ".pickColor", pickingColor.x + " " + pickingColor.y + " " + pickingColor.x);
930 prefs.putBoolean(c + ".picking", rendererPicking.getPicking());
931 prefs.put(c + ".pickLevel", rendererPicking.getPickLevel());
932 prefs.put(c + ".userColor", userColor.x + " " + userColor.y + " " + userColor.z);
933 Color3f temp = new Color3f();
934 background.getColor(temp);
935 prefs.put(c + ".backgroundColor", temp.x + " " + temp.y + " " + temp.z);
936 }
937
938
939
940
941
942
943 void setAxisShowing(boolean b) {
944 if (b && graphicsAxis == null) {
945 graphicsAxis = new GraphicsAxis(universe.getViewingPlatform(), bounds);
946 } else if (graphicsAxis != null) {
947 graphicsAxis.showAxis(b);
948 }
949 }
950
951
952
953
954 private void setBackgroundColor() {
955 Color3f col = new Color3f();
956 background.getColor(col);
957 Color currentColor = new Color(col.x, col.y, col.z);
958 Color newcolor = JColorChooser.showDialog(this, "Choose Background Color", currentColor);
959 if (newcolor != null) {
960 background.setColor(new Color3f(newcolor.getRGBColorComponents(new float[3])));
961 }
962 }
963
964
965
966
967
968
969
970
971
972 private void setColorModel(String model) {
973 if (!RendererCache.colorModelHash.containsKey(model.toUpperCase())) {
974 return;
975 }
976 ColorModel colorModel = RendererCache.colorModelHash.get(model.toUpperCase());
977 ArrayList<MSNode> active = mainPanel.getHierarchy().getActiveNodes();
978 if (active == null) {
979 return;
980 }
981 renderer.arm(active, false, false, null, true, colorModel);
982 }
983
984
985
986
987 private void setGraphicsPickingColor() {
988 Color newcolor =
989 JColorChooser.showDialog(
990 this,
991 "Choose Picking Color",
992 new Color(pickingColor.x, pickingColor.y, pickingColor.z));
993 if (newcolor != null) {
994 pickingColor = new Color3f(newcolor.getRGBColorComponents(new float[3]));
995 }
996 }
997
998
999
1000
1001
1002
1003 private void setImageFormat(String format) {
1004 if (format == null) {
1005 return;
1006 }
1007 format = format.toUpperCase();
1008 if (!imageFormatHash.containsKey(format)) {
1009 return;
1010 }
1011 imageFormat = imageFormatHash.get(format);
1012 }
1013
1014
1015
1016
1017 private void setLabelFontColor() {
1018 Color color = getGraphics2D().getColor();
1019 Color newColor = JColorChooser.showDialog(this, "Choose Font Color", color);
1020 if (newColor != null && newColor != color) {
1021 getGraphics2D().setPaint(newColor);
1022 if (RendererCache.labelAtoms || RendererCache.labelResidues) {
1023 repaint();
1024 }
1025 getStatusBar()
1026 .setText(
1027 " Label Font Color Changed to ("
1028 + newColor.getRed()
1029 + ","
1030 + newColor.getGreen()
1031 + ","
1032 + newColor.getBlue()
1033 + ")");
1034 }
1035 }
1036
1037
1038
1039
1040 private void setLabelFontSize() {
1041 Font currentFont = getGraphics2D().getFont();
1042 int currentSize = currentFont.getSize();
1043 String size = Integer.toString(currentSize);
1044 size = JOptionPane.showInputDialog("Set the Font Size (8 to 64)", size);
1045 try {
1046 int f = Integer.parseInt(size);
1047 if (f < 8 || f > 64 || f == currentSize) {
1048 return;
1049 }
1050 Font newFont = new Font(currentFont.getName(), currentFont.getStyle(), f);
1051 getGraphics2D().setFont(newFont);
1052 if (RendererCache.labelAtoms || RendererCache.labelResidues) {
1053 repaint();
1054 }
1055 getStatusBar().setText(" Label Font Size Changed to " + newFont.getSize());
1056 } catch (NumberFormatException e) {
1057 logger.warning(e.getMessage());
1058 }
1059 }
1060
1061
1062
1063
1064
1065
1066
1067 void setLabelsUpdated() {
1068 repaint();
1069 }
1070
1071
1072
1073
1074
1075
1076 private void setPickingLevel(String level) {
1077 if (level == null) {
1078 return;
1079 }
1080 level = level.toUpperCase();
1081 if (GraphicsPicking.pickLevelHash.containsKey(level)) {
1082 GraphicsPicking.PickLevel pickLevel = GraphicsPicking.pickLevelHash.get(level);
1083 switch (pickLevel) {
1084 case PICKATOM:
1085 case PICKBOND:
1086 case PICKANGLE:
1087 case PICKDIHEDRAL:
1088 case PICKRESIDUE:
1089 case PICKPOLYMER:
1090 case PICKSYSTEM:
1091 rendererPicking.setPickLevel(level);
1092 break;
1093 case MEASUREDISTANCE:
1094 case MEASUREANGLE:
1095 case MEASUREDIHEDRAL:
1096 rendererPicking.setPickLevel(level);
1097 rendererPicking.setPicking(true);
1098 mainPanel.getMainMenu().setPickBehavior(true);
1099 rendererPicking.clear();
1100 rendererPicking.resetCount();
1101 break;
1102 default:
1103 logger.warning("Unexpected PickingLevel");
1104 }
1105 }
1106 }
1107
1108
1109
1110
1111 private void setSelectionColor() {
1112 Color newcolor =
1113 JColorChooser.showDialog(
1114 this,
1115 "Choose Selection Color",
1116 new Color(selectionColor.x, selectionColor.y, selectionColor.z));
1117 if (newcolor != null) {
1118 selectionColor = new Color3f(newcolor.getRGBColorComponents(new float[3]));
1119 }
1120 if (RendererCache.highlightSelections) {
1121 this.updateScene(
1122 mainPanel.getDataRoot(), false, false, null, true, RendererCache.ColorModel.SELECT);
1123 }
1124 }
1125
1126
1127
1128
1129 private void setUserColor() {
1130 Color newcolor =
1131 JColorChooser.showDialog(
1132 this, "Choose User Color", new Color(userColor.x, userColor.y, userColor.z));
1133 if (newcolor != null) {
1134 userColor = new Color3f(newcolor.getRGBColorComponents(new float[3]));
1135 }
1136 }
1137
1138
1139
1140
1141
1142
1143 private void setViewModel(String model) {
1144 if (!RendererCache.viewModelHash.containsKey(model.toUpperCase())) {
1145 return;
1146 }
1147 RendererCache.ViewModel viewModel = RendererCache.viewModelHash.get(model.toUpperCase());
1148 if (viewModel == RendererCache.ViewModel.RESTRICT) {
1149 renderer.arm(mainPanel.getDataRoot(), false, true, viewModel, false, null);
1150 return;
1151 }
1152 ArrayList<MSNode> active = mainPanel.getHierarchy().getActiveNodes();
1153 if (active == null) {
1154 return;
1155 }
1156 renderer.arm(active, false, true, viewModel, false, null);
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169 private void updateSceneWait(
1170 ArrayList<MSNode> n,
1171 boolean t,
1172 boolean v,
1173 ViewModel newViewModel,
1174 boolean c,
1175 ColorModel newColorModel) {
1176 if (n != null) {
1177 renderer.arm(n, t, v, newViewModel, c, newColorModel);
1178 }
1179 while (isSceneRendering() || isCacheFull()) {
1180 synchronized (this) {
1181 try {
1182 wait(1);
1183 } catch (Exception e) {
1184 logger.warning(e.getMessage());
1185 }
1186 }
1187 }
1188 }
1189
1190
1191
1192
1193
1194
1195 private void viewWait(ViewModel viewModel) {
1196 if (viewModel == null) {
1197 logger.info("Null view.");
1198 return;
1199 }
1200 ArrayList<MSNode> nodes = mainPanel.getHierarchy().getActiveNodes();
1201 if (nodes == null) {
1202 logger.info("No active nodes.");
1203 return;
1204 }
1205 updateSceneWait(nodes, false, true, viewModel, false, null);
1206 }
1207
1208
1209
1210
1211
1212
1213 private void colorWait(ColorModel colorModel) {
1214 if (colorModel == null) {
1215 logger.info("Null color.");
1216 return;
1217 }
1218 ArrayList<MSNode> nodes = mainPanel.getHierarchy().getActiveNodes();
1219 if (nodes == null) {
1220 logger.info("No active nodes.");
1221 return;
1222 }
1223 updateSceneWait(nodes, false, false, null, true, colorModel);
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 void updateSceneWait(
1237 MSNode n, boolean t, boolean v, ViewModel newViewModel, boolean c, ColorModel newColorModel) {
1238 if (n != null) {
1239 renderer.arm(n, t, v, newViewModel, c, newColorModel);
1240 }
1241 while (isSceneRendering() || isCacheFull()) {
1242 synchronized (this) {
1243 try {
1244 wait(1);
1245 } catch (Exception e) {
1246 String message = "Exception waiting for a Graphics operation.";
1247 logger.log(Level.WARNING, message, e);
1248 }
1249 }
1250 }
1251 }
1252
1253
1254
1255
1256 private void zoomIn() {
1257 baseTransformGroup.getTransform(baseTransform3D);
1258 double scale = baseTransform3D.getScale() + 0.01;
1259 baseTransform3D.setScale(scale);
1260 baseTransformGroup.setTransform(baseTransform3D);
1261 }
1262
1263
1264
1265
1266 private void zoomOut() {
1267 baseTransformGroup.getTransform(baseTransform3D);
1268 double scale = baseTransform3D.getScale() - 0.01;
1269 if (scale > 0.0) {
1270 baseTransform3D.setScale(scale);
1271 baseTransformGroup.setTransform(baseTransform3D);
1272 }
1273 }
1274
1275
1276
1277
1278 public enum ImageFormat {
1279 BMP,
1280 GIF,
1281 JPEG,
1282 PNG,
1283 WBMP
1284 }
1285
1286
1287
1288
1289 public enum MouseMode {
1290 SYSTEMBELOWMOUSE,
1291 ACTIVESYSTEM
1292 }
1293
1294
1295
1296
1297 public enum LeftButtonMode {
1298 ROTATE,
1299 TRANSLATE,
1300 ZOOM
1301 }
1302 }