plese look at my code snippets , wha is wrong with it , it frrezes GUI when the Swing timer stats which is repeteadly paints on the jpnael ??
class WaveformPanel extends JPanel {
Timer graphTimer = null;
AudioInfo helper = null;
WaveformPanel() {
setPreferredSize(new Dimension(200, 80));
setBorder(BorderFactory.createLineBorder(Color.BLACK));
graphTimer = new Timer(15, new TimerDrawing());
}
/**
*
*/
private static final long serialVersionUID = 969991141812736791L;
protected final Color BACKGROUND_COLOR = Color.white;
protected final Color REFERENCE_LINE_COLOR = Color.black;
protected final Color WAVEFORM_COLOR = Color.red;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int lineHeight = getHeight() / 2;
g.setColor(REFERENCE_LINE_COLOR);
g.drawLine(0, lineHeight, (int) getWidth(), lineHeight);
if (helper == null) {
return;
}
drawWaveform(g, helper.getAudio(0));
}
protected void drawWaveform(Graphics g, int[] samples) {
if (samples == null) {
return;
}
int oldX = 0;
int oldY = (int) (getHeight() / 2);
int xIndex = 0;
int increment = helper.getIncrement(helper
.getXScaleFactor(getWidth()));
g.setColor(WAVEFORM_COLOR);
int t = 0;
for (t = 0; t < increment; t += increment) {
g.drawLine(oldX, oldY, xIndex, oldY);
xIndex++;
oldX = xIndex;
}
for (; t < samples.length; t += increment) {
double scaleFactor = helper.getYScaleFactor(getHeight());
double scaledSample = samples[t] * scaleFactor;
int y = (int) ((getHeight() / 2) - (scaledSample));
g.drawLine(oldX, oldY, xIndex, y);
xIndex++;
oldX = xIndex;
oldY = y;
}
}
public void setAnimation(boolean turnon) {
if (turnon) {
graphTimer.start();
} else {
graphTimer.stop();
}
}
class TimerDrawing implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
byte[] bytes = captureThread.getTempBuffer();
if (helper != null) {
helper.setBytes(bytes);
} else {
helper = new AudioInfo(bytes);
}
repaint();
}
}
}
I am calling setAnimation of WaveFormPanel from its parent class.when animation starts it does not draw anything but freezes. please , give me solution.
Thank You Mihir Parekh
The
java.swingx.Timer
calls theActionPerformed
within theEDT
. The question then is, what's taking the time to render. It could be the call tocaptureThread.getTempBuffer
it could be the construction of the help, but I suspect it's just the share amount of data you are trying to paint.Having playing with this recently, it takes quite a bit of time to process the waveform.
One suggestion might be to reduce the number of samples that you paint. Rather then painting each one, maybe paint every second or forth sample point depending on the width of the component. You should still get the same jest but without all the work...
UPDATED
All samples, 2.18 seconds
Every 4th sample, 0.711 seconds
Every 8th sample, 0.450 seconds
Rather then paint in response to the timer, maybe you need to paint in response to batches of data.
As your loader thread has a "chunk" of data, may be paint it then.
As HoverCraftFullOfEels suggested, you could paint this to a BufferedImage first and then paint that to the screen...
SwingWorker might be able to achieve this for you
UPDATED
This is the code I use to paint the above samples.
I use an
AudioStream
stream to load a Wav file an produce the 2D samples.I'm guessing that your wave drawing code, which is being called from within a
paintComponent(...)
method is taking longer than you think and is tying up both Swing painting and the EDT.If this were my code, I'd consider drawing my waves to BufferedImages once, making ImageIcons from these images and then simply swapping icons in my Swing Timer.