[英]swing drawing and threads
我正在嘗試創建一個簡單的波形可視化器,我的問題是使用擺動繪制線來協調線程。 我已經將部分代碼划分為執行數學運算的外部線程和揮桿線程來畫線。 由於某種原因,我無法使代碼正常工作,但是如果我調用getGraphics(),即使它跳動了很多,也可以看到一些行。
package it.pievis.GUI;
import it.pievis.utils.BackgroundExecutor;
import it.pievis.utils.Utils;
public class WaveformFrame extends JFrame {
private int WIDTH = 450;
private int HEIGHT = 100;
private JLabel testLbl = new JLabel();
private WaveformPanel wfp;
public WaveformFrame() {
super();
setSize(WIDTH, HEIGHT+20);
setTitle("Waveform Frame");
setName("Main FRAME");
JPanel container = new JPanel();
wfp = new WaveformPanel();
wfp.setSize(WIDTH, HEIGHT);
wfp.setName("Waveform PANEL");
add(wfp);
}
public void updateWave(byte[] pcmdata)
{
wfp.updateWave(pcmdata);
}
class WaveformPanel extends JPanel
{
byte[] pcmdata = null;
/**
* Refresh the wave every times a new pcmdata arrives
*/
public void updateWave(byte[] pcmdata)
{
log("pcmdata received");
this.pcmdata = pcmdata;
}
/**
* Handle the refresh of the waveform
* @param g
*/
private void doDrawing(Graphics g){
//log("ThreadSwing: " + Thread.currentThread());
Graphics2D g2d = (Graphics2D) g;
log( g2d.hashCode() + " drawing");
int HEIGHT = getHeight();
int WIDTH = getWidth();
if(pcmdata == null){
//Render a straight line
g2d.drawLine(0, HEIGHT/2, WIDTH, HEIGHT/2);
return;
}
//Let swing handle the drawing
BackgroundExecutor.get().execute(new WaveformTask(g2d, WIDTH, HEIGHT));
}
class WaveformTask implements Runnable
{
Graphics2D g2d;
int HEIGHT;
int WIDTH;
int val0;
int val1;
int diffx0;
int diffx1;
public WaveformTask(Graphics2D g2d, int width, int height) {
this.g2d = g2d;
HEIGHT = height;
WIDTH = width;
}
@Override
public void run() {
float scale = (float) HEIGHT/65536;
int nlines = pcmdata.length/4;
float lineLen = (float) WIDTH/(nlines-1);
ArrayList<Line2D.Float> lines = new ArrayList<Line2D.Float>();
for(int i = 0; i < nlines-4; i+=4){
int sample0 = Utils.getSixteenBitSample(pcmdata[i+1], pcmdata[i]);
int sample1 = Utils.getSixteenBitSample(pcmdata[i+3], pcmdata[i+2]);
int val0 = (int) (sample0*scale)+HEIGHT/2;
int val1 = (int) (sample1*scale)+HEIGHT/2;
int diffx0 = Math.round(lineLen*i);
int diffx1 = Math.round(lineLen*i+1);
lines.add(new Line2D.Float(diffx0, val0, diffx1, val1));
//log("Updated GUI ( " + sumData + ") " + lineLen + " " + WIDTH + " " + HEIGHT + " nlines: " +nlines + " Scale: "+scale );
//Let swing handle the drawing
}
//log("Thread0: " + Thread.currentThread());
SwingUtilities.invokeLater(new drawLinesTask(g2d,lines));
}
}
/**
* This task draws lines on screen
*/
class drawLinesTask implements Runnable
{
ArrayList<Line2D.Float> lines;
Graphics2D g2d;
public drawLinesTask(Graphics2D g2d, ArrayList<Line2D.Float> lines) {
this.g2d = g2d;
this.lines = lines;
}
@Override
public void run() {
//IF I UNCOMMENT THIS IT SORTA WORKS
//g2d = (Graphics2D) getGraphics();
log( g2d.hashCode() + " run " + getName());
for(Line2D.Float line : lines)
{
g2d.draw(line);
}
//log("Thread: " + Thread.currentThread());
log("lines have been drawn");
getContentPane().repaint();
}
}
/**
* Called each time the UI is rendered
*/
/**
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}*/
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
/// END OF JPANEL CLASS
}
我不知道為什么它不起作用,我做了一些測試,發現圖形組件是相同的,實際上我正在Jpanel和swing線程中工作。 我不明白為什么通過這種方式看不到任何東西,但是如果我使用getGraphics然后我重復,就會出現一些提示。 很抱歉,很長的代碼塊,希望有人能幫助我了解發生了什么。
對於任何有興趣的人,這是我的工作代碼,這要歸功於注釋者,使我能夠正常工作:
打包it.pievis.GUI;
公共類WaveformFrame擴展了JFrame {
private int WIDTH = 450;
private int HEIGHT = 100;
private WaveformPanel wfp;
private ArrayList<Line2D.Float> lines;
public WaveformFrame() {
super();
setSize(WIDTH, HEIGHT+20);
setTitle("Waveform Frame");
setName("Main FRAME");
wfp = new WaveformPanel();
wfp.setSize(WIDTH, HEIGHT);
wfp.setName("Waveform PANEL");
add(wfp);
}
public void updateWave(byte[] pcmdata)
{
wfp.updateWave(pcmdata);
//wfp.doDrawing(getGraphics());
//repaint();
}
class WaveformPanel extends JPanel
{
byte[] pcmdata = null;
/**
* Refresh the wave every times a new pcmdata arrives
*/
public void updateWave(byte[] pcmdata)
{
//log("pcmdata received");
this.pcmdata = pcmdata;
doDrawing(getGraphics());
repaint();
}
/**
* Handle the refresh of the waveform
* @param g
*/
private void doDrawing(Graphics g){
//log("ThreadSwing: " + Thread.currentThread());
Graphics2D g2d = (Graphics2D) g;
int HEIGHT = getHeight();
int WIDTH = getWidth();
if(pcmdata == null){
//Render a straight line
g2d.drawLine(0, HEIGHT/2, WIDTH, HEIGHT/2);
//g2d.drawLine(0, 0, WIDTH, HEIGHT);
return;
}
/*
float scale = (float) HEIGHT/65536;
int nlines = pcmdata.length/2;
float lineLen = (float) WIDTH/(nlines-1);
if(lineLen < 1)
lineLen = 1;
int sumData = 0;
for(int i = 0; i < nlines-2; i+=2){
int sample0 = Utils.getSixteenBitSample(pcmdata[i+1], pcmdata[i]);
int sample1 = Utils.getSixteenBitSample(pcmdata[i+3], pcmdata[i+2]);
int val0 = (int) (sample0*scale)+HEIGHT/2;
int val1 = (int) (sample1*scale)+HEIGHT/2;
int diffx0 = Math.round(lineLen*i);
int diffx1 = Math.round(lineLen*i+2);
g2d.drawLine(diffx0, val0, diffx1, val1);
log("- x0 " + diffx0 + " y " + val0);
sumData = val0 + val1;
//log("Updated GUI ( " + sumData + ") " + lineLen + " " + WIDTH + " " + HEIGHT + " nlines: " +nlines + " Scale: "+scale );
}
*/
//Let swing handle the drawing
BackgroundExecutor.get().execute(new WaveformTask(WIDTH, HEIGHT));
//Let swing handle the drawing
if(lines != null){
//SwingUtilities.invokeLater(new drawLinesTask(g2d));
//(new drawLinesTask(g2d)).run();
drawLines(g2d);
//repaint();
}
}
class WaveformTask implements Runnable
{
Graphics2D g2d;
int HEIGHT;
int WIDTH;
public WaveformTask(int width, int height) {
HEIGHT = height;
WIDTH = width;
}
@Override
public void run() {
calcLine2d();
//log("Thread0: " + Thread.currentThread());
}
void calcLine2d(){
float scale = (float) HEIGHT/65536;
int nlines = pcmdata.length/4;
float lineLen = (float) WIDTH/(nlines-1);
//Don't wanna work on the original thread
ArrayList<Line2D.Float> lines = new ArrayList<Line2D.Float>();
for(int i = 0; i < nlines-4; i+=4){
int sample0 = Utils.getSixteenBitSample(pcmdata[i+1], pcmdata[i]);
int sample1 = Utils.getSixteenBitSample(pcmdata[i+3], pcmdata[i+2]);
int val0 = (int) (sample0*scale)+HEIGHT/2;
int val1 = (int) (sample1*scale)+HEIGHT/2;
int diffx0 = Math.round(lineLen*i);
int diffx1 = Math.round(lineLen*i+1);
lines.add(new Line2D.Float(diffx0, val0, diffx1, val1));
//log("Updated GUI ( " + sumData + ") " + lineLen + " " + WIDTH + " " + HEIGHT + " nlines: " +nlines + " Scale: "+scale );
}
synchronized (this) {
WaveformFrame.this.lines = lines;
}
}
}
/**
* This should draw lines
* @param g2d
*/
synchronized void drawLines(Graphics2D g2d)
{
for(Line2D.Float line : lines)
{
g2d.draw(line);
}
//log("lines have been drawn");
repaint();
}
/**
* Called each time the UI is rendered
*/
/**
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}*/
@Override
public void paint(Graphics g) {
super.paint(g);
doDrawing(g);
}
}
/// END OF JPANEL CLASS
private void log(String line)
{
System.out.println("GUI out] " + line);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.