In the following program I'm putting some images in a panel and performing transformations on them relative to that panel. However, when the gui is first drawn it performs the initial paint operation relative to the coordinates of the window, rather than the panel. in addition to being in the wrong place, all images are stacked on top of each other. How do I avoid this? All subsequent repaints are correct but not the initial setting.
I've already tried repainting the panels in the main method after setting the window visible.
I'm attempting to jerry-rig a solution by creating a boolean flag that will change when the ActionListener is triggered. This will allow me to change the behaviour of the paintComponent() method when initially run and I can just use the window coordinate system, but this is incredibly inelegant and I suspect there is a better solution.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import javax.swing.*;
public class GraphicsCreation extends JFrame {
static int frame;
static JPanel images;
static final BufferedImage[] IMAGE = {Image.getImage(Image.imageArr1), Image.getImage(Image.imageArr2), Image.getImage(Image.imageArr3)};
boolean built = false;
public GraphicsCreation() {
final int MAXFRAMES = 5;
JPanel navBar = new JPanel();
navBar.setLayout(new BorderLayout());
JButton next = new JButton("NEXT >>");
JLabel label = new JLabel(" ", SwingConstants.CENTER);
frame = 1;
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame++;
for (Component image : images.getComponents()) {
image.repaint();
}
}
};
next.addActionListener(listener);
images = new JPanel();
images.setLayout(new GridLayout(0, 2));
JPanel imagePanel1 = new ImagePanel(0);
JPanel imagePanel2 = new ImagePanel(1);
images.add(imagePanel1);
images.add(imagePanel2);
images.validate();
this.setLayout(new BorderLayout());
this.add(next, BorderLayout.NORTH);
this.add(images, BorderLayout.CENTER);
}
public static void main(String args[]) {
GraphicsCreation gc = new GraphicsCreation();
gc.setMinimumSize(new Dimension(400, 300));
gc.setLocationRelativeTo(null);
gc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gc.setResizable(false);
gc.setVisible(true);
}
class ImagePanel extends JPanel {
AffineTransform currentTransform;
int img;
public ImagePanel(int img) {
super();
this.img = img;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.BLACK);
g2.fillRect(0, 0, getWidth(), getHeight());
//applyWindowToViewportTransformation(g2, -75, 75, -75, 75, true);
double width = getWidth();
double height = getHeight();
switch (frame) {
case 1:
currentTransform = new AffineTransform();
g2.setTransform(currentTransform);
break;
case 2:
g2.setTransform(currentTransform);
g2.translate((-5), 7);
break;
case 3:
g2.setTransform(currentTransform);
g2.rotate(Math.toRadians(-45), width / 2, height / 2);
break;
case 4:
g2.setTransform(currentTransform);
g2.rotate(Math.toRadians(90), width / 2, height / 2);
break;
case 5:
g2.setTransform(currentTransform);
g2.translate((width - width * 2) / 2, (height - height * 0.5) / 2);
g2.scale(2, 0.5);
break;
}
currentTransform = g2.getTransform();
g2.translate(width / 2 - (IMAGE[img].getWidth() / 2), height / 2 - (IMAGE[img].getHeight() / 2));
System.out.print(g2.getTransform().getTranslateX() + " ");
System.out.println(g2.getTransform().getTranslateY());
g2.drawImage(IMAGE[img], 0, 0, this);
}
}
}
How the program looks when initially run:
How the program SHOULD look when run:
The correct look can be reach by hitting the next button 5 times.
Here's the Image class if you want it, but it should only be relevant in creating a buffered image to work with.
import java.awt.Color;
import java.awt.image.BufferedImage;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Dylan Veraart
*/
public class Image {
private static int bg = Color.WHITE.getRGB();
private static int fg1 = Color.MAGENTA.getRGB();
static String name1 = "Rectangle";
static int[][] imageArr1 = {
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,fg1,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg}
};
private static int fg2=Color.BLACK.getRGB();
static String name2 = "lowercaseF";
static int[][] imageArr2 = {
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,fg2,fg2,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,fg2,fg2,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,fg2,fg2,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,fg2,fg2,fg2,fg2,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,bg,fg2,fg2,fg2,bg,bg,fg2,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,bg,fg2,fg2,fg2,bg,bg,fg2,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg2,fg2,fg2,fg2,fg2,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg}
};
private static int fg3=Color.GREEN.getRGB();
static String name3 = "circles";
static int[][] imageArr3 = {
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,fg3,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,fg3,fg3,fg3,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,fg3,fg3,fg3,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,fg3,fg3,fg3,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,fg3,fg3,fg3,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,fg3,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,fg3,fg3,fg3,fg3,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,fg3,fg3,fg3,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,fg3,fg3,fg3,fg3,fg3,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,fg3,fg3,fg3,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg},
{bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg,bg}
};
public static BufferedImage getImage(int[][] arr){
BufferedImage image = new BufferedImage(25, 25, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < 25; x++) {
for (int y = 0; y < 25; y++) {
image.setRGB(x, y, arr[y][x]);
} // End for y.
} // End for x.
return image;
}
}