eclipse meckert rum das es nicht auf die Plasma.class zugreifen kann.
Scheint aber ein Eclipse-Problem zu sein, da es den gleichen Fehler ausgegeben hat nachdem ich andere Programme hab laufen lassen, die nichts damit zu tun haben… sehr komisch:mad:
Komische rweise war der buildpath falsch eingestellt - jetzt funktioniert es auch mit eclise.
Allerdings hab ich ein neues Problem.
Ich bekomme in der neuen Variante keine kontinuierliche Grafikausgabe. Ich vermute, dass wenn ich die Aufgabe auf die GPU lege, es keine weiteren Probleme gibt - aber wie geht das? Oder weis jemand andere Abhilfe?
import java.applet.*;
import java.util.Random;
import java.awt.image.*;
//import java.lang.System;
public class Plasma extends Applet implements Runnable{
private static final long serialVersionUID = 1L;
/*Variablendeklaration*/
boolean stop;
int GridMX, GridMY;
int x, y, Xheat, Yheat, Xcool, Ycool, l, k;
double h1, h2, R, cScale, Fheat, Fcool, Fmax, eps0, q, Tmax, Tabs;
double rheat[][];
double rcool[][];
double[][] GridR;
double[][] GridG;
double[][] GridB;
Random rand = new Random();
DataBuffer dbPlasma;
BufferedImage biPlasma;
Thread animator;
/*Hauptfunktion*/
public void init()
{
GridMX=200; //x-Dimension des Applets
GridMY=200; //y-Dimension des Applets
biPlasma = new BufferedImage(GridMX, GridMY, 1); //Instanz des Buffers mit Dim MX, MY
dbPlasma = biPlasma.getRaster().getDataBuffer(); //Buffer Werte
GridR = new double[GridMX+1][GridMY+1]; //Instanz der Raster - Rot
GridG = new double[GridMX+1][GridMY+1]; //Grün
GridB = new double[GridMX+1][GridMY+1]; //Blau
rheat = new double[GridMX+1][GridMY+1];
rcool = new double[GridMX+1][GridMY+1];
/*Initialbelegung*/
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{ GridR[x][y]=0;
GridG[x][y]=0;
GridB[x][y]=255;
}
}
Xheat=25; //Position der Heizquelle
Yheat=GridMY-10;
Xcool=GridMX-10;
Ycool=25;
R =Math.sqrt(((GridMX-1.0)*(GridMX-1.0))+((GridMY-1.0)*(GridMY-1.0))); //Systemradius
}
/*Nebenfunktionen*/
//Buffer zeichnen, etc.
public void paint(Graphics g)
{ g.drawImage(biPlasma, 0,0, this); }
public void update(Graphics g)
{ paint(g); }
public void start()
{ if(animator == null)
{ animator=new Thread(this);
animator.start(); } }
public void stop()
{ stop=true;
animator = null; }
//Farbwechsel
public void run()
{Tmax=500;
l=255;
Tabs=250;
Fmax=Tabs/(1+Math.exp(.01)); //Höchster Wert für heißesten Pkt.
//System.out.println("Fmax= "+Fmax);
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{
rheat[x][y]=Math.sqrt((x-Xheat)*(x-Xheat)+(y-Yheat)*(y-Yheat));
rcool[x][y]=Math.sqrt((x-Xcool)*(x-Xcool)+(y-Ycool)*(y-Ycool));
if (rheat[x][y]==0){
rheat[x][y]=.01;}
if (rcool[x][y]==0){
rcool[x][y]=.01;}
}}
while(!stop)
{
for (q=0; q<Tmax; q=q+10){
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{
Fheat=q/(1+Math.exp(rheat[x][y]/(R*2)));
Fcool=Tmax*5/7/(1+Math.exp(rcool[x][y]/(R*2)));
h1=Math.round((Fheat*1275/(Fmax)));
h2=Math.round((Fcool*1275/(Fmax)));
h1=h1-h2;
if(h1<0){h1=0;}
if(h1<=l){ //Blau->Hellblau
GridR[x][y]=0;
GridG[x][y]=h1;
GridB[x][y]=255;
}
if(h1>255&&h1<=(2*l)){ //Hellblau->Grün
GridR[x][y]=0;
GridG[x][y]=255;
GridB[x][y]=2*255-h1;
}
if(h1>(2*l)&&h1<=(3*l)){ //Grün->Gelb
GridR[x][y]=-2*255+h1;
GridG[x][y]=255;
GridB[x][y]=0;
}
if(h1>(3*l)&&h1<=(4*l)){ //Gelb->Rot
GridR[x][y]=255;
GridG[x][y]=4*255-h1;
GridB[x][y]=0;
}
if(h1>(4*l)&&h1<=(5*l)){ //Rot->Lila
GridR[x][y]=255;
GridG[x][y]=0;
GridB[x][y]=-4*255+h1;
}
if(h1>5*l){ //sonst
GridR[x][y]=255;
GridG[x][y]=0;
GridB[x][y]=5*255;
}
dbPlasma.setElem(x + (y*GridMX), ((int)GridR[x][y]<<16) | ((int)GridG[x][y]<<8) | ((int)GridB[x][y]));
}
}
}
//if (k%10==0){
repaint();
//}k++;
}
}
}```
Danke für Kritik;)
Mit der GPU hat das aber zumindest so weit zu tun, dass das nach etwas aussieht, was man sehr schön und einfach mit JOCL machen könnte - und ich hatte in meinem Kopf schon ein kleines „Haftetikett“ erstellt, dass ich das mal probieren will
Eigentlich läuft die Berechnung dort ja in einem eigenen Thread. Allerdings ohne wait oder yield oder ähnliches - er ist also (theoretisch) mit dem einen Thread immer zu 100% ziemlich ausgelastet. Vermutlich würde es schon helfen, nach dem „repaint()“ mal ein kleines
Thread.sleep(10);
einzubauen…
Ich hab es mal versucht zum laufen zu bekommen, leider ohne großen erfolg:(.
Ich wäre euch also wirklich dankbar, wenn ihr mir sagen könntet was ich anders machen muss.
import java.applet.*;
import java.util.Random;
import java.awt.image.*;
//import javax.swing.*;
//import java.lang.*;
//import java.lang.System;
public class Plasma //main-class
extends Applet //benutzt Applet
implements Runnable //implementiert lauffähigkeit(Thread)
{
private static final long serialVersionUID = 1L;
/*Variablendeklaration*/
boolean stop;
int GridMX, GridMY;
int x, y, Xheat, Yheat, Xcool, Ycool, l, k;
double h1, h2, R, cScale, Fheat, Fcool, Fmax, eps0, q, Tmax, Tabs;
double rheat[][];
double rcool[][];
double[][] GridR;
double[][] GridG;
double[][] GridB;
Random rand = new Random();
DataBuffer dbPlasma;
BufferedImage biPlasma;
Thread animator;
Thread calculus;
/*Initialmethode - Wertzuweisung*/
public void init()
{
/*Wertzuweisung*/
GridMX=200; //x-Dimension des Applets
GridMY=200; //y-Dimension des Applets
Xheat=25; //Position der Heizquelle
Yheat=GridMY-10;
Xcool=GridMX-10;
Ycool=25;
R =Math.sqrt(((GridMX-1.0)*(GridMX-1.0))+((GridMY-1.0)*(GridMY-1.0))); //Systemradius/Spektralnorm
/*Bildspeicher*/
biPlasma = new BufferedImage(GridMX, GridMY, 1); //**Instanz** des Buffers mit Dim MX, MY
dbPlasma = biPlasma.getRaster().getDataBuffer(); //Buffer Werte
/*Feldgröße initialisieren*/
GridR = new double[GridMX+1][GridMY+1]; //Instanz der Raster - Rot
GridG = new double[GridMX+1][GridMY+1]; //Grün
GridB = new double[GridMX+1][GridMY+1]; //Blau
rheat = new double[GridMX+1][GridMY+1];
rcool = new double[GridMX+1][GridMY+1];
/*->Initialbelegung der Felder*/
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{ GridR[x][y]=0;
GridG[x][y]=0;
GridB[x][y]=255;
}
}
}//end of init()
/*Buffer zeichnen*/
public void paint(Graphics g)
{ g.drawImage(biPlasma, 0, 0, this); //Position des Zeichnens
}
/*
public void update(Graphics g)
{ paint(g); //zeichnen ausführen
}*/
public void start()
{
if(animator == null)
{
animator=new Thread(this);
calculus=new Thread(this);
animator.start();
calculus.start();
}
}
public void stop()
{ stop=true;
animator = null;
calculus = null;
}
public void run()
{
Tmax=500;
l=255;
Tabs=250;
Fmax=Tabs/(1+Math.exp(.01)); //Höchster Wert für heißesten Pkt.
//System.out.println("Fmax= "+Fmax);
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{
rheat[x][y]=Math.sqrt((x-Xheat)*(x-Xheat)+(y-Yheat)*(y-Yheat));
rcool[x][y]=Math.sqrt((x-Xcool)*(x-Xcool)+(y-Ycool)*(y-Ycool));
if (rheat[x][y]==0)
{
rheat[x][y]=.01;
}
if (rcool[x][y]==0)
{
rcool[x][y]=.01;
}
}
}
while(!stop)
{
try {
Thread.sleep(2000);
for (q=0; q<Tmax; q=q+10){
//q=490;
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{
Fheat=q/(1+Math.exp(rheat[x][y]/(R*2)));
Fcool=Tmax*5/7/(1+Math.exp(rcool[x][y]/(R*2)));
h1=Math.round((Fheat*1275/(Fmax)));
h2=Math.round((Fcool*1275/(Fmax)));
h1=h1-h2;
if(h1<0){h1=0;}
if(h1<=l) //Blau->Hellblau
{
GridR[x][y]=0;
GridG[x][y]=h1;
GridB[x][y]=255;
}
if(h1>255&&h1<=(2*l)) //Hellblau->Grün
{
GridR[x][y]=0;
GridG[x][y]=255;
GridB[x][y]=2*255-h1;
}
if(h1>(2*l)&&h1<=(3*l)) //Grün->Gelb
{
GridR[x][y]=-2*255+h1;
GridG[x][y]=255;
GridB[x][y]=0;
}
if(h1>(3*l)&&h1<=(4*l)) //Gelb->Rot
{
GridR[x][y]=255;
GridG[x][y]=4*255-h1;
GridB[x][y]=0;
}
if(h1>(4*l)&&h1<=(5*l)) //Rot->Lila
{
GridR[x][y]=255;
GridG[x][y]=0;
GridB[x][y]=-4*255+h1;
}
if(h1>5*l) //sonst
{
GridR[x][y]=255;
GridG[x][y]=0;
GridB[x][y]=5*255;
}
dbPlasma.setElem(x + (y*GridMX), ((int)GridR[x][y]<<16) | ((int)GridG[x][y]<<8) | ((int)GridB[x][y]));
}//end of for
}//end of for
}//end of for
}//end of try
catch (InterruptedException e){}
animator.suspend();
try
{
Thread.sleep(2000);
repaint();
}
catch (InterruptedException e){}
}//end of while
calculus.suspend();
animator.resume();
}//end of run()
}//end of class ```
Eigentlich will ich den “Temperaturverlauf” dynamisch dargestellt haben. Also jede berechnete Änderung nach kurzer Zeit ausgegeben bekommen, so dass man sieht wie die Temperatur steigt. Allerdings rechnet er nur alles durch und gibt mit dann nach Blackscreen den “Stationären” Zustand aus.
Da ich noch lerne, hab ich auch schon die nächste dumme Frage.
Wie bekomme ich meine Animation jetzt in einen bestimmten Bereich eines JFrames, und wie kann ich eine Scrollbar belibige darin positioieren:confused:
Wenn du eine Swing Anwendung machen willst, brauchst du eine „main“ Methode. Positioniert wird mittels LayoutManager. Was du mit einer Scrollbar machen willst, musst du schon genauer definieren. Das folgende Beispiel nimmt GridBagLayout als LayoutManager:
Runnable gui = new Runnable() {
public void run() {
JFrame f = new JFrame("Plasma");
f.setLayout(new GridBagLayout());
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setSize(400, 300);
f.setLocationRelativeTo(null);
Plasma plasma = new Plasma();
plasma.setPreferredSize(new Dimension(200, 200));
plasma.setMinimumSize(new Dimension(200, 200));
plasma.init();
plasma.start();
f.add(plasma);
f.setVisible(true);
}
};
//GUI must start on EventDispatchThread:
SwingUtilities.invokeLater(gui);
}```
mit der Scrollbar will ich den Wert Tmax in der Plasma.class verändern, so dass ich einen Schieberegler für die maximale Temperatur habe. Ich würde es am liebsten so mach wie in diesem Applet: http://www.am.uni-duesseldorf.de/de/Interaktiv/Biologische_Musterbildung/MubiApp.html
auch mit numerischer Anzeige, nur ist der Quellcode leider nicht einsehbar.
Nach einiger zeit hab ich mal etwas weiter gemacht und hab nun das Problem das meine Grafik nichtmehr weiter dargestellt wird wenn ich daneben klicke. Wie kann ich das beheben?
import java.awt.event.*;
import java.awt.LayoutManager;
import javax.swing.*;
public class FullScreenJFrame extends JFrame implements KeyListener
{
public FullScreenJFrame(String title)
{
super(title);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setUndecorated(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(0,0,screenSize.width, screenSize.height);
//getContentPane().add(new JLabel("A JKiosk"), BorderLayout.NORTH);
setVisible(true);
addKeyListener(this);
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
FullScreenJFrame.this.setVisible(false);
System.exit(0);
}
}
}
);
/*
JButton closeButton = new JButton("Close");
closeButton.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
System.out.println("Close button Pressed");
FullScreenJFrame.this.setVisible(false);
System.exit(0);
}
});
getContentPane().add(closeButton, BorderLayout.PAGE_END);*/
}//End of method FullScreenJFrame
public static void main( String[] args )
{
Runnable gui = new Runnable()
{
public void run()
{
FullScreenJFrame wnd = new FullScreenJFrame("Plasma");
FullScreenJFrame frame = new FullScreenJFrame("Plasma");
wnd.setVisible(true);
frame.setIgnoreRepaint(true);
wnd.setIgnoreRepaint(true);
Plasma plasma = new Plasma();
frame.setVisible(true);
//frame.setLayout(new GridBagLayout());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
//plasma.setSize(new Dimension(500, 300));
plasma.init();
plasma.start();
frame.add(plasma);
frame.setLocation(820, 50);
frame.setVisible(true);
}
};
//GUI must start on EventDispatchThread:
SwingUtilities.invokeLater(gui);
}
public FullScreenJFrame()
{
super("Nachrichtentransfer");
//setBackground(Color.lightGray);
//setSize(300,200);
//setLocation(200,100);
setVisible(true);
addKeyListener(this);
}
public void paint(Graphics g)
{
g.setFont(new Font("Serif",Font.PLAIN,18));
g.drawString("Zum Beenden bitte ESC drücken...",10,50);
}
public void keyPressed(KeyEvent event){
if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
{
setVisible(false);
dispose();
System.exit(0);
}
}
public void keyReleased(KeyEvent arg0){}
public void keyTyped(KeyEvent arg0){}
}//End of class FullScreenJFrame```
```import java.awt.*;
import java.applet.*;
import java.util.Random;
import java.awt.image.*;
import javax.swing.JFrame;
//import javax.swing.*;
//import java.lang.*;
//import java.lang.System;
public class Plasma extends Applet implements Runnable //implementiert lauffähigkeit(Thread)
{
private static final long serialVersionUID = 1L;
/*Variablendeklaration*/
boolean stop;
int GridMX, GridMY;
int x, y, Xheat, Yheat, Xcool, Ycool, l, k, hilf;
double h1, h2, R, cScale, Fheat, Fcool, Fmax, eps0, q, Tmax, Tabs;
double rheat[][];
double rcool[][];
double[][] GridR;
double[][] GridG;
double[][] GridB;
Random rand = new Random();
DataBuffer dbPlasma;
BufferedImage biPlasma;
Thread animator;
Thread calculus;
/*Initialmethode - Wertzuweisung*/
public void init()
{
/*Wertzuweisung*/
GridMX=400; //x-Dimension des Applets
GridMY=400; //y-Dimension des Applets
Xheat=25; //Position der Heizquelle
Yheat=GridMY-10;
Xcool=GridMX-10;
Ycool=25;
R =Math.sqrt(((GridMX-1.0)*(GridMX-1.0))+((GridMY-1.0)*(GridMY-1.0))); //Systemradius/Spektralnorm
hilf=1;
/*Bildspeicher*/
biPlasma = new BufferedImage(GridMX, GridMY, 1); //**Instanz** des Buffers mit Dim MX, MY
dbPlasma = biPlasma.getRaster().getDataBuffer(); //Buffer Werte
/*Feldgröße initialisieren*/
GridR = new double[GridMX+1][GridMY+1]; //Instanz der Raster - Rot
GridG = new double[GridMX+1][GridMY+1]; //Grün
GridB = new double[GridMX+1][GridMY+1]; //Blau
rheat = new double[GridMX+1][GridMY+1];
rcool = new double[GridMX+1][GridMY+1];
/*->Initialbelegung der Felder*/
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{ GridR[x][y]=0;
GridG[x][y]=0;
GridB[x][y]=255;
}
}
}//end of init()
/*Buffer zeichnen*/
public void paint(Graphics g)
{ g.drawImage(biPlasma, 0, 0, this); //Position des Zeichnens
}
public void update(Graphics g)
{ paint(g); //zeichnen ausführen
}
public void start()
{
animator=new Thread(this);
animator.start();
}
public void stop()
{ stop=true;
animator = null;
calculus = null;
}
public void run()
{
Tmax=500;
l=255;
Tabs=250;
Fmax=Tabs/(1+Math.exp(.01)); //Höchster Wert für heißesten Pkt.
//System.out.println("Fmax= "+Fmax);
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{
rheat[x][y]=Math.sqrt((x-Xheat)*(x-Xheat)+(y-Yheat)*(y-Yheat));
rcool[x][y]=Math.sqrt((x-Xcool)*(x-Xcool)+(y-Ycool)*(y-Ycool));
if (rheat[x][y]==0)
{
rheat[x][y]=.01;
}
if (rcool[x][y]==0)
{
rcool[x][y]=.01;
}
}
}
while(!stop)
{
//synchronized (getClass()){
for (q=290; q<Tmax; q=q+1){
//q=490;
try {
Thread.sleep(3);
for(x=0; x<GridMX; x++)
{ for(y=0; y<GridMY; y++)
{
Fheat=q/(1+Math.exp(rheat[x][y]/(R*2)));
Fcool=Tmax*5/7/(1+Math.exp(rcool[x][y]/(R*2)));
h1=Math.round((Fheat*1275/(Fmax)));
h2=Math.round((Fcool*1275/(Fmax)));
h1=h1-h2;
if(h1<0){h1=0;}
if(h1<=l) //Blau->Hellblau
{
GridR[x][y]=0;
GridG[x][y]=h1;
GridB[x][y]=255;
}
if(h1>255&&h1<=(2*l)) //Hellblau->Grün
{
GridR[x][y]=0;
GridG[x][y]=255;
GridB[x][y]=2*255-h1;
}
if(h1>(2*l)&&h1<=(3*l)) //Grün->Gelb
{
GridR[x][y]=-2*255+h1;
GridG[x][y]=255;
GridB[x][y]=0;
}
if(h1>(3*l)&&h1<=(4*l)) //Gelb->Rot
{
GridR[x][y]=255;
GridG[x][y]=4*255-h1;
GridB[x][y]=0;
}
if(h1>(4*l)&&h1<=(5*l)) //Rot->Lila
{
GridR[x][y]=255;
GridG[x][y]=0;
GridB[x][y]=-4*255+h1;
}
if(h1>5*l) //sonst
{
GridR[x][y]=255;
GridG[x][y]=0;
GridB[x][y]=5*255;
}
//System.out.println("Änderung");
dbPlasma.setElem(x + (y*GridMX), ((int)GridR[x][y]<<16) | ((int)GridG[x][y]<<8) | ((int)GridB[x][y]));
}//end of for
}//end of for
//Thread.sleep(10);
//animator.suspend();
}//end of try
//}end of for
//Thread.sleep(2000);//}
catch (InterruptedException e){}
//animator.suspend();
try
{
Thread.sleep(200);
repaint();
}
catch (InterruptedException e){}
//calculus.suspend();
//animator.resume();
}//end of while
}//end of run()
}//end of class
}```