OsziDarstellung

Status
Nicht offen für weitere Antworten.

SammY

Bekanntes Mitglied
Hi Leute,

hab ein kleines Prob und hoffe ihr könnt mir helfen.

Also ich soll ein graphische Darstellung eines Wertes realisieren der sich jede Sekunde ändert.

Wertebereich(0 - 300).

Dies soll ein in einem JFrame passieren.
Es soll ungefähr so wie ein Oszi ausschauen.



Gruß Manuel.
 

SammY

Bekanntes Mitglied
Ich muss sagen vom Prinzip her stell ich mir das auch so vor.
Nur ein kleines Problem:

Ich kenn mich in dem Quellcode nicht recht stark aus. :cry:
Gibs denn da vielleicht nicht noch ein anderes Beispiel.
Wäre sehr dankbar dafür da es sehr wichtig ist für mich.

Danke schon mal im vorraus.
 

André Uhres

Top Contributor
SammY hat gesagt.:
...Gibs denn da vielleicht nicht noch ein anderes Beispiel...
Dies ist zwar kein anderes Beispiel, aber ein schlankeres:
Code:
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
public class MonitorDemo extends JFrame {
    public MonitorDemo() {
        super("Monitor Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(400,500));
        setLocationRelativeTo(null);
        Tester tester = new Tester();
        new Thread(tester).start();
        monitor = new Monitor(tester);
        getContentPane().add(monitor, BorderLayout.CENTER);
        Thread monitorThread = new Thread(monitor);
        monitorThread.setPriority(Thread.MIN_PRIORITY);
        monitorThread.start();
        
    }
    public static void main(String s[]){new MonitorDemo().setVisible(true);}
    private Monitor monitor;
}
class Monitor extends JPanel implements Runnable {
    private long sleepAmount = 1000;//wie oft aktualisiert wird (in Millisekunden)
    private int  usageHistCount = 400;// maximale Lauflänge der Graphik
    public Monitor(Object object) {
        this.object = object;
        setBackground(Color.black);
        usedMem = new float[usageHistCount];
        ptNum = 0;
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (big == null){
            Dimension d = getSize();
            if (d.width != w || d.height != h) {
                w = d.width;
                h = d.height;
                bimg = (BufferedImage) createImage(w, h);
                big = bimg.createGraphics();
                big.setFont(font);
                FontMetrics fm = big.getFontMetrics(font);
                ascent = (int) fm.getAscent();
                descent = (int) fm.getDescent();
            }
        }
        big.setBackground(getBackground());
        big.clearRect(0,0,w,h);
        plotMemoryUsage(w,h, ((Tester)object).getWert());
        g.drawImage(bimg, 0, 0, this);
    }
    public void plotMemoryUsage(int width, int height, float wert) {
        float usedMemory =  wert;
        float totalMemory =  500000f;// hier hab ich auch nur einen Testwert eingesetzt
        big.setColor(Color.green);
        // Print Max memory allocated for this memory pool.
        big.drawString(String.valueOf((int)totalMemory/1024) + "K Max ", 4.0f, ascent+0.5f);
        big.setColor(Color.yellow);
        big.drawString("Memory Monitor",  width/2, ascent+0.5f);// Print the memory pool name.
        // Print the memory used by this memory pool.
        usedStr = String.valueOf((int)usedMemory/1024)
        + "K used";
        big.setColor(Color.green);
        big.drawString(usedStr, 4, height-descent);
        // Calculate remaining size
        float ssH = ascent + descent;
        float remainingHeight = (float) (height - (ssH*2) - 0.5f);
        float blockHeight = remainingHeight/10;
        float blockWidth = 20.0f;
        float remainingWidth = (float) (width - blockWidth - 10);
        // .. Memory Free ..
        big.setColor(mfColor);
        int memUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);
        int i = 0;
        for ( ; i < memUsage ; i++) {
            mfRect.setRect(5,(float) ssH+i*blockHeight,
                    blockWidth,(float) blockHeight-1);
            big.fill(mfRect);
        }
        // .. Memory Used ..
        big.setColor(Color.green);
        for ( ; i < 10; i++)  {
            muRect.setRect(5,(float) ssH+i*blockHeight,
                    blockWidth,(float) blockHeight-1);
            big.fill(muRect);
        }
        // .. Draw History Graph ..
        if (remainingWidth <= 30) remainingWidth = (float)30;
        if (remainingHeight <= ssH) remainingHeight = (float)ssH;
        big.setColor(graphColor);
        int graphX = 30;
        int graphY = (int) ssH;
        int graphW = (int) remainingWidth;
        int graphH = (int) remainingHeight;
        graphOutlineRect.setRect(graphX, graphY, graphW, graphH);
        big.draw(graphOutlineRect);
        int graphRow = graphH/10;
        // .. Draw row ..
        for (int j = graphY; j <= graphH+graphY; j += graphRow) {
            graphLine.setLine(graphX,j,graphX+graphW,j);
            big.draw(graphLine);
        }
        // .. Draw animated column movement ..
        int graphColumn = graphW/15;
        if (columnInc == 0) {
            columnInc = graphColumn;
        }
        for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {
            graphLine.setLine(j,graphY,j,graphY+graphH);
            big.draw(graphLine);
        }
        --columnInc;
        // save memory usage history.
        usedMem[ptNum] = usedMemory;
        big.setColor(Color.yellow);
        int w1; // width of memory usage history.
        if (ptNum > graphW)  w1 = graphW;
        else                 w1 = ptNum;
        for (int j=graphX+graphW-w1, k=ptNum-w1; k < ptNum;
        k++, j++) {
            if (k != 0) {
                if (usedMem[k] != usedMem[k-1]) {
                    int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[k-1])/totalMemory));
                    int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[k])/totalMemory));
                    big.drawLine(j-1, h1, j, h2);
                } else {
                    int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[k])/totalMemory));
                    big.fillRect(j, h1, 1, 1);
                }
            }
        }
        if (ptNum+2 == usedMem.length) {
            // throw out oldest point
            for (int j = 1;j < ptNum; j++) {
                usedMem[j-1] = usedMem[j];
            }
            --ptNum;
        } else {
            ptNum++;
        }
    }
    public void run() {
        while (true) {
            repaint();
            try { Thread.sleep(sleepAmount); } catch (InterruptedException e) { break; }
        }
    }
    private Object object;
    private BufferedImage bimg;
    private Graphics2D big;
    private Font font = new Font("Times New Roman", Font.PLAIN, 11);
    private float usedMem[];
    private int w, h, ptNum, ascent, descent, columnInc;
    private Rectangle graphOutlineRect = new Rectangle();
    private Rectangle2D mfRect = new Rectangle2D.Float();
    private Rectangle2D muRect = new Rectangle2D.Float();
    private Line2D graphLine = new Line2D.Float();
    private Color graphColor = new Color(46, 139, 87);
    private Color mfColor = new Color(0, 100, 0);
    private String usedStr;
}
class Tester implements Runnable {// Test thread to consume memory
    public Tester() {}
    public void run() {
        int sign = 1;
        while(true){//Hier wird der testWert verändert (Testfunktion):
            try {Thread.sleep(100);} catch (Exception x){}
            if(testWert > 200000) sign = -1;
            if(testWert < 10000)  sign =  1;
            testWert += sign*1000;
        }
    }
    public float getWert(){
        return testWert;
    }
    private float testWert;
}
 

SammY

Bekanntes Mitglied
Also weitergebracht hats mich auf alle fälle aber ich weis halt noch nicht wie ich das umschreiben soll damit es nicht
vom Memory abhängig ist.

Bei mir soll die Kurve von einem Wert abhängig sein der sich jede sekunde ändert.
Hättest du vielleicht so ein Beispiel wo jede Sekunde ein Zufallswert errechnet wird und dann
in so einem Graphen dargestellt wird.

Danke.

Gruß Manuel.
 

André Uhres

Top Contributor
SammY hat gesagt.:
...Hättest du vielleicht so ein Beispiel wo jede Sekunde ein Zufallswert errechnet wird und dann
in so einem Graphen dargestellt wird...
Das Beispiel enthält die Klasse "Tester" die Testwerte simuliert. Die Variablennamen die das Wort "memory"
enthalten sind also nicht wörtlich zu nehmen.
Ich hab das Beispiel vor ein paar Minuten noch mal angepasst, am besten du kopierst es noch einmal neu vom Forum.
Gruß
André
 

SammY

Bekanntes Mitglied
Also so weit ich das jetzt verstanden habe muss ich nur die Klasse Tester auf meinen Wert anpassen und dann müsste es funktionieren oder??
 

André Uhres

Top Contributor
SammY hat gesagt.:
Also so weit ich das jetzt verstanden habe muss ich nur die Klasse Tester auf meinen Wert anpassen und dann müsste es funktionieren oder??
Genau. Die Klasse Tester generiert den zu überwachenden Wert.
Der Monitor holt sich diesen Wert mit der Methode Tester#getWert()[(i].
 

André Uhres

Top Contributor
..allerdings wird der Wert im Monitor noch mal angepasst, das muss du dann auch noch ändern:
Code:
...
        float totalMemory =  500000f;// hier hab ich auch nur einen Testwert eingesetzt
...
        big.drawString(String.valueOf((int)totalMemory/1024) + "K Max ", 4.0f, ascent+0.5f);
...
        usedStr = String.valueOf((int)usedMemory/1024)
...
 

SammY

Bekanntes Mitglied
Was ich noch nicht so ganz verstehe: Zeichnetst du die Linie mit drawString oder ist das nur ne Berechnung und dann die Ausgabe?
 

André Uhres

Top Contributor
Wenn das Programm läuft siehste oben links eine Zahl die den Maximalen Wert darstellt,
und unten links eine Zahl, die den aktuellen Wert darstellt.
Diese Zahlen und der Text daneben werden mit drawString(..) gezeichnet.
Die Graphik selbst natürlich nicht.
 

SammY

Bekanntes Mitglied
Ich hoff ich nerv dich nicht schon aber könntest du mir mal ein Beispiel geben wo nur die sich bewegende Linie ist ohne dem drumherum??
 

André Uhres

Top Contributor
SammY hat gesagt.:
Ich hoff ich nerv dich nicht schon ...
Nein, überhaupt nicht.
Hier ist die vereinfachte Version:
Code:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class MonitorDemo_1 extends JFrame {
    public MonitorDemo_1() {
        super("Monitor_1 Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,300);
        setLocationRelativeTo(null);
        Tester_1 tester = new Tester_1();
        new Thread(tester).start();
        monitor = new Monitor_1(tester);
        getContentPane().add(monitor, BorderLayout.CENTER);
        Thread monitorThread = new Thread(monitor);
        monitorThread.setPriority(Thread.MIN_PRIORITY);
        monitorThread.start();
    }
    public static void main(String s[]){new MonitorDemo_1().setVisible(true);}
    private Monitor_1 monitor;
}
class Monitor_1 extends JPanel implements Runnable {
    private long sleepAmount = 1000;//wie oft aktualisiert wird (in Millisekunden)
    private int  usageHistCount = 400;// maximale Lauflänge der Graphik
    public Monitor_1(Object object) {
        this.object = object;
        usedMem = new float[usageHistCount];
        ptNum = 0;
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (big == null){
            Dimension d = getSize();
            if (d.width != w || d.height != h) {
                w = d.width;
                h = d.height;
                bimg = (BufferedImage) createImage(w, h);
                big = bimg.createGraphics();
            }
        }
        big.clearRect(0,0,w,h);
        plotMemoryUsage(w,h, ((Tester_1)object).getWert());
        g.drawImage(bimg, 0, 0, this);
    }
    public void plotMemoryUsage(int width, int height, float wert) {
        float usedMemory =  wert;
        float totalMemory =  500000f;// hier hab ich auch nur einen Testwert eingesetzt
        // .. Draw History Graph ..
        int graphX = 0;
        int graphY = 0;
        int graphW = width;
        int graphH = height;
        usedMem[ptNum] = usedMemory; // save memory usage history.
        int w1; // width of memory usage history.
        if (ptNum > graphW)  w1 = graphW;
        else                 w1 = ptNum;
        for (int j=graphX+graphW-w1, k=ptNum-w1; k < ptNum;
        k++, j++) {
            if (k != 0) {
                if (usedMem[k] != usedMem[k-1]) {
                    int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[k-1])/totalMemory));
                    int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[k])/totalMemory));
                    big.drawLine(j-1, h1, j, h2);
                } else {
                    int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[k])/totalMemory));
                    big.fillRect(j, h1, 1, 1);
                }
            }
        }
        if (ptNum+2 == usedMem.length) {
            // throw out oldest point
            for (int j = 1;j < ptNum; j++) {
                usedMem[j-1] = usedMem[j];
            }
            --ptNum;
        } else {
            ptNum++;
        }
    }
    public void run() {
        while (true) {
            repaint();
            try { Thread.sleep(sleepAmount); } catch (InterruptedException e) { break; }
        }
    }
    private Object object;
    private BufferedImage bimg;
    private Graphics2D big;
    private float usedMem[];
    private int w, h, ptNum;
}
class Tester_1 implements Runnable {// Test thread to consume memory
    public Tester_1() {}
    public void run() {
        int sign = 1;
        while(true){//Hier wird der testWert verändert (Testfunktion):
            try {Thread.sleep(100);} catch (Exception x){}
            if(testWert > 200000) sign = -1;
            if(testWert < 10000)  sign =  1;
            testWert += sign*1000;
        }
    }
    public float getWert(){
        return testWert;
    }
    private float testWert;
}
 

SammY

Bekanntes Mitglied
Eine Frage hätte ich da noch und zwar kann ich das ganze in ein JInternalFrame machen.
Ich meine weil du erbst von JPanel.
Kann ich das durch JInternalFrame ersetzen :?:

MFG Manuel
 

André Uhres

Top Contributor
SammY hat gesagt.:
...kann ich das ganze in ein JInternalFrame machen...
Code:
...
    public MonitorDemo_1() {
...
//        getContentPane().add(monitor, BorderLayout.CENTER);
        JDesktopPane desktop = new JDesktopPane();
        JInternalFrame frame = new JInternalFrame();
        frame.setVisible(true);
        frame.setBounds(0,0,300,200);
        desktop.add(frame);
        frame.add(monitor, BorderLayout.CENTER);
        getContentPane().add(desktop);
...
}
...
 

SammY

Bekanntes Mitglied
Danke ich versuchs jetzt einfach mal.
Hab jetzt 10 Stunden zeit das hin zu bekommen.

Danke für deine Hilfe. :toll:
 

SammY

Bekanntes Mitglied
Ich hab mein Problem jetzt gelöst.
Aber wie schauts denn eigentlích mit der Performance aus??

Kann das sein das der ablauf mit der zeit langsamer wird??
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben