Search code examples
javaswingpaintcomponent

Image not showing up in Swing?


I honestly don't know what I'm doing wrong. (Although I'm sure it's quite a bit.) I've been trying to adjust my code for hours to no avail.

I'm attempting to cut up pieces of a picture and display them. Later, I will randomize where they are located and try to place them in their correct positions. Now, however, I'm having issues having anything show up on my JPanel at all. At one point, my test code displayed the image. Now, however, the same test code doesn't work.

If you can see what I'm doing wrong/where the issue is, please let me know. Hopefully it's something simple and stupid.

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;

public class Lab10 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        MyFrame frame = new MyFrame();
        MyPanel panel = new MyPanel();
        frame.add(panel);
        panel.setFocusable(true);


    }

}

class MyFrame extends JFrame{
    MyFrame(){
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        setSize(800,800);
        setResizable(false);
    }
}

class MyPanel extends JPanel{
    public static final int SIZE = 4;
    private int oldx = -1;
    private int oldy = -1;
    private final String fileName = "houseTyrell.png";

    public ImageArray imageArray = new ImageArray(fileName, SIZE);

    MyPanel(){

        addMouseListener(new MouseAdapter(){

            public void mousePressed(MouseEvent e){
                if(e.getButton()==1){
                    if(oldx == -1){
                        oldx = e.getX();
                        oldy = e.getY();
                    }else{
                        //imageArray.swapPoints(oldx, oldy, e.getX(), e.getY());
                        oldx = -1;
                        oldy = -1;
                        repaint();
                    }
                }
            }
        });
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        imageArray.draw(g2);

        /*Image image2;
        try {
            image2 = ImageIO.read(new File("houseTyrell.png"));
            System.out.println("I should print");

            try{
                g2.drawImage(image2, 0, 0, null);
            } catch(Exception my){
                System.out.println("Drawing issue");
            }

        } catch (IOException ex) {
            System.out.println("Reading issue");

        }*/

    }
}


class ImageArray{
    private Square[][] squares;
    private String fileName;
    private int size;
    private int w;
    private int h;

    public ImageArray(String fileName, int size) {
        this.size = size;
        this.fileName= fileName;
        squares = new Square[size][size];
        try {
            BufferedImage image = ImageIO.read(new File(fileName));
            w = image.getWidth() / size;
            h = image.getHeight() / size;
            for (int row = 0; row < size; row++) {
                for (int col = 0; col < size; col++) {
                    squares[row][col] = new Square(
                    image.getSubimage(row * w , col * h , w, h), row, col, w, h);
                }
            }

        } catch (Exception e) {
            System.out.println("Can't open file!");
        }
        shuffle();
        } 

    //TODO
    public void shuffle(){
        for(int i = 0; i < size * size; i++){

        }
    }

    //TODO
    public void swapPoints(int oldx, int oldy, int newx, int newy){

    }

    public void draw(Graphics2D g2){
        for(int i = 0; i < squares.length; i++){
            for(int j = 0; j < squares[0].length; j++){
                Square square = squares[i][j];
                square.draw(g2);

            }
        }
    }

}

class Square{
    private BufferedImage image;
    private int row;
    private int col;
    private int x,y;
    private int w;
    private int h;

    Square(BufferedImage image, int row, int col, int w, int h){
        this.image = image;
        this.row = row;
        this.col = col;
        this.x = row * w;
        this.y = col * h;
        this.w = w;
        this.h = h;
    }

    public void draw(Graphics2D g2){
        try{
            g2.drawImage(image, x, y, null);
        } catch (Exception my){
            System.out.println("Square issue");
        }
    }

    public BufferedImage getImage(){
        return image;
    }

    public int getRow(){
        return row;
    }

    public int getCol(){
        return col;
    }
}

Solution

  • You are making the frame visible BEFORE you've finished establishing UI, try calling invalidate, validate and repaint on the frame AFTER you've added the panel...

    public static void main(String[] args) {
        MyFrame frame = new MyFrame();
        MyPanel panel = new MyPanel();
        frame.add(panel);
        panel.setFocusable(true);
        frame.invalidate();
        frame.validate();
        frame.repaint();
    
    }
    

    Frankly, your MyFrame class is doing very little (other then making your life more difficult), I'd consider getting rid of it, maybe replace it with a builder method which returns a frame which is not visible yet...

    You should also be creating your UI from within the context of the Event Dispatching Thread, which can help solve other "weird" issues.

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
    
                MyFrame frame = new MyFrame();
                MyPanel panel = new MyPanel();
                frame.add(panel);
                panel.setFocusable(true);
                frame.invalidate();
                frame.validate();
                frame.repaint();
            }
        });
    }
    

    See Initial Threads for more details