I am trying to make an editable grid of pixels using a Java BufferedImage in a JFrame. I set the size of the JFrame and the BufferedImage to be the same:
int width = 640;
int height = 480;
PixelGrid aGrid = new PixelGrid(width, height);
JFrame window = new JFrame("help me");
window.add(aGrid); // Incorporates the pixel grid into the window
window.setSize(640,480);
window.setVisible(true); // Makes the window visible
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Where the PixelGrid constructor just creates a black and white BufferedImage:
public PixelGrid(int width, int height) {
grid = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
}
In order to test that the full image was being rendered, I set the pixel values for the top left and bottom rightmost pixels:
aGrid.setColour(1, 0, 0);
aGrid.setColour(1, 639, 479);
aGrid.repaint();
Which displays this: enter image description here Here we can see the pixel on the top left but not in the bottom right. We can only see the bottom right pixel if we expand the window: enter image description here Furthermore, I have checked the width and height parameters for the JFrame and it returns 640x480. I feel as if I have trawled through the Java docs for both of these classes and yet I am still not sure what exactly will fix this issue.
The basic answer to your question is to ignore the window size. The viewable content size is the size of the window minus the windows decorations, so, in your case, your viewable area is going to be smaller then the window itself.
A better approach would be to provide appropriate sizing hints in your child components and then pack
the window around it, for example...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
public TestPane() {
setLayout(new GridBagLayout());
label = new JLabel("...");
label.setFont(label.getFont().deriveFont(48f));
add(label);
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
label.setText(getWidth() + "x" + getHeight());
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
}
}
Also remember, on different platforms (and even different settings on the same platform) the window decorations can change size, so you're best to ignore them and rely on providing sizing hints back up the view hierarchy