You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
13 KiB

  1. package verteiltesysteme.mandelbrot.rmi;
  2. import java.awt.BorderLayout;
  3. //Mandelbot Example A. Gepperth
  4. import java.awt.Color;
  5. import java.awt.Graphics;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.MouseEvent;
  9. import java.awt.event.MouseListener;
  10. import java.awt.event.MouseMotionListener;
  11. import java.awt.image.BufferedImage;
  12. import java.rmi.NotBoundException;
  13. import java.rmi.RemoteException;
  14. import java.rmi.registry.LocateRegistry;
  15. import java.rmi.registry.Registry;
  16. import javax.swing.ImageIcon;
  17. import javax.swing.JButton;
  18. import javax.swing.JFrame;
  19. import javax.swing.JLabel;
  20. import javax.swing.JPanel;
  21. import javax.swing.JSlider;
  22. import javax.swing.JTextField;
  23. import javax.swing.border.BevelBorder;
  24. import javax.swing.event.ChangeEvent;
  25. import javax.swing.event.ChangeListener;
  26. class MyJLabel extends JLabel {
  27. /**
  28. *
  29. */
  30. private static final long serialVersionUID = -7750935382747799343L;
  31. int boxULx, boxULy, boxW, boxH;
  32. MyJLabel() {
  33. super();
  34. }
  35. MyJLabel(String s) {
  36. super(s);
  37. }
  38. void setBox(int boxULx, int boxULy, int boxW, int boxH) {
  39. this.boxULx = boxULx;
  40. this.boxULy = boxULy;
  41. this.boxW = boxW;
  42. this.boxH = boxH;
  43. }
  44. @Override
  45. protected void paintComponent(Graphics g) {
  46. super.paintComponent(g);
  47. g.setColor(Color.black);
  48. g.drawRect(this.boxULx, this.boxULy, this.boxW, this.boxH);
  49. }
  50. }
  51. class RMIMandelbrotCalculationThread extends Thread {
  52. MyJLabel view;
  53. RMIMandelbrotCalculationsInterface remoteCalcObj;
  54. int boxULx, boxULy, boxW, boxH;
  55. public static int RESX = 600;
  56. public static int RESY = 600;
  57. Boolean upperPart;
  58. int maxIterations;
  59. RMIMandelbrotCalculationThread(Boolean upperPart, MyJLabel view, RMIMandelbrotCalculationsInterface remoteCalcObj, int maxIterations) {
  60. this.view = view;
  61. this.remoteCalcObj = remoteCalcObj;
  62. this.upperPart = upperPart;
  63. this.maxIterations = maxIterations;
  64. }
  65. // visualization related stuff, do not touch!
  66. int[] generateLookupTable(int nrHues) {
  67. int[] tmp = new int[nrHues + 1];
  68. int cycle = 2048;
  69. for (int i = 0; i < nrHues; i++) {
  70. float hue = 1 * ((float) (i % cycle)) / cycle/* ((float)nrHues) */ ;
  71. tmp[i] = Color.HSBtoRGB(hue, 0.8f, 1.0f);
  72. }
  73. tmp[0] = Color.HSBtoRGB(0f, 1.0f, 0.0f);
  74. return tmp;
  75. }
  76. public void run() {
  77. try {
  78. long timestampStart = System.currentTimeMillis();
  79. double ULx = this.remoteCalcObj.getULx();
  80. double ULy = this.remoteCalcObj.getULy();
  81. double LRx = this.remoteCalcObj.getLRx();
  82. double LRy = this.remoteCalcObj.getLRy();
  83. System.out.println("actual="+ULx + "/" + ULy + "/" + LRx + "/" + LRy);
  84. double w = LRx - ULx;
  85. double h = LRy - ULy;
  86. // AG change define box such that it contains only upper half of apple man :-)
  87. if (this.upperPart == true)
  88. {
  89. boxULx = 0 ; boxULy = 0; boxW = MGuiRMI.RESX ; boxH = MGuiRMI.RESY/2;
  90. }
  91. else
  92. {
  93. // for lower half:
  94. boxULx = 0 ; boxULy = RESY/2; boxW = RESX ; boxH = RESY/2;
  95. }
  96. ULx = ULx + w * this.boxULx / (double) MGuiRMI.RESX;
  97. ULy = ULy + h * this.boxULy / (double) MGuiRMI.RESY;
  98. w *= this.boxW / (double) (RESX);
  99. h *= this.boxH / (double) (RESY);
  100. LRx = ULx + w;
  101. LRy = ULy + h;
  102. System.out.println("computed="+ULx + "/" + ULy + "/" + LRx + "/" + LRy);
  103. this.boxULx = 0;
  104. this.boxULy = 0;
  105. this.boxW = MGuiRMI.RESX;
  106. this.boxH = MGuiRMI.RESY;
  107. this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
  108. // end alex
  109. int[] colors = null;
  110. this.remoteCalcObj.iterateAllPoints(this.maxIterations * 1000, MGuiRMI.RESX, MGuiRMI.RESY/2);
  111. /*
  112. int[] lookupTable = generateLookupTable(this.maxIterations.getValue() * 1000);
  113. colors = new int[MGuiRMI.RESX * MGuiRMI.RESY];
  114. MGuiRMI.applyLookupTable(remoteCalcObj.getResult(), colors, lookupTable);
  115. BufferedImage colorImage = new BufferedImage(MGuiRMI.RESX, MGuiRMI.RESY, BufferedImage.TYPE_INT_ARGB);
  116. colorImage.setRGB(0, 0, MGuiRMI.RESX, MGuiRMI.RESY, colors, 0, MGuiRMI.RESX);
  117. this.view.setIcon(new ImageIcon(colorImage));
  118. this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
  119. this.view.repaint();
  120. long timestampEnd = System.currentTimeMillis();
  121. String timeElapsed = "Dauer: " + ((timestampEnd - timestampStart) / 1000.0) + " sec";
  122. System.out.println(timeElapsed);
  123. this.message.setText(timeElapsed);
  124. * */
  125. int[] lookupTable = generateLookupTable(this.maxIterations * 1000);
  126. colors = new int[MGuiRMI.RESX * MGuiRMI.RESY/2];
  127. MGuiRMI.applyLookupTable(remoteCalcObj.getResult(), colors, lookupTable);
  128. BufferedImage colorImage = new BufferedImage(MGuiRMI.RESX, MGuiRMI.RESY/2, BufferedImage.TYPE_INT_ARGB);
  129. colorImage.setRGB(0, 0, MGuiRMI.RESX, MGuiRMI.RESY/2, colors, 0, MGuiRMI.RESX);
  130. this.view.setIcon(new ImageIcon(colorImage));
  131. long timestampEnd = System.currentTimeMillis();
  132. String timeElapsed = "Zeit: " + ((timestampEnd - timestampStart) / 1000.0) + " sec";
  133. System.out.println(timeElapsed);
  134. //this.view.setText(timeElapsed);
  135. } catch (RemoteException e) {
  136. // TODO Auto-generated catch block
  137. e.printStackTrace();
  138. }
  139. }
  140. }
  141. public class MGuiRMI implements ActionListener, ChangeListener, MouseListener, MouseMotionListener {
  142. // GUI elements
  143. JFrame frame;
  144. JPanel panel;
  145. JButton endButton;
  146. JButton backButton;
  147. JButton calcButton;
  148. JTextField hostTextField;
  149. JSlider maxIterations;
  150. MyJLabel viewUpper;
  151. MyJLabel viewLower;
  152. JLabel message;
  153. int nrIterations;
  154. // box management
  155. int boxULx, boxULy, boxW, boxH;
  156. boolean dragging = false;
  157. // this one does all the calculating work
  158. RMIMandelbrotCalculationsInterface remoteCalcObj;
  159. RMIMandelbrotCalculationsInterface remoteCalcObj2;
  160. // how many points in the image?
  161. // change if you want a higher resolution
  162. public static int RESX = 600;
  163. public static int RESY = 600;
  164. MGuiRMI() {
  165. // set up GUI
  166. this.frame = new JFrame("Mandelbrotmenge");
  167. this.panel = new JPanel();
  168. this.endButton = new JButton("Ende");
  169. this.panel.add(this.endButton);
  170. this.backButton = new JButton("Zur�ck");
  171. this.panel.add(this.backButton);
  172. this.calcButton = new JButton("Rechnen");
  173. this.hostTextField = new JTextField(20);
  174. this.hostTextField.setText("localhost");
  175. this.panel.add(this.calcButton);
  176. this.panel.add(this.hostTextField);
  177. this.frame.add(this.panel);
  178. this.frame.setSize(700, 720);
  179. this.frame.setVisible(true);
  180. this.viewUpper = new MyJLabel();
  181. this.viewLower = new MyJLabel();
  182. this.maxIterations = new JSlider(0, 50, 30);
  183. this.panel.add(this.maxIterations);
  184. this.panel.add(this.viewUpper);
  185. this.panel.add(this.viewLower);
  186. this.message = new JLabel("Status");
  187. this.message.setBorder(new BevelBorder(BevelBorder.LOWERED));
  188. this.frame.add(this.message,BorderLayout.SOUTH);
  189. this.endButton.addActionListener(this);
  190. this.backButton.addActionListener(this);
  191. this.calcButton.addActionListener(this);
  192. this.maxIterations.addChangeListener(this);
  193. this.maxIterations.setMajorTickSpacing(10);
  194. this.maxIterations.setPaintTicks(true);
  195. this.maxIterations.setPaintLabels(true);
  196. this.viewUpper.addMouseListener(this);
  197. this.viewUpper.addMouseMotionListener(this);
  198. this.viewLower.addMouseListener(this);
  199. this.viewLower.addMouseMotionListener(this);
  200. this.boxULx = 0;
  201. this.boxULy = 0;
  202. this.boxW = MGuiRMI.RESX;
  203. this.boxH = MGuiRMI.RESY;
  204. this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  205. // Non-Gui stuff
  206. this.nrIterations = 1000;
  207. }
  208. // visualization
  209. static void applyLookupTable(int[] data, int[] dest, int[] lookupTable) {
  210. for (int i = 0; i < data.length; i++) {
  211. dest[i] = lookupTable[data[i]];
  212. }
  213. }
  214. // here we check what the buttons do
  215. public void actionPerformed(ActionEvent ae) {
  216. if (ae.getSource() == this.endButton) {
  217. System.out.println("Ende");
  218. System.exit(0);
  219. } else
  220. if (ae.getSource() == this.backButton) {
  221. System.out.println("Zurueck");
  222. // Zoom und Ausschnitt zur�cksetzen
  223. double ULx = -2;
  224. double ULy = 2;
  225. double LRx = 2;
  226. double LRy = -2;
  227. this.boxULx = 0;
  228. this.boxULy = 0;
  229. this.boxW = MGuiRMI.RESX;
  230. this.boxH = MGuiRMI.RESY;
  231. this.viewUpper.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
  232. this.viewUpper.repaint();
  233. this.viewLower.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
  234. this.viewLower.repaint();
  235. if (this.remoteCalcObj == null)
  236. {
  237. String message = "Fehler: noch nicht verbunden, noch keine Berechnung durchgef�hrt";
  238. this.message.setText(message);
  239. System.out.println(message);
  240. }
  241. else
  242. {
  243. try {
  244. this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
  245. } catch (RemoteException e) {
  246. // TODO Auto-generated catch block
  247. e.printStackTrace();
  248. }
  249. this.message.setText("Ausschnitt zur�ckgesetzt");
  250. }
  251. if (this.remoteCalcObj2 == null)
  252. {
  253. String message = "Fehler: noch nicht verbunden, noch keine Berechnung durchgef�hrt";
  254. this.message.setText(message);
  255. System.out.println(message);
  256. }
  257. else
  258. {
  259. try {
  260. this.remoteCalcObj2.setView(ULx, ULy, LRx, LRy);
  261. } catch (RemoteException e) {
  262. // TODO Auto-generated catch block
  263. e.printStackTrace();
  264. }
  265. this.message.setText("Ausschnitt zur�ckgesetzt");
  266. }
  267. } else
  268. if (ae.getSource() == this.calcButton) {
  269. String hostname = this.hostTextField.getText();
  270. System.out.println("Verbinde mit RMI Registry auf Host: " + hostname);
  271. try {
  272. Registry registry = LocateRegistry.getRegistry(hostname);
  273. this.remoteCalcObj = (RMIMandelbrotCalculationsInterface) registry.lookup("RMIMandelbrotCalculationsInterface");
  274. this.remoteCalcObj2 = (RMIMandelbrotCalculationsInterface) registry.lookup("RMIMandelbrotCalculationsInterface2");
  275. /** CODE SEBASTIAN
  276. System.out.println("Rechnen");
  277. long timestampStart = System.currentTimeMillis();
  278. //this.boxW = this.boxW / 2;
  279. //MGuiRMI.RESX = MGuiRMI.RESX / 2;
  280. double ULx = 0;
  281. double ULy = 0;
  282. double LRx = 0;
  283. double LRy = 0;
  284. ULx = this.remoteCalcObj.getULx();
  285. ULy = this.remoteCalcObj.getULy();
  286. LRx = this.remoteCalcObj.getLRx();
  287. LRy = this.remoteCalcObj.getLRy();
  288. double w = LRx - ULx;
  289. double h = LRy - ULy;
  290. ULx = ULx + w * this.boxULx / (double) MGuiRMI.RESX;
  291. ULy = ULy + h * this.boxULy / (double) MGuiRMI.RESY;
  292. w *= this.boxW / (double) (RESX);
  293. h *= this.boxH / (double) (RESX);
  294. LRx = ULx + w;
  295. LRy = ULy + h;
  296. System.out.println(ULx + "/" + ULy + "/" + LRx + "/" + LRy);
  297. this.boxULx = 0;
  298. this.boxULy = 0;
  299. this.boxW = MGuiRMI.RESX;
  300. this.boxH = MGuiRMI.RESY;
  301. int[] colors = null;
  302. //this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
  303. this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
  304. end */
  305. /* Code Alex */
  306. System.out.println("Rechnen");
  307. RMIMandelbrotCalculationThread rmimct = new RMIMandelbrotCalculationThread(true, this.viewUpper, this.remoteCalcObj, maxIterations.getValue());
  308. new Thread(rmimct).start();
  309. RMIMandelbrotCalculationThread rmimct2 = new RMIMandelbrotCalculationThread(false, this.viewLower, this.remoteCalcObj2, maxIterations.getValue());
  310. new Thread(rmimct2).start();
  311. } catch (RemoteException | NotBoundException e) {
  312. // TODO Auto-generated catch block
  313. e.printStackTrace();
  314. }
  315. }
  316. }
  317. // Zoom not wirking for lower...
  318. public void mousePressed(MouseEvent e) {
  319. this.boxULx = e.getX();
  320. this.boxULy = e.getY();
  321. this.boxW = 1;
  322. this.boxH = 1;
  323. this.viewUpper.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
  324. this.message.setText("boxULx: " + this.boxULx + " boxULy: " + this.boxULy + " boxW: " + this.boxW + " boxH: " + this.boxH);
  325. }
  326. public void mouseDragged(MouseEvent e) {
  327. this.boxW = e.getX() - this.boxULx + 1;
  328. this.boxH = e.getY() - this.boxULy + 1;
  329. int m = Math.min(boxW, boxH);
  330. this.boxW = m;
  331. this.boxH = m;
  332. this.viewUpper.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
  333. this.message.setText("boxULx: " + this.boxULx + " boxULy: " + this.boxULy + " boxW: " + this.boxW + " boxH: " + this.boxH);
  334. this.viewUpper.repaint();
  335. }
  336. public void mouseReleased(MouseEvent e) {
  337. if (e.getButton() == MouseEvent.BUTTON1) {
  338. this.viewUpper.repaint();
  339. this.message.setText("Gesetzt: boxULx: " + this.boxULx + " boxULy: " + this.boxULy + " boxW: " + this.boxW + " boxH: " + this.boxH);
  340. }
  341. }
  342. public void mouseMoved(MouseEvent e) {
  343. }
  344. public void mouseExited(MouseEvent e) {
  345. }
  346. public void mouseEntered(MouseEvent e) {
  347. }
  348. public void mouseClicked(MouseEvent e) {
  349. }
  350. // process a new slider value
  351. public void stateChanged(ChangeEvent ce) {
  352. if (ce.getSource() == this.maxIterations) {
  353. // System.out.println("Neuer Wert");
  354. this.nrIterations = this.maxIterations.getValue() * 1000;
  355. }
  356. }
  357. // main, just instantiate an MGui object, gives control to the Gui
  358. public static void main(String[] args) {
  359. @SuppressWarnings("unused")
  360. MGuiRMI gui = new MGuiRMI();
  361. }
  362. }