gpt4 book ai didi

Java JLayeredPane 内容在刷新时闪烁

转载 作者:行者123 更新时间:2023-11-30 11:23:40 25 4
gpt4 key购买 nike

我在 NetBeans 中有一个项目,它使用分层 Pane 通过在必要时在它们之间切换来显示重叠的面板。启动时,程序会在其中一个面板上显示介绍动画(在单独的线程上运行),通过以下方式实现:

public class IntroPanel extends javax.swing.JPanel implements Runnable {

private boolean finished;
private int opacity;
private JLabel[] labels = new JLabel[3];

public IntroPanel() {
initComponents();
labels[0] = jLabel1;
labels[1] = jLabel2;
labels[2] = jLabel3;
}

@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
for(JLabel label : labels)
label.setForeground(new Color(200,200,200,opacity));
}

@Override
public void run(){
while (!finished) {
while (opacity < 255) {
try {
Thread.sleep(30);
opacity += 5;
repaint();
} catch (InterruptedException ex) {
Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
repaint();
Thread.sleep(3000);
} catch (InterruptedException ex) {
Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex);
}
while (opacity > 0) {
try {
Thread.sleep(30);
opacity -= 5;
repaint();
} catch (InterruptedException ex) {
Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex);
}
finished = true;
}
}

预期效果是让三个 JLabel 淡入,在屏幕上停留片刻,然后淡出。前两个标签包含大字体的斜体文本,第三个包含小字体。这里的问题:

  1. 前两个标签的文本在淡入或淡出时显示为非斜体,仅在标签未淡出时短暂变为斜体。
  2. 第三个标签(小字体、非斜体的标签)根本不会褪色,而是在重绘循环期间快速上下“摇晃”。

我读到如何编写我自己的主动渲染方法而不是使用 paintComponent() 而是用以下内容替换 paintComponent() 是一个更好的主意:

public void render() {
Graphics g = getGraphics();
for(JLabel label : labels)
label.setForeground(new Color(200,200,200,opacity));
g.dispose();
}

做同样的闪烁。我是不是遗漏了什么,或者循环重绘和分层框架只是不混合?

最佳答案

  1. 您不应在该方法内执行您的 paintComponent 中的任何代码。那应该在你程序的另一个区域。 paintComponent 仅用于绘制,不用于设置状态。
  2. 您的 while 循环应该被 Swing Timer 代替,这就是 setForground 调用应该去的地方。
  3. 你应该发布一个最小的,complete valid, example, a small program我们可以编译运行和测试。您的代码不允许这样做。

例如:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class IntroPanel extends JPanel {
private static final int DELAY_TIME = 5;
protected static final Color FG_COLOR = Color.blue;
private List<JLabel> labelList = new ArrayList<JLabel>();
private List<Color> colorList = new ArrayList<>();

public IntroPanel() {
for (int i = 0; i < 255; i++) {
colorList.add(new Color(0, 0, 255, i));
}
for (int i = 0; i < 255; i++) {
colorList.add(new Color(0, 0, 255, 255 - i));
}

setLayout(new GridLayout(0, 1));

JLabel label1 = new JLabel("Label 1");
label1.setFont(label1.getFont().deriveFont(Font.ITALIC, 24));
add(label1);
labelList.add(label1);
JLabel label2 = new JLabel("Label 2");
label2.setFont(label2.getFont().deriveFont(Font.ITALIC, 24));
add(label2);
labelList.add(label2);
JLabel label3 = new JLabel("Label 3");
label3.setFont(label3.getFont().deriveFont(Font.PLAIN, 10));
add(label3);
labelList.add(label3);

new Timer(DELAY_TIME, new ActionListener() {
private int index = 0;

@Override
public void actionPerformed(ActionEvent evt) {
if (index < colorList.size()) {
for (JLabel label : labelList) {
label.setForeground(colorList.get(index));
}
index++;
} else {
((Timer)evt.getSource()).stop();
}
}
}).start();
}

private static void createAndShowGUI() {
IntroPanel paintEg = new IntroPanel();

JFrame frame = new JFrame("IntroPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

关于Java JLayeredPane 内容在刷新时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21064702/

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