我试图创建一个简单的波形可视化工具,我的问题是使用swing来绘制线条来协调线程。我在执行数学运算的外部线程和绘制线条的swing线程之间划分了部分代码。出于某种原因,我无法使代码工作,但是如果我调用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上工作并在摇摆线程。我不明白为什么通过这样做什么都看不到,但如果我使用getGraphics然后我重复,一些东西出现和轻弹。 对于长长的代码块感到抱歉,我希望有人可以帮助我理解正在发生的事情。
答案 0 :(得分:0)
对于任何感兴趣的人,这是我的工作代码,感谢评论者我能够让这个工作:
打包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);
}
}