有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在手动调整窗口大小之前,swing Java窗口无法正确重新绘制

我使用了一个非常基本的设置,一个扩展了JPanel的类,我将它添加到了JFrame

import java.awt.*;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;

public class PinTestMCVE extends JPanel implements ActionListener{

    BufferedImage loadedImage;
    JButton calcButton;

    public static void main(String[] args) {
        new PinTestMCVE();
    }

    public PinTestMCVE() {
        loadedImage = getTestImage();

        JPanel toolbarPanel = new JPanel();
        calcButton = new JButton("calcButton...");
        toolbarPanel.add(calcButton);
        calcButton.addActionListener(this);

        JFrame jf = new JFrame();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.getContentPane().setLayout(new BorderLayout()); 
        jf.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
        jf.getContentPane().add(this, BorderLayout.CENTER);
        jf.setSize(1250, 950);
        jf.setVisible(true);
    }

    public void paintComponent(Graphics g) {
        g.drawImage(loadedImage, 0, 0, this);
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("ActionEvent " + e.getActionCommand());
        if(e.getSource().equals(calcButton)){
            this.repaint();
        }
    }


//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
    BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = image.createGraphics();
    g2d.setPaint(Color.GRAY);
    g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setPaint(Color.gray);
    int x = 5;
    int y = 7;
    GradientPaint redtowhite = new GradientPaint(x, y, Color.red, 200, y, Color.blue);
    g2d.setPaint(redtowhite);
    g2d.fill(new RoundRectangle2D.Double(x, y, 200, 200, 10, 10));
    return image;
}
}

所发生的事情是,最初窗口是正确绘制的,但一旦调用paintComponent,在新绘制的图像下方就可以看到一条旧图像(与工具栏面板的高度相同)——类似于从扑克牌组中伸出的扑克牌。但是,如果我手动调整窗口的大小,比如拖动边框,背景会像应该的那样变灰

发生了什么,我该如何解决


共 (1) 个答案

  1. # 1 楼答案

    here所述,在调用setVisible()之前需要pack()帧。您可以重写^{}以指定合适的初始Dimension。还考虑使用^ {< CD5> }。另见Initial Threads

    image

    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.*;
    
    public class PinTestMCVE extends JPanel implements ActionListener{
    
        private static final int SIZE = 200;
        BufferedImage loadedImage;
        JButton calcButton;
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new PinTestMCVE();
                }
            });
        }
    
        public PinTestMCVE() {
            loadedImage = getTestImage();
            JPanel toolbarPanel = new JPanel();
            calcButton = new JButton("calcButton...");
            toolbarPanel.add(calcButton);
            calcButton.addActionListener(this);
    
            JFrame jf = new JFrame();
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.add(toolbarPanel, BorderLayout.NORTH);
            jf.add(this, BorderLayout.CENTER);
            jf.pack();
            jf.setLocationRelativeTo(null);
            jf.setVisible(true);
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(SIZE, SIZE);
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(loadedImage, 0, 0, this);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("ActionEvent " + e.getActionCommand());
            if(e.getSource().equals(calcButton)){
                this.repaint();
            }
        }
    
    
        //Please ignore the inner workings of this
        public static BufferedImage getTestImage(){
            BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();
            g2d.setPaint(Color.GRAY);
            g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setPaint(Color.gray);
            GradientPaint redtowhite = new GradientPaint(5, 5, Color.red, SIZE, 5, Color.blue);
            g2d.setPaint(redtowhite);
            g2d.fill(new RoundRectangle2D.Double(5, 5, SIZE - 10, SIZE - 10, 10, 10));
            return image;
        }
    }