0

I am displaying an image in a scroll pane and it works great when the pane is smaller than the image. When the pane is larger then the image, the image is centered vertically and left justified horizontally. I would like the image to be left and top justified so all the extra space is on the bottom and right.

enter image description here

I have tried using insets, setAlignmentY(), the methods in JScrollPaneLayout and can't affect where the image is displaying.

All the tips and documents I have found show how to handle the panes when the scroll bars are needed, not when they are not.

I suspect the behavior is caused by the use of a JLabel to display the image, since JLabels seem to align themselves on the left and vertically centered by default. But none of my attempts have succeeded in shoving the image to the top.

Here is the actual code I used to create the above image (pared down significantly from my project, and comments removed for brevity). It should compile and run fine.

I am using Java 15 inside Intellij Idea community edition on a Windows 10 machine.

public class ShowPattern extends JFrame
{
    public static final int IMAGE_WIDTH = 340;
    public static final int IMAGE_HEIGHT = 272;
    protected BufferedImage fullSizeImage;
    private final JLabel imgLabel = new JLabel();

    public ShowPattern(int width, int height)
    {
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.add(createImagePane(this.imgLabel), BorderLayout.CENTER);
        add(mainPanel);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setPreferredSize(new Dimension(width + 35, height + 60));
        this.setLocation(25, 25);
        pack();
    }
    public final void showMapImage(BufferedImage img, File file)
    {
        setTitle("Pattern from file " + file.getName());
        fullSizeImage = img;
        ImageIcon imgIcon = new ImageIcon(img);
        imgLabel.setIcon(imgIcon);
    }
    private JScrollPane createImagePane(JLabel image)
    {
        JScrollPane scrollPane = new JScrollPane(image);
        image.setAlignmentY(Component.TOP_ALIGNMENT);  //DOESN'T AFFECT PLACEMENT
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        return scrollPane;
    }
    public static void main( String[] args )
    {
        ShowPattern showPattern = new ShowPattern(IMAGE_WIDTH, IMAGE_HEIGHT);
        try
        {
            JFileChooser fileChooser = new JFileChooser();
            int status = fileChooser.showOpenDialog(null);
            fileChooser.setMultiSelectionEnabled(false);
            if (status == JFileChooser.APPROVE_OPTION)
            {
                File file = fileChooser.getSelectedFile();
                BufferedImage bimg;
                try
                {
                    bimg = ImageIO.read(file);
                    showPattern.showMapImage(bimg, file);
                    showPattern.setVisible(true);
                }
                catch (IOException ioe)
                {
                    throw new RuntimeException(ioe);
                }
            }
        }
        catch (Exception e)
        {
            System.out.println("Exception Loading Pattern " + e.getMessage());
        }
    }
}
1
  • Have you tried JLable#setHorizontalAlignment and JLabel#setVerticalAlignment Commented Apr 3 at 0:46

1 Answer 1

1

Make use of JLabel#setHorizontalAlignment and JLabel#setVerticalAlignment

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame("Test");
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    protected class TestPane extends JPanel {

        public TestPane() throws IOException {
            setLayout(new BorderLayout());
            JLabel label = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/resources/apple.png"))));
            label.setHorizontalAlignment(JLabel.LEADING);
            label.setVerticalAlignment(JLabel.TOP);

            add(new JScrollPane(label));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }
}
2
  • Thank you @MadProgrammer. I didn't know about these, assuming that setAlignmentX and setAlignmentY were the ones to use. To help me in future searches, is there some technique you used to find these (besides that thing between your ears)? Commented Apr 3 at 1:07
  • 1
    @AlexHomeBrew The offical tutorials and JavaDocs mostly Commented Apr 3 at 1:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.