-1

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.

Slomas99
  • 3
  • 2
  • There is a difference between the window size and the viewable content size. The viewable content size is the `windowSize - windowDecorationInsets`, so the viewable size is always smaller then the window size, [for example](https://stackoverflow.com/questions/13457237/how-to-get-the-exact-middle-of-a-screen-even-when-re-sized/13460914#13460914). A better solution would be to have your `aGrid` class define it's `preferredSize` and then `pack` the window around it. – MadProgrammer May 26 '23 at 22:33

1 Answers1

0

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • This worked for me, I had no clue there was a separation between viewable content resolution and the resolution of the whole window - thanks! – Slomas99 May 26 '23 at 23:27