Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/applets/MoleculeViewer/XYZApp.java
38827 views
1
/*
2
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
42
import java.applet.Applet;
43
import java.awt.Image;
44
import java.awt.Graphics;
45
import java.awt.Dimension;
46
import java.awt.event.MouseEvent;
47
import java.awt.event.MouseListener;
48
import java.awt.event.MouseMotionListener;
49
import java.net.URL;
50
import java.awt.image.IndexColorModel;
51
import java.awt.image.MemoryImageSource;
52
import java.io.BufferedReader;
53
import java.io.IOException;
54
import java.io.InputStream;
55
import java.io.InputStreamReader;
56
import java.io.StreamTokenizer;
57
import java.util.HashMap;
58
import java.util.Map;
59
import java.util.logging.Level;
60
import java.util.logging.Logger;
61
62
63
/*
64
* A set of classes to parse, represent and display Chemical compounds in
65
* .xyz format (see http://chem.leeds.ac.uk/Project/MIME.html)
66
*/
67
/** The representation of a Chemical .xyz model */
68
final class XYZChemModel {
69
70
float vert[];
71
Atom atoms[];
72
int tvert[];
73
int ZsortMap[];
74
int nvert, maxvert;
75
static final Map<String, Atom> atomTable = new HashMap<String, Atom>();
76
static Atom defaultAtom;
77
78
static {
79
atomTable.put("c", new Atom(0, 0, 0));
80
atomTable.put("h", new Atom(210, 210, 210));
81
atomTable.put("n", new Atom(0, 0, 255));
82
atomTable.put("o", new Atom(255, 0, 0));
83
atomTable.put("p", new Atom(255, 0, 255));
84
atomTable.put("s", new Atom(255, 255, 0));
85
atomTable.put("hn", new Atom(150, 255, 150)); /* !!*/
86
defaultAtom = new Atom(255, 100, 200);
87
}
88
boolean transformed;
89
Matrix3D mat;
90
float xmin, xmax, ymin, ymax, zmin, zmax;
91
92
XYZChemModel() {
93
mat = new Matrix3D();
94
mat.xrot(20);
95
mat.yrot(30);
96
}
97
98
/** Create a Chemical model by parsing an input stream */
99
XYZChemModel(InputStream is) throws Exception {
100
this();
101
StreamTokenizer st = new StreamTokenizer(
102
new BufferedReader(new InputStreamReader(is, "UTF-8")));
103
st.eolIsSignificant(true);
104
st.commentChar('#');
105
106
try {
107
scan:
108
while (true) {
109
switch (st.nextToken()) {
110
case StreamTokenizer.TT_EOF:
111
break scan;
112
default:
113
break;
114
case StreamTokenizer.TT_WORD:
115
String name = st.sval;
116
double x = 0,
117
y = 0,
118
z = 0;
119
if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
120
x = st.nval;
121
if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
122
y = st.nval;
123
if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
124
z = st.nval;
125
}
126
}
127
}
128
addVert(name, (float) x, (float) y, (float) z);
129
while (st.ttype != StreamTokenizer.TT_EOL
130
&& st.ttype != StreamTokenizer.TT_EOF) {
131
st.nextToken();
132
}
133
134
} // end Switch
135
136
} // end while
137
138
is.close();
139
140
} // end Try
141
catch (IOException e) {
142
}
143
144
if (st.ttype != StreamTokenizer.TT_EOF) {
145
throw new Exception(st.toString());
146
}
147
148
} // end XYZChemModel()
149
150
/** Add a vertex to this model */
151
int addVert(String name, float x, float y, float z) {
152
int i = nvert;
153
if (i >= maxvert) {
154
if (vert == null) {
155
maxvert = 100;
156
vert = new float[maxvert * 3];
157
atoms = new Atom[maxvert];
158
} else {
159
maxvert *= 2;
160
float nv[] = new float[maxvert * 3];
161
System.arraycopy(vert, 0, nv, 0, vert.length);
162
vert = nv;
163
Atom na[] = new Atom[maxvert];
164
System.arraycopy(atoms, 0, na, 0, atoms.length);
165
atoms = na;
166
}
167
}
168
Atom a = atomTable.get(name.toLowerCase());
169
if (a == null) {
170
a = defaultAtom;
171
}
172
atoms[i] = a;
173
i *= 3;
174
vert[i] = x;
175
vert[i + 1] = y;
176
vert[i + 2] = z;
177
return nvert++;
178
}
179
180
/** Transform all the points in this model */
181
void transform() {
182
if (transformed || nvert <= 0) {
183
return;
184
}
185
if (tvert == null || tvert.length < nvert * 3) {
186
tvert = new int[nvert * 3];
187
}
188
mat.transform(vert, tvert, nvert);
189
transformed = true;
190
}
191
192
/** Paint this model to a graphics context. It uses the matrix associated
193
with this model to map from model space to screen space.
194
The next version of the browser should have double buffering,
195
which will make this *much* nicer */
196
void paint(Graphics g) {
197
if (vert == null || nvert <= 0) {
198
return;
199
}
200
transform();
201
int v[] = tvert;
202
int zs[] = ZsortMap;
203
if (zs == null) {
204
ZsortMap = zs = new int[nvert];
205
for (int i = nvert; --i >= 0;) {
206
zs[i] = i * 3;
207
}
208
}
209
210
/*
211
* I use a bubble sort since from one iteration to the next, the sort
212
* order is pretty stable, so I just use what I had last time as a
213
* "guess" of the sorted order. With luck, this reduces O(N log N)
214
* to O(N)
215
*/
216
217
for (int i = nvert - 1; --i >= 0;) {
218
boolean flipped = false;
219
for (int j = 0; j <= i; j++) {
220
int a = zs[j];
221
int b = zs[j + 1];
222
if (v[a + 2] > v[b + 2]) {
223
zs[j + 1] = a;
224
zs[j] = b;
225
flipped = true;
226
}
227
}
228
if (!flipped) {
229
break;
230
}
231
}
232
233
int lim = nvert;
234
if (lim <= 0 || nvert <= 0) {
235
return;
236
}
237
for (int i = 0; i < lim; i++) {
238
int j = zs[i];
239
int grey = v[j + 2];
240
if (grey < 0) {
241
grey = 0;
242
}
243
if (grey > 15) {
244
grey = 15;
245
}
246
// g.drawString(names[i], v[j], v[j+1]);
247
atoms[j / 3].paint(g, v[j], v[j + 1], grey);
248
// g.drawImage(iBall, v[j] - (iBall.width >> 1), v[j + 1] -
249
// (iBall.height >> 1));
250
}
251
}
252
253
/** Find the bounding box of this model */
254
void findBB() {
255
if (nvert <= 0) {
256
return;
257
}
258
float v[] = vert;
259
float _xmin = v[0], _xmax = _xmin;
260
float _ymin = v[1], _ymax = _ymin;
261
float _zmin = v[2], _zmax = _zmin;
262
for (int i = nvert * 3; (i -= 3) > 0;) {
263
float x = v[i];
264
if (x < _xmin) {
265
_xmin = x;
266
}
267
if (x > _xmax) {
268
_xmax = x;
269
}
270
float y = v[i + 1];
271
if (y < _ymin) {
272
_ymin = y;
273
}
274
if (y > _ymax) {
275
_ymax = y;
276
}
277
float z = v[i + 2];
278
if (z < _zmin) {
279
_zmin = z;
280
}
281
if (z > _zmax) {
282
_zmax = z;
283
}
284
}
285
this.xmax = _xmax;
286
this.xmin = _xmin;
287
this.ymax = _ymax;
288
this.ymin = _ymin;
289
this.zmax = _zmax;
290
this.zmin = _zmin;
291
}
292
}
293
294
295
/** An applet to put a Chemical model into a page */
296
@SuppressWarnings("serial")
297
public class XYZApp extends Applet implements Runnable, MouseListener,
298
MouseMotionListener {
299
300
XYZChemModel md;
301
boolean painted = true;
302
float xfac;
303
int prevx, prevy;
304
float scalefudge = 1;
305
Matrix3D amat = new Matrix3D(), tmat = new Matrix3D();
306
String mdname = null;
307
String message = null;
308
Image backBuffer;
309
Graphics backGC;
310
Dimension backSize;
311
312
private synchronized void newBackBuffer() {
313
backBuffer = createImage(getSize().width, getSize().height);
314
if (backGC != null) {
315
backGC.dispose();
316
}
317
backGC = backBuffer.getGraphics();
318
backSize = getSize();
319
}
320
321
@Override
322
public void init() {
323
mdname = getParameter("model");
324
try {
325
scalefudge = Float.valueOf(getParameter("scale")).floatValue();
326
} catch (Exception ignored) {
327
}
328
amat.yrot(20);
329
amat.xrot(20);
330
if (mdname == null) {
331
mdname = "model.obj";
332
}
333
resize(getSize().width <= 20 ? 400 : getSize().width,
334
getSize().height <= 20 ? 400 : getSize().height);
335
newBackBuffer();
336
addMouseListener(this);
337
addMouseMotionListener(this);
338
}
339
340
@Override
341
public void destroy() {
342
removeMouseListener(this);
343
removeMouseMotionListener(this);
344
}
345
346
@Override
347
public void run() {
348
InputStream is = null;
349
try {
350
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
351
is = getClass().getResourceAsStream(mdname);
352
XYZChemModel m = new XYZChemModel(is);
353
Atom.setApplet(this);
354
md = m;
355
m.findBB();
356
float xw = m.xmax - m.xmin;
357
float yw = m.ymax - m.ymin;
358
float zw = m.zmax - m.zmin;
359
if (yw > xw) {
360
xw = yw;
361
}
362
if (zw > xw) {
363
xw = zw;
364
}
365
float f1 = getSize().width / xw;
366
float f2 = getSize().height / xw;
367
xfac = 0.7f * (f1 < f2 ? f1 : f2) * scalefudge;
368
} catch (Exception e) {
369
Logger.getLogger(XYZApp.class.getName()).log(Level.SEVERE, null, e);
370
md = null;
371
message = e.toString();
372
}
373
try {
374
if (is != null) {
375
is.close();
376
}
377
} catch (Exception ignored) {
378
}
379
repaint();
380
}
381
382
@Override
383
public void start() {
384
if (md == null && message == null) {
385
new Thread(this).start();
386
}
387
}
388
389
@Override
390
public void stop() {
391
}
392
/* event handling */
393
394
@Override
395
public void mouseClicked(MouseEvent e) {
396
}
397
398
@Override
399
public void mousePressed(MouseEvent e) {
400
prevx = e.getX();
401
prevy = e.getY();
402
e.consume();
403
}
404
405
@Override
406
public void mouseReleased(MouseEvent e) {
407
}
408
409
@Override
410
public void mouseEntered(MouseEvent e) {
411
}
412
413
@Override
414
public void mouseExited(MouseEvent e) {
415
}
416
417
@Override
418
public void mouseDragged(MouseEvent e) {
419
int x = e.getX();
420
int y = e.getY();
421
tmat.unit();
422
float xtheta = (prevy - y) * (360.0f / getSize().width);
423
float ytheta = (x - prevx) * (360.0f / getSize().height);
424
tmat.xrot(xtheta);
425
tmat.yrot(ytheta);
426
amat.mult(tmat);
427
if (painted) {
428
painted = false;
429
repaint();
430
}
431
prevx = x;
432
prevy = y;
433
e.consume();
434
}
435
436
@Override
437
public void mouseMoved(MouseEvent e) {
438
}
439
440
@Override
441
public void update(Graphics g) {
442
if (backBuffer == null) {
443
g.clearRect(0, 0, getSize().width, getSize().height);
444
}
445
paint(g);
446
}
447
448
@Override
449
public void paint(Graphics g) {
450
if (md != null) {
451
md.mat.unit();
452
md.mat.translate(-(md.xmin + md.xmax) / 2,
453
-(md.ymin + md.ymax) / 2,
454
-(md.zmin + md.zmax) / 2);
455
md.mat.mult(amat);
456
// md.mat.scale(xfac, -xfac, 8 * xfac / getSize().width);
457
md.mat.scale(xfac, -xfac, 16 * xfac / getSize().width);
458
md.mat.translate(getSize().width / 2, getSize().height / 2, 8);
459
md.transformed = false;
460
if (backBuffer != null) {
461
if (!backSize.equals(getSize())) {
462
newBackBuffer();
463
}
464
backGC.setColor(getBackground());
465
backGC.fillRect(0, 0, getSize().width, getSize().height);
466
md.paint(backGC);
467
g.drawImage(backBuffer, 0, 0, this);
468
} else {
469
md.paint(g);
470
}
471
setPainted();
472
} else if (message != null) {
473
g.drawString("Error in model:", 3, 20);
474
g.drawString(message, 10, 40);
475
}
476
}
477
478
private synchronized void setPainted() {
479
painted = true;
480
notifyAll();
481
}
482
483
@Override
484
public String getAppletInfo() {
485
return "Title: XYZApp \nAuthor: James Gosling \nAn applet to put"
486
+ " a Chemical model into a page.";
487
}
488
489
@Override
490
public String[][] getParameterInfo() {
491
String[][] info = {
492
{ "model", "path string", "The path to the model to be displayed"
493
+ " in .xyz format "
494
+ "(see http://chem.leeds.ac.uk/Project/MIME.html)."
495
+ " Default is model.obj." },
496
{ "scale", "float", "Scale factor. Default is 1 (i.e. no scale)." }
497
};
498
return info;
499
}
500
} // end class XYZApp
501
502
503
class Atom {
504
505
private static Applet applet;
506
private static byte[] data;
507
private final static int R = 40;
508
private final static int hx = 15;
509
private final static int hy = 15;
510
private final static int bgGrey = 192;
511
private final static int nBalls = 16;
512
private static int maxr;
513
private int Rl;
514
private int Gl;
515
private int Bl;
516
private Image balls[];
517
518
static {
519
data = new byte[R * 2 * R * 2];
520
int mr = 0;
521
for (int Y = 2 * R; --Y >= 0;) {
522
int x0 = (int) (Math.sqrt(R * R - (Y - R) * (Y - R)) + 0.5);
523
int p = Y * (R * 2) + R - x0;
524
for (int X = -x0; X < x0; X++) {
525
int x = X + hx;
526
int y = Y - R + hy;
527
int r = (int) (Math.sqrt(x * x + y * y) + 0.5);
528
if (r > mr) {
529
mr = r;
530
}
531
data[p++] = r <= 0 ? 1 : (byte) r;
532
}
533
}
534
maxr = mr;
535
}
536
537
static void setApplet(Applet app) {
538
applet = app;
539
}
540
541
Atom(int Rl, int Gl, int Bl) {
542
this.Rl = Rl;
543
this.Gl = Gl;
544
this.Bl = Bl;
545
}
546
547
private int blend(int fg, int bg, float fgfactor) {
548
return (int) (bg + (fg - bg) * fgfactor);
549
}
550
551
private void Setup() {
552
balls = new Image[nBalls];
553
byte red[] = new byte[256];
554
red[0] = (byte) bgGrey;
555
byte green[] = new byte[256];
556
green[0] = (byte) bgGrey;
557
byte blue[] = new byte[256];
558
blue[0] = (byte) bgGrey;
559
for (int r = 0; r < nBalls; r++) {
560
float b = (float) (r + 1) / nBalls;
561
for (int i = maxr; i >= 1; --i) {
562
float d = (float) i / maxr;
563
red[i] = (byte) blend(blend(Rl, 255, d), bgGrey, b);
564
green[i] = (byte) blend(blend(Gl, 255, d), bgGrey, b);
565
blue[i] = (byte) blend(blend(Bl, 255, d), bgGrey, b);
566
}
567
IndexColorModel model = new IndexColorModel(8, maxr + 1,
568
red, green, blue, 0);
569
balls[r] = applet.createImage(
570
new MemoryImageSource(R * 2, R * 2, model, data, 0, R * 2));
571
}
572
}
573
574
void paint(Graphics gc, int x, int y, int r) {
575
Image ba[] = balls;
576
if (ba == null) {
577
Setup();
578
ba = balls;
579
}
580
Image i = ba[r];
581
int size = 10 + r;
582
gc.drawImage(i, x - (size >> 1), y - (size >> 1), size, size, applet);
583
}
584
}
585
586