0

I haven’t made a Java Swing app for a while (2+ years), so excuse me for any silly mistake.

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.

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

@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

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)
cyber101
  • 2,672
  • 11
  • 46
  • 81

1 Answers1

2
  1. You never load the image, so your paint method is going to throw a 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)
  3. In this context, you should be passing this to the last parameter of Graphics#drawImage
  4. It is recommended that custom painting be done within the context of the paintComponent method and not the paint method. See Performing Custom Painting for more details

nb- I also tried adding the pane to a full screen window without issues. 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.

Try removing the full screen requirement while you test it...

MadProgrammer
  • 323,026
  • 21
  • 204
  • 329
  • I updated the above code, I fixed the errors that you ponied out 1) I'm loading image now, 2) I'm drawing the image start at top,left 0,0 the image dimension is no longer zeros 3)the JComponent reference is passed in paintComponent() 4) I'm using paintComponent() , there no errors or exception however , **the image is still not drawn , paintComponent() is never called.** – cyber101 Oct 18 '13 at 16:15
  • So, ican get your Art class to. The only reasons paintComponent won't be called, is if the component t isn't displayable (has being added to a container that is displayed on the screen) or the component doesn't have an a appropriate size. It's not possible to ascertain any of this fro. Your snippet. With a runnable example, we'd only be guessing – MadProgrammer Oct 18 '13 at 20:01
  • @ MadProgrammer, thanks for the effort, I actually posted the entire Art class already , please see above. In my program I'm adding the Art (JComponent) to a JPanel that has GroupLayout , and the JPanel(will be same since as the JFrame) it self is added to my main JFrame which is also GroupLayout, Will post the entire main JFrame , now. – cyber101 Oct 18 '13 at 22:43
  • @AryanNaim Yes, I've used your Art class, which is why I could find what was wrong. I'd avoid GroupLayout, it's not particularly dynamic. Try using something like BorderLayout as a test – MadProgrammer Oct 19 '13 at 00:07
  • I actually encapsulated a the image loading in a method and figured out that I had to add ***my Art class (JComponent) to the main JPanel is groupLayout by specifying the horizontal & vertical components***. The picture is been drawn now , however its small , actually 1/4 of the pic is being drawn although the dimensions are correct. Im going to accept your answer, since you point out important bugs. I will post my working method above , based on the loadArtToScreen(Art art) method why is 1/4 of the image only being drawn??? Thanks – cyber101 Oct 19 '13 at 06:05