请看看我的代码片段,它是错的,它frrezes GUI时,Swing定时器统计是repeteadly油漆的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();
}
}
}
我从它的父类调用WaveFormPanel的setAnimation。当动画开始时,它不会绘制任何东西,但会冻结。请给予我解决方案。
感谢您的评分
2条答案
按热度按时间tp5buhyn1#
java.swingx.Timer
在EDT
中调用ActionPerformed
。问题是,是什么花了时间来渲染。可能是对captureThread.getTempBuffer
的调用,也可能是帮助的构造,但我怀疑这只是你试图绘制的数据量。最近玩过这个,它需要相当多的时间来处理波形。
一个建议可能是减少你绘制的样本数量。而不是绘制每一个,也许根据组件的宽度每第二个或第四个样本点绘制一次。你应该仍然得到相同的jist,但没有所有的工作...
已更新
所有样本,2.18秒
每4个样本,0.711秒
每8个样本,0.450秒
也许您需要绘制响应批量数据的图形,而不是响应计时器的图形。
因为你的加载器线程有一个“大块”的数据,所以可以绘制它。
正如HoverCraftFullOfEels所建议的,您可以先将此绘制到BufferedImage,然后再将其绘制到屏幕上......
SwingWorker可以为您实现这一点
已更新
这是我用来绘制上述示例的代码。
我使用
AudioStream
流来加载Wav文件并生成2D样本。unftdfkk2#
我猜您的wave绘制代码(从
paintComponent(...)
方法中调用)花费的时间比您想象的要长,并且占用了Swing绘制和EDT。如果这是我的代码,我会考虑将我的waves绘制到BufferedImages * 一次 *,从这些图像中制作ImageIcons,然后在我的Swing Timer中简单地交换图标。