Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
AppJmol | 60 | 196 | 63 | ||
AppJmol.RenderPanel | 601 | 26 | 10 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package jalview.gui; | |
22 | ||
23 | import java.awt.BorderLayout; | |
24 | import java.awt.Color; | |
25 | import java.awt.Dimension; | |
26 | import java.awt.Font; | |
27 | import java.awt.Graphics; | |
28 | import java.awt.Graphics2D; | |
29 | import java.awt.RenderingHints; | |
30 | import java.io.File; | |
31 | import java.util.List; | |
32 | import java.util.Locale; | |
33 | import java.util.Map; | |
34 | import java.util.concurrent.Executors; | |
35 | ||
36 | import javax.swing.JPanel; | |
37 | import javax.swing.JSplitPane; | |
38 | import javax.swing.SwingUtilities; | |
39 | import javax.swing.event.InternalFrameAdapter; | |
40 | import javax.swing.event.InternalFrameEvent; | |
41 | ||
42 | import jalview.api.AlignmentViewPanel; | |
43 | import jalview.bin.Console; | |
44 | import jalview.datamodel.PDBEntry; | |
45 | import jalview.datamodel.SequenceI; | |
46 | import jalview.datamodel.StructureViewerModel; | |
47 | import jalview.datamodel.StructureViewerModel.StructureData; | |
48 | import jalview.gui.ImageExporter.ImageWriterI; | |
49 | import jalview.gui.StructureViewer.ViewerType; | |
50 | import jalview.io.exceptions.ImageOutputException; | |
51 | import jalview.structure.StructureCommand; | |
52 | import jalview.structures.models.AAStructureBindingModel; | |
53 | import jalview.util.BrowserLauncher; | |
54 | import jalview.util.ImageMaker; | |
55 | import jalview.util.ImageMaker.TYPE; | |
56 | import jalview.util.MessageManager; | |
57 | import jalview.util.Platform; | |
58 | import jalview.util.imagemaker.BitmapImageSizing; | |
59 | ||
60 | public class AppJmol extends StructureViewerBase | |
61 | { | |
62 | // ms to wait for Jmol to load files | |
63 | private static final int JMOL_LOAD_TIMEOUT = 20000; | |
64 | ||
65 | private static final String SPACE = " "; | |
66 | ||
67 | private static final String QUOTE = "\""; | |
68 | ||
69 | AppJmolBinding jmb; | |
70 | ||
71 | JPanel scriptWindow; | |
72 | ||
73 | JSplitPane splitPane; | |
74 | ||
75 | RenderPanel renderPanel; | |
76 | ||
77 | /** | |
78 | * | |
79 | * @param files | |
80 | * @param ids | |
81 | * @param seqs | |
82 | * @param ap | |
83 | * @param usetoColour | |
84 | * - add the alignment panel to the list used for colouring these | |
85 | * structures | |
86 | * @param useToAlign | |
87 | * - add the alignment panel to the list used for aligning these | |
88 | * structures | |
89 | * @param leaveColouringToJmol | |
90 | * - do not update the colours from any other source. Jmol is | |
91 | * handling them | |
92 | * @param loadStatus | |
93 | * @param bounds | |
94 | * @param viewid | |
95 | */ | |
96 | 7 | public AppJmol(StructureViewerModel viewerModel, AlignmentPanel ap, |
97 | String sessionFile, String viewid) | |
98 | { | |
99 | 7 | Map<File, StructureData> pdbData = viewerModel.getFileData(); |
100 | 7 | PDBEntry[] pdbentrys = new PDBEntry[pdbData.size()]; |
101 | 7 | SequenceI[][] seqs = new SequenceI[pdbData.size()][]; |
102 | 7 | int i = 0; |
103 | 7 | for (StructureData data : pdbData.values()) |
104 | { | |
105 | 7 | PDBEntry pdbentry = new PDBEntry(data.getPdbId(), null, |
106 | PDBEntry.Type.PDB, data.getFilePath()); | |
107 | 7 | pdbentrys[i] = pdbentry; |
108 | 7 | List<SequenceI> sequencesForPdb = data.getSeqList(); |
109 | 7 | seqs[i] = sequencesForPdb |
110 | .toArray(new SequenceI[sequencesForPdb.size()]); | |
111 | 7 | i++; |
112 | } | |
113 | ||
114 | // TODO: check if protocol is needed to be set, and if chains are | |
115 | // autodiscovered. | |
116 | 7 | jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(), |
117 | pdbentrys, seqs, null); | |
118 | ||
119 | 7 | jmb.setLoadingFromArchive(true); |
120 | 7 | addAlignmentPanel(ap); |
121 | 7 | if (viewerModel.isAlignWithPanel()) |
122 | { | |
123 | 0 | useAlignmentPanelForSuperposition(ap); |
124 | } | |
125 | 7 | initMenus(); |
126 | 7 | boolean useToColour = viewerModel.isColourWithAlignPanel(); |
127 | 7 | boolean leaveColouringToJmol = viewerModel.isColourByViewer(); |
128 | 7 | if (leaveColouringToJmol || !useToColour) |
129 | { | |
130 | 7 | jmb.setColourBySequence(false); |
131 | 7 | seqColour.setSelected(false); |
132 | 7 | viewerColour.setSelected(true); |
133 | } | |
134 | 0 | else if (useToColour) |
135 | { | |
136 | 0 | useAlignmentPanelForColourbyseq(ap); |
137 | 0 | jmb.setColourBySequence(true); |
138 | 0 | seqColour.setSelected(true); |
139 | 0 | viewerColour.setSelected(false); |
140 | } | |
141 | ||
142 | 7 | this.setBounds(viewerModel.getX(), viewerModel.getY(), |
143 | viewerModel.getWidth(), viewerModel.getHeight()); | |
144 | 7 | setViewId(viewid); |
145 | ||
146 | 7 | this.addInternalFrameListener(new InternalFrameAdapter() |
147 | { | |
148 | 7 | @Override |
149 | public void internalFrameClosing( | |
150 | InternalFrameEvent internalFrameEvent) | |
151 | { | |
152 | 7 | closeViewer(false); |
153 | } | |
154 | }); | |
155 | 7 | StringBuilder cmd = new StringBuilder(); |
156 | 7 | cmd.append("load FILES ").append(QUOTE) |
157 | .append(Platform.escapeBackslashes(sessionFile)).append(QUOTE); | |
158 | 7 | initJmol(cmd.toString()); |
159 | } | |
160 | ||
161 | 45 | @Override |
162 | protected void initMenus() | |
163 | { | |
164 | 45 | super.initMenus(); |
165 | ||
166 | 45 | viewerColour |
167 | .setText(MessageManager.getString("label.colour_with_jmol")); | |
168 | 45 | viewerColour.setToolTipText(MessageManager |
169 | .getString("label.let_jmol_manage_structure_colours")); | |
170 | } | |
171 | ||
172 | /** | |
173 | * display a single PDB structure in a new Jmol view | |
174 | * | |
175 | * @param pdbentry | |
176 | * @param seq | |
177 | * @param chains | |
178 | * @param ap | |
179 | */ | |
180 | 38 | public AppJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains, |
181 | final AlignmentPanel ap) | |
182 | { | |
183 | 38 | setProgressIndicator(ap.alignFrame); |
184 | ||
185 | 38 | openNewJmol(ap, alignAddedStructures, new PDBEntry[] { pdbentry }, |
186 | new SequenceI[][] | |
187 | { seq }); | |
188 | } | |
189 | ||
190 | 38 | private void openNewJmol(AlignmentPanel ap, boolean alignAdded, |
191 | PDBEntry[] pdbentrys, SequenceI[][] seqs) | |
192 | { | |
193 | 38 | setProgressIndicator(ap.alignFrame); |
194 | 38 | jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(), |
195 | pdbentrys, seqs, null); | |
196 | 38 | addAlignmentPanel(ap); |
197 | 38 | useAlignmentPanelForColourbyseq(ap); |
198 | ||
199 | 38 | alignAddedStructures = alignAdded; |
200 | 38 | if (pdbentrys.length > 1) |
201 | { | |
202 | 0 | useAlignmentPanelForSuperposition(ap); |
203 | } | |
204 | ||
205 | 38 | jmb.setColourBySequence(true); |
206 | 38 | setSize(400, 400); // probably should be a configurable/dynamic default here |
207 | 38 | initMenus(); |
208 | 38 | addingStructures = false; |
209 | 38 | worker = new Thread(this); |
210 | 38 | worker.start(); |
211 | ||
212 | 38 | this.addInternalFrameListener(new InternalFrameAdapter() |
213 | { | |
214 | 14 | @Override |
215 | public void internalFrameClosing( | |
216 | InternalFrameEvent internalFrameEvent) | |
217 | { | |
218 | 14 | closeViewer(false); |
219 | } | |
220 | }); | |
221 | ||
222 | } | |
223 | ||
224 | /** | |
225 | * create a new Jmol containing several structures optionally superimposed | |
226 | * using the given alignPanel. | |
227 | * | |
228 | * @param ap | |
229 | * @param alignAdded | |
230 | * - true to superimpose | |
231 | * @param pe | |
232 | * @param seqs | |
233 | */ | |
234 | 0 | public AppJmol(AlignmentPanel ap, boolean alignAdded, PDBEntry[] pe, |
235 | SequenceI[][] seqs) | |
236 | { | |
237 | 0 | openNewJmol(ap, alignAdded, pe, seqs); |
238 | } | |
239 | ||
240 | 45 | void initJmol(String command) |
241 | { | |
242 | 45 | jmb.setFinishedInit(false); |
243 | 45 | renderPanel = new RenderPanel(); |
244 | // TODO: consider waiting until the structure/view is fully loaded before | |
245 | // displaying | |
246 | 45 | this.getContentPane().add(renderPanel, java.awt.BorderLayout.CENTER); |
247 | 45 | jalview.gui.Desktop.addInternalFrame(this, jmb.getViewerTitle(), |
248 | getBounds().width, getBounds().height); | |
249 | 45 | if (scriptWindow == null) |
250 | { | |
251 | 45 | BorderLayout bl = new BorderLayout(); |
252 | 45 | bl.setHgap(0); |
253 | 45 | bl.setVgap(0); |
254 | 45 | scriptWindow = new JPanel(bl); |
255 | 45 | scriptWindow.setVisible(false); |
256 | } | |
257 | ||
258 | 45 | jmb.allocateViewer(renderPanel, true, "", null, null, "", scriptWindow, |
259 | null); | |
260 | // jmb.newJmolPopup("Jmol"); | |
261 | 45 | if (command == null) |
262 | { | |
263 | 0 | command = ""; |
264 | } | |
265 | 45 | jmb.executeCommand(new StructureCommand(command), false); |
266 | 45 | jmb.executeCommand(new StructureCommand("set hoverDelay=0.1"), false); |
267 | 45 | jmb.executeCommand(new StructureCommand("set antialiasdisplay on"), |
268 | false); | |
269 | 45 | jmb.setFinishedInit(true); |
270 | } | |
271 | ||
272 | 39 | @Override |
273 | public void run() | |
274 | { | |
275 | 39 | _started = true; |
276 | 39 | try |
277 | { | |
278 | 39 | List<String> files = jmb.fetchPdbFiles(this); |
279 | 39 | if (files.size() > 0) |
280 | { | |
281 | 39 | showFilesInViewer(files); |
282 | } | |
283 | } finally | |
284 | { | |
285 | 39 | _started = false; |
286 | 39 | worker = null; |
287 | } | |
288 | } | |
289 | ||
290 | /** | |
291 | * Either adds the given files to a structure viewer or opens a new viewer to | |
292 | * show them | |
293 | * | |
294 | * @param files | |
295 | * list of absolute paths to structure files | |
296 | */ | |
297 | 39 | void showFilesInViewer(List<String> files) |
298 | { | |
299 | 39 | long lastnotify = jmb.getLoadNotifiesHandled(); |
300 | 39 | StringBuilder fileList = new StringBuilder(); |
301 | 39 | for (String s : files) |
302 | { | |
303 | 39 | fileList.append(SPACE).append(QUOTE) |
304 | .append(Platform.escapeBackslashes(s)).append(QUOTE); | |
305 | } | |
306 | 39 | String filesString = fileList.toString(); |
307 | ||
308 | 39 | if (!addingStructures) |
309 | { | |
310 | 38 | try |
311 | { | |
312 | 38 | initJmol("load FILES " + filesString); |
313 | } catch (OutOfMemoryError oomerror) | |
314 | { | |
315 | 0 | new OOMWarning("When trying to open the Jmol viewer!", oomerror); |
316 | 0 | Console.debug("File locations are " + filesString); |
317 | } catch (Exception ex) | |
318 | { | |
319 | 0 | Console.error("Couldn't open Jmol viewer!", ex); |
320 | 0 | ex.printStackTrace(); |
321 | 0 | return; |
322 | } | |
323 | } | |
324 | else | |
325 | { | |
326 | 1 | StringBuilder cmd = new StringBuilder(); |
327 | 1 | cmd.append("loadingJalviewdata=true\nload APPEND "); |
328 | 1 | cmd.append(filesString); |
329 | 1 | cmd.append("\nloadingJalviewdata=null"); |
330 | 1 | final StructureCommand command = new StructureCommand(cmd.toString()); |
331 | 1 | lastnotify = jmb.getLoadNotifiesHandled(); |
332 | ||
333 | 1 | try |
334 | { | |
335 | 1 | jmb.executeCommand(command, false); |
336 | } catch (OutOfMemoryError oomerror) | |
337 | { | |
338 | 0 | new OOMWarning("When trying to add structures to the Jmol viewer!", |
339 | oomerror); | |
340 | 0 | Console.debug("File locations are " + filesString); |
341 | 0 | return; |
342 | } catch (Exception ex) | |
343 | { | |
344 | 0 | Console.error("Couldn't add files to Jmol viewer!", ex); |
345 | 0 | ex.printStackTrace(); |
346 | 0 | return; |
347 | } | |
348 | } | |
349 | ||
350 | // need to wait around until script has finished | |
351 | 39 | int waitMax = JMOL_LOAD_TIMEOUT; |
352 | 39 | int waitFor = 35; |
353 | 39 | int waitTotal = 0; |
354 | 129 | while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled() |
355 | : !(jmb.isFinishedInit() && jmb.getStructureFiles() != null | |
356 | && jmb.getStructureFiles().length == files.size())) | |
357 | { | |
358 | 90 | try |
359 | { | |
360 | 90 | Console.debug("Waiting around for jmb notify."); |
361 | 90 | waitTotal += waitFor; |
362 | ||
363 | // Thread.sleep() throws an exception in JS | |
364 | 90 | Thread.sleep(waitFor); |
365 | } catch (Exception e) | |
366 | { | |
367 | } | |
368 | 90 | if (waitTotal > waitMax) |
369 | { | |
370 | 0 | jalview.bin.Console.errPrintln( |
371 | "Timed out waiting for Jmol to load files after " | |
372 | + waitTotal + "ms"); | |
373 | // jalview.bin.Console.errPrintln("finished: " + jmb.isFinishedInit() | |
374 | // + "; loaded: " + Arrays.toString(jmb.getPdbFile()) | |
375 | // + "; files: " + files.toString()); | |
376 | 0 | jmb.getStructureFiles(); |
377 | 0 | break; |
378 | } | |
379 | } | |
380 | ||
381 | // refresh the sequence colours for the new structure(s) | |
382 | 39 | for (AlignmentViewPanel ap : _colourwith) |
383 | { | |
384 | 39 | jmb.updateColours(ap); |
385 | } | |
386 | // do superposition if asked to | |
387 | 36 | if (alignAddedStructures) |
388 | { | |
389 | 1 | alignAddedStructures(); |
390 | } | |
391 | 36 | addingStructures = false; |
392 | } | |
393 | ||
394 | /** | |
395 | * Queues a thread to align structures with Jalview alignments | |
396 | */ | |
397 | 1 | void alignAddedStructures() |
398 | { | |
399 | 1 | javax.swing.SwingUtilities.invokeLater(new Runnable() |
400 | { | |
401 | 1 | @Override |
402 | public void run() | |
403 | { | |
404 | 1 | if (jmb.jmolViewer.isScriptExecuting()) |
405 | { | |
406 | 0 | SwingUtilities.invokeLater(this); |
407 | 0 | try |
408 | { | |
409 | 0 | Thread.sleep(5); |
410 | } catch (InterruptedException q) | |
411 | { | |
412 | } | |
413 | 0 | return; |
414 | } | |
415 | else | |
416 | { | |
417 | 1 | alignStructsWithAllAlignPanels(); |
418 | } | |
419 | } | |
420 | }); | |
421 | ||
422 | } | |
423 | ||
424 | 0 | public boolean isRepainting() |
425 | { | |
426 | 0 | if (renderPanel != null && renderPanel.isVisible()) |
427 | { | |
428 | 0 | return renderPanel.repainting; |
429 | } | |
430 | 0 | return false; |
431 | } | |
432 | ||
433 | /** | |
434 | * Outputs the Jmol viewer image as an image file, after prompting the user to | |
435 | * choose a file and (for EPS) choice of Text or Lineart character rendering | |
436 | * (unless a preference for this is set) | |
437 | * | |
438 | * @param type | |
439 | */ | |
440 | 0 | @Override |
441 | public void makePDBImage(ImageMaker.TYPE type) | |
442 | { | |
443 | 0 | while (!isRepainting()) |
444 | { | |
445 | 0 | try |
446 | { | |
447 | 0 | Thread.sleep(2); |
448 | } catch (Exception q) | |
449 | { | |
450 | } | |
451 | } | |
452 | 0 | try |
453 | { | |
454 | 0 | makePDBImage(null, type, null, |
455 | BitmapImageSizing.defaultBitmapImageSizing()); | |
456 | } catch (ImageOutputException ioex) | |
457 | { | |
458 | 0 | Console.error("Unexpected error whilst writing " + type.toString(), |
459 | ioex); | |
460 | } | |
461 | } | |
462 | ||
463 | 10 | public void makePDBImage(File file, ImageMaker.TYPE type, String renderer, |
464 | BitmapImageSizing userBis) throws ImageOutputException | |
465 | { | |
466 | 10 | int width = getWidth(); |
467 | 10 | int height = getHeight(); |
468 | ||
469 | 10 | BitmapImageSizing bis = ImageMaker.getScaleWidthHeight(width, height, |
470 | userBis); | |
471 | 10 | float usescale = bis.scale(); |
472 | 10 | int usewidth = bis.width(); |
473 | 10 | int useheight = bis.height(); |
474 | ||
475 | 10 | ImageWriterI writer = new ImageWriterI() |
476 | { | |
477 | 10 | @Override |
478 | public void exportImage(Graphics g) throws Exception | |
479 | { | |
480 | 10 | Graphics2D ig2 = (Graphics2D) g; |
481 | 10 | ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, |
482 | RenderingHints.VALUE_ANTIALIAS_ON); | |
483 | 10 | if (type == TYPE.PNG && usescale > 0.0f) |
484 | { | |
485 | // for a scaled image, this scales down a bigger image to give the | |
486 | // right resolution | |
487 | 4 | if (usescale > 0.0f) |
488 | { | |
489 | 4 | ig2.scale(1 / usescale, 1 / usescale); |
490 | } | |
491 | } | |
492 | ||
493 | 10 | jmb.jmolViewer.requestRepaintAndWait("image export"); |
494 | 10 | jmb.jmolViewer.renderScreenImage(ig2, usewidth, useheight); |
495 | } | |
496 | }; | |
497 | 10 | String view = MessageManager.getString("action.view") |
498 | .toLowerCase(Locale.ROOT); | |
499 | 10 | final ImageExporter exporter = new ImageExporter(writer, |
500 | getProgressIndicator(), type, getTitle()); | |
501 | ||
502 | 10 | final Throwable[] exceptions = new Throwable[1]; |
503 | 10 | exceptions[0] = null; |
504 | 10 | final AppJmol us = this; |
505 | 10 | try |
506 | { | |
507 | 10 | Thread runner = Executors.defaultThreadFactory() |
508 | .newThread(new Runnable() | |
509 | { | |
510 | 10 | @Override |
511 | public void run() | |
512 | { | |
513 | 10 | try |
514 | { | |
515 | 10 | exporter.doExport(file, us, width, height, view, |
516 | renderer, userBis); | |
517 | } catch (Throwable t) | |
518 | { | |
519 | 0 | exceptions[0] = t; |
520 | } | |
521 | } | |
522 | }); | |
523 | 10 | runner.start(); |
524 | 10 | long time = 0; |
525 | 10 | do |
526 | { | |
527 | 414 | Thread.sleep(25); |
528 | 414 | } while (runner.isAlive() && time++ < 4000); |
529 | 10 | if (time >= 4000) |
530 | { | |
531 | 0 | runner.interrupt(); |
532 | 0 | throw new ImageOutputException( |
533 | "Jmol took too long to export. Waited for 100 seconds."); | |
534 | } | |
535 | } catch (Throwable e) | |
536 | { | |
537 | 0 | throw new ImageOutputException( |
538 | "Unexpected error when generating image", e); | |
539 | } | |
540 | 10 | if (exceptions[0] != null) |
541 | { | |
542 | 0 | if (exceptions[0] instanceof ImageOutputException) |
543 | { | |
544 | 0 | throw ((ImageOutputException) exceptions[0]); |
545 | } | |
546 | else | |
547 | { | |
548 | 0 | throw new ImageOutputException( |
549 | "Unexpected error when generating image", exceptions[0]); | |
550 | } | |
551 | } | |
552 | } | |
553 | ||
554 | 0 | @Override |
555 | public void showHelp_actionPerformed() | |
556 | { | |
557 | 0 | try |
558 | { | |
559 | 0 | BrowserLauncher // BH 2018 |
560 | .openURL("http://wiki.jmol.org");// http://jmol.sourceforge.net/docs/JmolUserGuide/"); | |
561 | } catch (Exception ex) | |
562 | { | |
563 | 0 | jalview.bin.Console |
564 | .errPrintln("Show Jmol help failed with: " + ex.getMessage()); | |
565 | } | |
566 | } | |
567 | ||
568 | 0 | @Override |
569 | public void showConsole(boolean showConsole) | |
570 | { | |
571 | 0 | if (showConsole) |
572 | { | |
573 | 0 | if (splitPane == null) |
574 | { | |
575 | 0 | splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); |
576 | 0 | splitPane.setTopComponent(renderPanel); |
577 | 0 | splitPane.setBottomComponent(scriptWindow); |
578 | 0 | this.getContentPane().add(splitPane, BorderLayout.CENTER); |
579 | 0 | splitPane.setDividerLocation(getHeight() - 200); |
580 | 0 | scriptWindow.setVisible(true); |
581 | 0 | scriptWindow.validate(); |
582 | 0 | splitPane.validate(); |
583 | } | |
584 | ||
585 | } | |
586 | else | |
587 | { | |
588 | 0 | if (splitPane != null) |
589 | { | |
590 | 0 | splitPane.setVisible(false); |
591 | } | |
592 | ||
593 | 0 | splitPane = null; |
594 | ||
595 | 0 | this.getContentPane().add(renderPanel, BorderLayout.CENTER); |
596 | } | |
597 | ||
598 | 0 | validate(); |
599 | } | |
600 | ||
601 | class RenderPanel extends JPanel | |
602 | { | |
603 | final Dimension currentSize = new Dimension(); | |
604 | ||
605 | 325 | @Override |
606 | public void paintComponent(Graphics g) | |
607 | { | |
608 | 325 | getSize(currentSize); |
609 | ||
610 | 325 | if (jmb != null && jmb.hasFileLoadingError()) |
611 | { | |
612 | 0 | g.setColor(Color.black); |
613 | 0 | g.fillRect(0, 0, currentSize.width, currentSize.height); |
614 | 0 | g.setColor(Color.white); |
615 | 0 | g.setFont(new Font("Verdana", Font.BOLD, 14)); |
616 | 0 | g.drawString(MessageManager.getString("label.error_loading_file") |
617 | + "...", 20, currentSize.height / 2); | |
618 | 0 | StringBuffer sb = new StringBuffer(); |
619 | 0 | int lines = 0; |
620 | 0 | for (int e = 0; e < jmb.getPdbCount(); e++) |
621 | { | |
622 | 0 | sb.append(jmb.getPdbEntry(e).getId()); |
623 | 0 | if (e < jmb.getPdbCount() - 1) |
624 | { | |
625 | 0 | sb.append(","); |
626 | } | |
627 | ||
628 | 0 | if (e == jmb.getPdbCount() - 1 || sb.length() > 20) |
629 | { | |
630 | 0 | lines++; |
631 | 0 | g.drawString(sb.toString(), 20, currentSize.height / 2 |
632 | - lines * g.getFontMetrics().getHeight()); | |
633 | } | |
634 | } | |
635 | } | |
636 | 325 | else if (jmb == null || jmb.jmolViewer == null |
637 | || !jmb.isFinishedInit()) | |
638 | { | |
639 | 24 | g.setColor(Color.black); |
640 | 24 | g.fillRect(0, 0, currentSize.width, currentSize.height); |
641 | 24 | g.setColor(Color.white); |
642 | 24 | g.setFont(new Font("Verdana", Font.BOLD, 14)); |
643 | 24 | g.drawString(MessageManager.getString("label.retrieving_pdb_data"), |
644 | 20, currentSize.height / 2); | |
645 | } | |
646 | else | |
647 | { | |
648 | 301 | repainting = true; |
649 | 301 | synchronized (jmb) |
650 | { | |
651 | 301 | jmb.jmolViewer.renderScreenImage(g, currentSize.width, |
652 | currentSize.height); | |
653 | ||
654 | } | |
655 | 301 | repainting = false; |
656 | } | |
657 | } | |
658 | ||
659 | volatile boolean repainting = false; | |
660 | } | |
661 | ||
662 | 1654 | @Override |
663 | public AAStructureBindingModel getBinding() | |
664 | { | |
665 | 1654 | return this.jmb; |
666 | } | |
667 | ||
668 | 68 | @Override |
669 | public ViewerType getViewerType() | |
670 | { | |
671 | 68 | return ViewerType.JMOL; |
672 | } | |
673 | ||
674 | 139 | @Override |
675 | protected String getViewerName() | |
676 | { | |
677 | 139 | return "Jmol"; |
678 | } | |
679 | } |