forked from srieger/verteilte-systeme-bsc-ai-examples
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.
312 lines
8.8 KiB
312 lines
8.8 KiB
package verteiltesysteme.mandelbrot.rmi;
|
|
|
|
import java.awt.BorderLayout;
|
|
|
|
//Mandelbot Example A. Gepperth
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Graphics;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.event.MouseListener;
|
|
import java.awt.event.MouseMotionListener;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
import java.rmi.NotBoundException;
|
|
import java.rmi.RemoteException;
|
|
import java.rmi.registry.LocateRegistry;
|
|
import java.rmi.registry.Registry;
|
|
|
|
import javax.swing.ImageIcon;
|
|
import javax.swing.JButton;
|
|
import javax.swing.JFrame;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JSlider;
|
|
import javax.swing.JTextField;
|
|
import javax.swing.border.BevelBorder;
|
|
import javax.swing.event.ChangeEvent;
|
|
import javax.swing.event.ChangeListener;
|
|
|
|
class MyJLabel extends JLabel {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
private static final long serialVersionUID = -7750935382747799343L;
|
|
|
|
int boxULx, boxULy, boxW, boxH;
|
|
|
|
MyJLabel() {
|
|
super();
|
|
}
|
|
|
|
MyJLabel(String s) {
|
|
super(s);
|
|
}
|
|
|
|
void setBox(int boxULx, int boxULy, int boxW, int boxH) {
|
|
this.boxULx = boxULx;
|
|
this.boxULy = boxULy;
|
|
this.boxW = boxW;
|
|
this.boxH = boxH;
|
|
}
|
|
|
|
@Override
|
|
protected void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
g.setColor(Color.black);
|
|
g.drawRect(this.boxULx, this.boxULy, this.boxW, this.boxH);
|
|
}
|
|
|
|
}
|
|
|
|
public class MGuiRMI implements ActionListener, ChangeListener, MouseListener, MouseMotionListener {
|
|
|
|
// GUI elements
|
|
JFrame frame;
|
|
JPanel panel;
|
|
JButton endButton;
|
|
JButton backButton;
|
|
JButton calcButton;
|
|
JTextField hostTextField;
|
|
JSlider maxIterations;
|
|
MyJLabel view;
|
|
JLabel message;
|
|
int nrIterations;
|
|
|
|
// box management
|
|
int boxULx, boxULy, boxW, boxH;
|
|
boolean dragging = false;
|
|
|
|
// this one does all the calculating work
|
|
RMIMandelbrotCalculationsInterface remoteCalcObj;
|
|
|
|
// how many points in the image?
|
|
// change if you want a higher resolution
|
|
public static int RESX = 600;
|
|
public static int RESY = 600;
|
|
|
|
MGuiRMI() {
|
|
// set up GUI
|
|
this.frame = new JFrame("Mandelbrotmenge");
|
|
this.panel = new JPanel();
|
|
this.endButton = new JButton("Ende");
|
|
this.panel.add(this.endButton);
|
|
this.backButton = new JButton("Zurück");
|
|
this.panel.add(this.backButton);
|
|
this.calcButton = new JButton("Rechnen");
|
|
this.hostTextField = new JTextField(20);
|
|
this.hostTextField.setText("localhost");
|
|
this.panel.add(this.calcButton);
|
|
this.panel.add(this.hostTextField);
|
|
this.frame.add(this.panel);
|
|
this.frame.setSize(700, 720);
|
|
this.frame.setVisible(true);
|
|
this.view = new MyJLabel();
|
|
this.maxIterations = new JSlider(0, 50, 30);
|
|
this.panel.add(this.maxIterations);
|
|
this.panel.add(this.view);
|
|
this.message = new JLabel("Status");
|
|
this.message.setBorder(new BevelBorder(BevelBorder.LOWERED));
|
|
this.frame.add(this.message,BorderLayout.SOUTH);
|
|
|
|
this.endButton.addActionListener(this);
|
|
this.backButton.addActionListener(this);
|
|
this.calcButton.addActionListener(this);
|
|
this.maxIterations.addChangeListener(this);
|
|
|
|
this.maxIterations.setMajorTickSpacing(10);
|
|
this.maxIterations.setPaintTicks(true);
|
|
this.maxIterations.setPaintLabels(true);
|
|
|
|
this.view.addMouseListener(this);
|
|
this.view.addMouseMotionListener(this);
|
|
|
|
this.boxULx = 0;
|
|
this.boxULy = 0;
|
|
this.boxW = MGuiRMI.RESX;
|
|
this.boxH = MGuiRMI.RESY;
|
|
|
|
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
// Non-Gui stuff
|
|
this.nrIterations = 1000;
|
|
}
|
|
|
|
// visualization related stuff, do not touch!
|
|
int[] generateLookupTable(int nrHues) {
|
|
int[] tmp = new int[nrHues + 1];
|
|
int cycle = 2048;
|
|
for (int i = 0; i < nrHues; i++) {
|
|
float hue = 1 * ((float) (i % cycle)) / cycle/* ((float)nrHues) */ ;
|
|
tmp[i] = Color.HSBtoRGB(hue, 0.8f, 1.0f);
|
|
}
|
|
tmp[0] = Color.HSBtoRGB(0f, 1.0f, 0.0f);
|
|
return tmp;
|
|
}
|
|
|
|
// visualization
|
|
static void applyLookupTable(int[] data, int[] dest, int[] lookupTable) {
|
|
for (int i = 0; i < data.length; i++) {
|
|
dest[i] = lookupTable[data[i]];
|
|
}
|
|
}
|
|
|
|
// here we check what the buttons do
|
|
public void actionPerformed(ActionEvent ae) {
|
|
if (ae.getSource() == this.endButton) {
|
|
System.out.println("Ende");
|
|
System.exit(0);
|
|
} else
|
|
|
|
if (ae.getSource() == this.backButton) {
|
|
System.out.println("Zurueck");
|
|
// Zoom und Ausschnitt zurücksetzen
|
|
double ULx = -0.16099999999999995;
|
|
double ULy = -0.9365333333333333;
|
|
double LRx = -0.03533333333333327;
|
|
double LRy = -0.8108666666666666;
|
|
this.boxULx = 0;
|
|
this.boxULy = 0;
|
|
this.boxW = MGuiRMI.RESX;
|
|
this.boxH = MGuiRMI.RESY;
|
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
|
|
this.view.repaint();
|
|
if (this.remoteCalcObj == null)
|
|
{
|
|
String message = "Fehler: noch nicht verbunden, noch keine Berechnung durchgeführt";
|
|
this.message.setText(message);
|
|
System.out.println(message);
|
|
}
|
|
else
|
|
{
|
|
try {
|
|
this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
|
|
} catch (RemoteException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
this.message.setText("Ausschnitt zurückgesetzt");
|
|
}
|
|
} else
|
|
|
|
if (ae.getSource() == this.calcButton) {
|
|
String hostname = this.hostTextField.getText();
|
|
System.out.println("Verbinde mit RMI Registry auf Host: " + hostname);
|
|
try {
|
|
Registry registry = LocateRegistry.getRegistry(hostname);
|
|
this.remoteCalcObj = (RMIMandelbrotCalculationsInterface) registry.lookup("RMIMandelbrotCalculationsInterface");
|
|
System.out.println("Rechnen");
|
|
long timestampStart = System.currentTimeMillis();
|
|
|
|
//this.boxW = this.boxW / 2;
|
|
//MGuiRMI.RESX = MGuiRMI.RESX / 2;
|
|
|
|
double ULx = 0;
|
|
double ULy = 0;
|
|
double LRx = 0;
|
|
double LRy = 0;
|
|
|
|
ULx = this.remoteCalcObj.getULx();
|
|
ULy = this.remoteCalcObj.getULy();
|
|
LRx = this.remoteCalcObj.getLRx();
|
|
LRy = this.remoteCalcObj.getLRy();
|
|
|
|
double w = LRx - ULx;
|
|
double h = LRy - ULy;
|
|
ULx = ULx + w * this.boxULx / (double) MGuiRMI.RESX;
|
|
ULy = ULy + h * this.boxULy / (double) MGuiRMI.RESY;
|
|
w *= this.boxW / (double) (RESX);
|
|
h *= this.boxH / (double) (RESX);
|
|
LRx = ULx + w;
|
|
LRy = ULy + h;
|
|
System.out.println(ULx + "/" + ULy + "/" + LRx + "/" + LRy);
|
|
this.boxULx = 0;
|
|
this.boxULy = 0;
|
|
this.boxW = MGuiRMI.RESX;
|
|
this.boxH = MGuiRMI.RESY;
|
|
int[] colors = null;
|
|
|
|
//this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
|
|
this.remoteCalcObj.setView(ULx, ULy, LRx, LRy);
|
|
this.remoteCalcObj.iterateAllPoints(this.maxIterations.getValue() * 1000, MGuiRMI.RESX, MGuiRMI.RESY);
|
|
int[] lookupTable = generateLookupTable(this.maxIterations.getValue() * 1000);
|
|
colors = new int[MGuiRMI.RESX * MGuiRMI.RESY];
|
|
MGuiRMI.applyLookupTable(remoteCalcObj.getResult(), colors, lookupTable);
|
|
|
|
BufferedImage colorImage = new BufferedImage(MGuiRMI.RESX, MGuiRMI.RESY, BufferedImage.TYPE_INT_ARGB);
|
|
colorImage.setRGB(0, 0, MGuiRMI.RESX, MGuiRMI.RESY, colors, 0, MGuiRMI.RESX);
|
|
this.view.setIcon(new ImageIcon(colorImage));
|
|
|
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
|
|
this.view.repaint();
|
|
|
|
long timestampEnd = System.currentTimeMillis();
|
|
|
|
String timeElapsed = "Dauer: " + ((timestampEnd - timestampStart) / 1000.0) + " sec";
|
|
System.out.println(timeElapsed);
|
|
this.message.setText(timeElapsed);
|
|
} catch (RemoteException | NotBoundException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
this.boxULx = e.getX();
|
|
this.boxULy = e.getY();
|
|
this.boxW = 1;
|
|
this.boxH = 1;
|
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
|
|
this.message.setText("boxULx: " + this.boxULx + " boxULy: " + this.boxULy + " boxW: " + this.boxW + " boxH: " + this.boxH);
|
|
}
|
|
|
|
public void mouseDragged(MouseEvent e) {
|
|
this.boxW = e.getX() - this.boxULx + 1;
|
|
this.boxH = e.getY() - this.boxULy + 1;
|
|
int m = Math.min(boxW, boxH);
|
|
this.boxW = m;
|
|
this.boxH = m;
|
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH);
|
|
this.message.setText("boxULx: " + this.boxULx + " boxULy: " + this.boxULy + " boxW: " + this.boxW + " boxH: " + this.boxH);
|
|
this.view.repaint();
|
|
}
|
|
|
|
public void mouseReleased(MouseEvent e) {
|
|
|
|
if (e.getButton() == MouseEvent.BUTTON1) {
|
|
this.view.repaint();
|
|
this.message.setText("Gesetzt: boxULx: " + this.boxULx + " boxULy: " + this.boxULy + " boxW: " + this.boxW + " boxH: " + this.boxH);
|
|
}
|
|
}
|
|
|
|
public void mouseMoved(MouseEvent e) {
|
|
}
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
}
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
}
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
}
|
|
|
|
// process a new slider value
|
|
public void stateChanged(ChangeEvent ce) {
|
|
if (ce.getSource() == this.maxIterations) {
|
|
// System.out.println("Neuer Wert");
|
|
this.nrIterations = this.maxIterations.getValue() * 1000;
|
|
}
|
|
}
|
|
|
|
// main, just instantiate an MGui object, gives control to the Gui
|
|
public static void main(String[] args) {
|
|
@SuppressWarnings("unused")
|
|
MGuiRMI gui = new MGuiRMI();
|
|
}
|
|
}
|