简体   繁体   English

是否通过validate(),revalidate()或paint()调用JComponent的paint(Graphics g)方法?

[英]JComponent's paint(Graphics g) method is being called by validate(), revalidate(), or paint()?

I haven't made a Java Swing app for a while (2+ years), so excuse me for any silly mistake. 我有一段时间没有制作Java Swing应用程序(2年以上),所以请原谅我任何愚蠢的错误。

I want to upload some artwork , that will be displayed as full screen image. 我想上传一些艺术品,它们将显示为全屏图像。

The problem I'm having is that the JComponent, that I have extended to represent my Image object , does not call its paint () method & does not draw itself on the existing JPanel. 我遇到的问题是,我扩展为表示我的Image对象的JComponent 没有调用它的paint()方法,也没有在现有的JPanel上绘制自己。

Below is the relevant snippet & event that uploads an Image & instantiates by “art” class which extends JComponent Class JFrameMainArt's actionPerformed() method (relevant section only) , when the OPEN action fies , the image object should be drawn on the fullscreenJPanel 下面是上传一个Image并通过“art”类实例化的相关片段和事件,该类扩展了JComponent Class JFrameMainArt的actionPerformed()方法(仅限相关部分),当OPEN操作fies时,应该在fullscreenJPanel上绘制图像对象

@Override
    public void actionPerformed(ActionEvent arg0) {

        if (arg0.getActionCommand().equalsIgnoreCase("Fullscreen Mode")) {
            isScreenFullscreen = true;
            // full screen mode settings
            fullscreenFrame.invalidate();
            fullscreenFrame = null;
            // create new fullscreen frame
            fullscreenFrame = new JFrame();
            fullscreenFrame
                    .setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            fullscreenFrame.setUndecorated(true);
            fullscreenFrame.setResizable(false);
            // add label to Panel
            fullscreenPanel.add(new JLabel("ALT + F4 to exit .",
                    SwingConstants.CENTER), BorderLayout.CENTER);
            fullscreenFrame.invalidate();
            GraphicsEnvironment.getLocalGraphicsEnvironment()
                    .getDefaultScreenDevice()
                    .setFullScreenWindow(fullscreenFrame);
        } else if (arg0.getActionCommand().equalsIgnoreCase("Upload")) {
            System.out.println("Upload Pictures");
            fileChooser = new JFileChooser();
            fileChooser
                    .setDialogTitle("Choose Your Image File (PNG or JPEG only)");
            // below codes for select the file
            int returnval = fileChooser.showOpenDialog(null);
            File file = fileChooser.getSelectedFile();
            System.out.println("Upload Pictures, selected file path: "
                    + file.getAbsolutePath());

            // if OPEN
            if (returnval == JFileChooser.APPROVE_OPTION) {

                String name = file.getName();
                if (name != null) {
                    int i = name.indexOf('.');
                    // get the extension such as jpeg, or png
                    String extension = name.substring(i + 1);
                    System.out.println("extension: " + extension);
                    if (extension.equalsIgnoreCase("jpeg")
                            || extension.equalsIgnoreCase("jpg")
                            || extension.equalsIgnoreCase("png")) {

                        Art newArt = new Art(file, fullscreenPanel.getSize());
                        //test dimension 
                        System.out.println("Dimension of image "+name+"- Dimensions "+newArt.scaleImageToJPanelDimensions(newArt.getImageFromFile()));


                        //add Art Jcomponent to existing JPanel
                        fullscreenPanel.add(newArt);
                        //revalidate & paint
                        fullscreenPanel.revalidate();
                        fullscreenPanel.repaint();
                        //pack & revalidate the Jframe
                        fullscreenFrame.revalidate();


                    } else {
                        System.out
                                .println("Error file/image type is not supported: "
                                        + extension);
                    }

                }// end name not null
                else {
                    System.out.println("Error file name: " + name);
                }

            } else if (returnval == JFileChooser.ERROR_OPTION) {
                System.out.println("Error selecting file");
            } else {
                System.out.println("returnval: " + returnval);
            }

        }// end else if upload
        else if (arg0.getActionCommand().equalsIgnoreCase("Choose Effect")) {

        } else {

        }

    }//end method actionPerformed()

Art.java extends JComponent and is responsible for loading the image, scaling image, drawing of the image object Art.java扩展了JComponent并负责加载图像,缩放图像,绘制图像对象

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.beans.Transient;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;

public class Art extends JComponent {

    private File file = null;
    private BufferedImage image = null;
    private Dimension dimensionToScale = null;

    public Art(File file, Dimension dimensionToScale) {
        super();
        this.file = file;
        this.dimensionToScale = dimensionToScale;
        this.setVisible(true);

    }

    @Override
    @Transient
    public Dimension getPreferredSize() {
        // TODO Auto-generated method stub
        return this.dimensionToScale;
    }

    public Art(File file) {
        super();
        this.file = file;
        this.setVisible(true);
    }

    public BufferedImage getImageFromFile() {
        BufferedImage  image = null;
        if (this.file != null) {
            try {
                image = ImageIO.read(file);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return image;
    }

    public Dimension scaleImageToJPanelDimensions(BufferedImage image) {
        Dimension dimension = null;
        // scaling factors

        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();


        // scale based on largest side
        int largestImageSide = Math.min(imageWidth, imageHeight);

        double scaledHeight =  this.dimensionToScale.getHeight()
                / largestImageSide;
        double scaledWidth =  this.dimensionToScale.getWidth()
                / largestImageSide;
        // compute new image dimensions
        imageWidth = (int) (imageWidth * scaledWidth);
        imageHeight = (int) (imageHeight * scaledHeight);

        dimension = new Dimension(imageWidth, imageHeight);

        return dimension;

    }

    @Override
    public void paintComponent(Graphics g) {

        System.out.println("paintComponent(Graphics g) ");

        super.paintComponent (g);

        // repaint background
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(getForeground());


        image = getImageFromFile();
        if (image != null) {

            // compute dimensions of image to draw
            Dimension imageDimension = scaleImageToJPanelDimensions(image);
    /*public abstract boolean drawImage(Image img,
            int x,
            int y,
            int width,
            int height,
            ImageObserver observer)*/

            g.drawImage(image, 0,0, (int) imageDimension.getWidth() ,(int)imageDimension.getHeight(),this);

        } else {
            System.out.println("paintComponent(Graphics g)  image:"+image);
        }

    }

}/end Art class

Any help will be appreciated. 任何帮助将不胜感激。

Thanks. 谢谢。

Actual working method ,image is now drawn , issue is solved. 实际工作方法,现在绘制图像,问题解决。

public void loadArtToScreen(Art art)
    {


        //add Art JComponent to existing JPanel
        JPanelGroupLayout.setHorizontalGroup(JPanelGroupLayout.createParallelGroup(
                Alignment.LEADING).addGroup(
                        JPanelGroupLayout.createSequentialGroup().addGap(0)
                        .addComponent(art )
                        .addContainerGap((int)mainJFrameSize.getWidth(), Short.MAX_VALUE)));

        JPanelGroupLayout.setVerticalGroup(JPanelGroupLayout.createParallelGroup(
                Alignment.LEADING).addGroup(
                        JPanelGroupLayout.createSequentialGroup().addGap(0)
                        .addComponent(art )
                        .addContainerGap((int)mainJFrameSize.getHeight(), Short.MAX_VALUE)));

        //revalidate & paint
        fullscreenPanel.revalidate();
        fullscreenPanel.repaint();
        //pack & revalidate the Jframe
        mainJFrame.revalidate();

    }//end loadArtToScreen(Art art)
  1. You never load the image , so your paint method is going to throw a NullPointerException 您永远不会加载image ,因此您的paint方法将抛出NullPointerException
  2. Graphics#drawImage(Image, int, int, ImageObserver) refers to the position the image should be painted, not it's size (strangely, your scale algorithm is return 0x0 , but I didn't spend much time looking into it) Graphics#drawImage(Image, int, int, ImageObserver)指的是图像应该被绘制的位置,而不是它的大小(奇怪的是,你的缩放算法返回0x0 ,但我没有花太多时间研究它)
  3. In this context, you should be passing this to the last parameter of Graphics#drawImage 在这种情况下,你应该通过this来的最后一个参数Graphics#drawImage
  4. It is recommended that custom painting be done within the context of the paintComponent method and not the paint method. 建议在paintComponent方法的上下文中完成自定义绘制,而不是paint方法。 See Performing Custom Painting for more details 有关详细信息,请参阅执行自定义绘画

nb- I also tried adding the pane to a full screen window without issues. nb-我也尝试将窗格添加到全屏窗口而没有问题。 I even introduced a small delay between the frame becoming visible and adding the pane and had it work - after I corrected for the NullPointerException . 我甚至在框架变得可见并添加窗格之间引入了一个小延迟并使其工作 - 在我更正了NullPointerException

Try removing the full screen requirement while you test it... 尝试在测试时删除全屏要求...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM