Java I';我重写了paintComponent(),那么为什么不';我的形状没有出现吗?

Java I';我重写了paintComponent(),那么为什么不';我的形状没有出现吗?,java,swing,awt,event-dispatch-thread,jcomponent,Java,Swing,Awt,Event Dispatch Thread,Jcomponent,我在玩弄awt图形,一开始我设法得到了我想要的一切,但在清理完代码后,突然除了一个带有JPanel的空框架外,什么也没有出现 这可能是显而易见的,但我不明白为什么我的形状不再出现了。我做错了什么 公共类主{ 公共静态void main(字符串[]args){ invokeLater(新的Runnable(){ @凌驾 公开募捐{ 新游戏().setVisible(true); } }); } } import javax.swing.*; 导入java.awt.*; 导入java.awt.ge

我在玩弄awt图形,一开始我设法得到了我想要的一切,但在清理完代码后,突然除了一个带有JPanel的空框架外,什么也没有出现

这可能是显而易见的,但我不明白为什么我的形状不再出现了。我做错了什么

公共类主{
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
新游戏().setVisible(true);
}
});
}
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.geom.Rectangle2D;
导入java.awt.geom.RoundRectangle2D;
导入java.util.ArrayDeque;
导入java.util.NoSuchElementException;
公共类GameCanvas扩展画布实现可运行{
私有最终整数fps=24;//fps
专用圆形矩形2D rr;
私有字符串文本;
私人浮动阿尔法;
专用浮点alphaDelta=0.05f;//Alpha衰减速度
private javax.swing.Timer Timer=新计时器(1000/fps,a->repaint());
private java.util.Queue textQueue;//包含文本行
公共游戏画布(){
setFont(新字体(“OCR A扩展”,Font.BOLD,20));
//介绍文本
textQueue=new ArrayDeque();
添加(“欢迎来到丛林!”);
添加(“我们有乐趣和游戏。”);
//圆形矩形
int弧=10;
整数高度=(整数)(Game.height*0.2);
int-width=(int)(Game.width-Game.width*0.1);/(int)(Game.width-Game.width*0.5);
intx=Game.width/2-width/2-10;
int y=(int)(游戏高度-高度*1.5);
rr=新的圆形矩形2D.Double(x、y、宽度、高度、圆弧、圆弧);
this.text=textQueue.remove();
线程=新线程(此);//淡入线程
thread.start();
timer.start();
}
@凌驾
公共空间涂料(图g){
超级油漆(g);
图形2d g2=(图形2d)g;
//设置组件alpha
//setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));
//绘制圆形矩形
g2.挫折背景(颜色:深灰色);
g2.填充(rr);
//绘制文本
最终FontMetrics fm=g2.getFontMetrics();
矩形2D textBounds=fm.getStringBounds(文本,g2);
g2.设置颜色(颜色为白色);
g2.drawString(text,(float)(rr.getCenterX()-(textBounds.getWidth()/2)),(float)(rr.getCenterY()+textBounds.getHeight()/2));
g2.设置颜色(颜色:深灰色);
}
@凌驾
公开募捐{
while(true){
如果(α>=0){
α+=αδ;
}
如果(α<0){
α=0;
试一试{
this.text=textQueue.remove();
}捕获(无接触元素例外){
timer.stop();
}
αδ*=-1;
}否则如果(α>=1){
α=1;
αδ*=-1;
//全速睡眠1秒钟
试一试{
睡眠(1000);
}捕获(中断异常例外){
例如printStackTrace();
}
}
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}

这是因为您的
gamePanel
没有用组件填充面板的
LayoutManager
(默认情况下,它使用
FlowLayout
)。为了看到一些东西,将其更改为
JPanel gamePanel=newjpanel(newborderlayout())


但是,在
计时器的操作中,您可以
线程.sleep()
。这将冻结整个GUI,因为
计时器
的操作侦听器在事件调度线程中运行,这是一个不应
睡眠的
线程。相反,您可以使用第二个
计时器
或某种类型的o标志变量,或者使用
SwingWorker

我将gamePanel改为新的类扩展画布。给了它一个计时器,但只是重新绘制,还给了它一个单独的线程,可以运行alpha褪色,现在所有的睡眠都在该运行中。但是现在它只绘制第一帧,没有其他内容。@r.r您应该创建另一个关于此的问题,包括所有细节。如果我的回答帮助了你,请考虑。@ R.R把GAMEPANEL换成了一个新的扩展画布的类——你不应该使用Caves。在Swing中使用JPanel(或JComponent)进行自定义绘制。问题是您没有重写自定义类的
getPreferredSize()
方法。所有Swing组件的任务是提供布局管理器可以使用的首选大小。FlowLayout尊重首选的大小,但由于您没有指定一个,因此没有任何可绘制的内容。@camickr感谢您提供的提示。我正在第四次(或第五次?)尝试扩展JPanel(最初是为了消除JPanel附带的双缓冲的闪烁)。我很难找到最佳实践的好来源。我应该什么时候使用画布?只调用repaint()的计时器什么也不做。在重新绘制()之前,需要调用一些更改组件属性的代码。@camickr这很有意义。我已经注释掉了paint()函数中唯一一行实际上发生了变化,那就是setComposite(alpha)行。
public class Game extends JFrame {
    static int width = 500;
    static int height = 500;

    public Game() {
        this.setPreferredSize(new Dimension(width, height));
        JPanel menuPanel = new JPanel(); // Menypanel
        JPanel filmPanel = new JPanel(); // Filmpanel
        JPanel gamePanel = new JPanel(); // Spelpanel
        gamePanel.setBackground(Color.WHITE);

        // Intro texts
        Queue<String> intro = new ArrayDeque<>();
        intro.add("Welcome to the jungle!");
        intro.add("We've got fun and games.");
        FadingTextBox introBox = new FadingTextBox(intro);
        gamePanel.add(introBox);

        getContentPane().add(gamePanel);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        pack();
    }
}
class FadingTextBox extends JComponent implements ActionListener {
    private RoundRectangle2D rr;
    private String text = "";
    private float alpha;
    private float alphaDelta = 0.05f; // Alpha fade speed
    private final int fps = 60;  // FPS
    private javax.swing.Timer timer = new Timer(1000 / fps, this);
    private java.util.Queue<String> textQueue; // Contains lines of texts

    public FadingTextBox(java.util.Queue<String> textQueue) {
        this.textQueue = textQueue;
        this.setFont(new Font("OCR A EXTENDED", Font.BOLD, 24));

        int arc = 10;
        int height = (int) (Game.height * 0.2);
        int width = (int) (Game.width - Game.width * 0.1);
        int x = Game.width / 2 - width / 2;
        int y = (int) (Game.height - height * 1.5);

        rr = new RoundRectangle2D.Double(x, y, width, height, arc, arc);

        setText(textQueue.remove());
        timer.start();
    }

    private void setText(String text) {
        this.text = text;
    }

    boolean isRunning() {
        return timer.isRunning();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        // Set component alpha
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));

        // Draw RoundRectangle
        g2.setBackground(Color.DARK_GRAY);
        g2.fill(rr);

        // Draw text
//        g2.setColor(Color.BLUE);
        final FontMetrics fm = g.getFontMetrics();
        Rectangle2D textBounds = fm.getStringBounds(text, g2);
        g2.drawString(text, (float) (rr.getCenterX() - (textBounds.getWidth() / 2)), (float) (rr.getCenterY() + textBounds.getHeight() / 2));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (alpha >= 0) {
            alpha += alphaDelta;
        }
        if (alpha < 0) {
            alpha = 0;
            try {
                setText(textQueue.remove());
            } catch (NoSuchElementException ex) {
                timer.stop();
            }
            alphaDelta *= -1;
        } else if (alpha >= 1) {
            alpha = 1;
            alphaDelta *= -1;

            // Sleep 1 sec on full alpha
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        repaint();
    }
}
public class Game extends JFrame {
    ...
    GameCanvas gameCanvas;

    public Game() {
        ...
        gameCanvas = new GameCanvas(); // Spelpanel
        getContentPane().add(gameCanvas);
        ...
        pack();
    }
}
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayDeque;
import java.util.NoSuchElementException;

public class GameCanvas extends Canvas implements Runnable {
    private final int fps = 24;  // FPS
    private RoundRectangle2D rr;
    private String text;
    private float alpha;
    private float alphaDelta = 0.05f; // Alpha fade speed
    private javax.swing.Timer timer = new Timer(1000 / fps, a -> repaint());
    private java.util.Queue<String> textQueue; // Contains lines of texts

    public GameCanvas() {
        this.setFont(new Font("OCR A EXTENDED", Font.BOLD, 20));
        // Intro texts
        textQueue = new ArrayDeque<>();
        textQueue.add("Welcome to the jungle!");
        textQueue.add("We've got fun and games.");

        // RoundRectangle
        int arc = 10;
        int height = (int) (Game.height * 0.2);
        int width = (int) (Game.width - Game.width * 0.1);// (int) (Game.width - Game.width * 0.5);
        int x = Game.width / 2 - width / 2 - 10;
        int y = (int) (Game.height - height * 1.5);
        rr = new RoundRectangle2D.Double(x, y, width, height, arc, arc);

        this.text = textQueue.remove();
        Thread thread = new Thread(this);  // Fade thread
        thread.start();
        timer.start();

    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;

        // Set component alpha

//        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));

        // Draw RoundRectangle
        g2.setBackground(Color.DARK_GRAY);
        g2.fill(rr);

        // Draw text
        final FontMetrics fm = g2.getFontMetrics();
        Rectangle2D textBounds = fm.getStringBounds(text, g2);
        g2.setColor(Color.WHITE);
        g2.drawString(text, (float) (rr.getCenterX() - (textBounds.getWidth() / 2)), (float) (rr.getCenterY() + textBounds.getHeight() / 2));
        g2.setColor(Color.DARK_GRAY);
    }

    @Override
    public void run() {
        while (true) {
            if (alpha >= 0) {
                alpha += alphaDelta;
            }
            if (alpha < 0) {
                alpha = 0;
                try {
                    this.text = textQueue.remove();
                } catch (NoSuchElementException ex) {
                    timer.stop();
                }
                alphaDelta *= -1;
            } else if (alpha >= 1) {
                alpha = 1;
                alphaDelta *= -1;

                // Sleep 1 sec on full alpha
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}