gpt4 book ai didi

java - 尽管我使用了 Swing Timer,但在 JPanel 上从动画绘制 Wave 时 GUI 卡住

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:30:39 26 4
gpt4 key购买 nike

请查看我的代码片段,它有什么问题,当 Swing 计时器统计信息重复绘制在 jpnael 上时,它会卡住 GUI ??

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。当动画开始时,它不会绘制任何东西,但会卡住。请给我解决方案。

谢谢米希尔·帕克

最佳答案

java.swingx.TimerEDT 中调用 ActionPerformed。接下来的问题是,什么需要时间来渲染。这可能是对 captureThread.getTempBuffer 的调用,也可能是帮助的构建,但我怀疑这只是您尝试绘制的数据共享量。

最近在玩这个,处理波形需要相当多的时间。

一个建议可能是减少绘制的样本数量。与其绘制每个样本点,不如根据组件的宽度每隔一秒或第四个样本点绘制一次。你仍然应该得到同样的笑话,但没有所有的工作......

已更新

所有样本,2.18 秒

AllSamples

每 4 个样本,0.711 秒

enter image description here

每第 8 个样本,0.450 秒

enter image description here

与其响应计时器进行绘制,也许您需要响应批量数据进行绘制。

由于您的加载程序线程有一个数据“ block ”,因此可能会绘制它。

正如 HoverCraftFullOfEels 所建议的,您可以先将其绘制到 BufferedImage,然后再将其绘制到屏幕...

SwingWorker或许可以为您实现这一目标

已更新

这是我用来绘制上述示例的代码。

// Samples is a 2D int array (int[][]), where the first index is the channel, the second is the sample for that channel
if (samples != null) {

Graphics2D g2d = (Graphics2D) g;

int length = samples[0].length;

int width = getWidth() - 1;
int height = getHeight() - 1;

int oldX = 0;
int oldY = height / 2;
int frame = 0;

// min, max is the min/max range of the samples, ie the highest and lowest samples
int range = max + (min * -2);
float scale = (float) height / (float) range;

int minY = Math.round(((height / 2) + (min * scale)));
int maxY = Math.round(((height / 2) + (max * scale)));

LinearGradientPaint lgp = new LinearGradientPaint(
new Point2D.Float(0, minY),
new Point2D.Float(0, maxY),
new float[]{0f, 0.5f, 1f},
new Color[]{Color.BLUE, Color.RED, Color.BLUE});
g2d.setPaint(lgp);
for (int sample : samples[0]) {

if (sample % 64 == 0) {

int x = Math.round(((float) frame / (float) length) * width);
int y = Math.round((height / 2) + (sample * scale));

g2d.drawLine(oldX, oldY, x, y);

oldX = x;
oldY = y;

}

frame++;

}

}

我使用 AudioStream 流加载 Wav 文件并生成 2D 样本。

关于java - 尽管我使用了 Swing Timer,但在 JPanel 上从动画绘制 Wave 时 GUI 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12066698/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com