3

I'm developing a simple image editing program to adjust brightness/contrast. My custom JPanel is simply used to display the loaded image, but it is causing my sliders and labels on the next column to display incorrectly.

import java.awt.*;
import javax.swing.*;

public class IMView extends JFrame  implements Observer {

JButton selectIMGFolder = new JButton("Select Folder");
ImagePanel originalImage;
//Labels and sliders to control image
JLabel brightnessLabel = new JLabel("Brightness");
JSlider brightness = new JSlider(-255,255,0);
JLabel contrastLabel = new JLabel("Contrast");
JSlider contrastSlider = new JSlider(-255,255,0);

JLabel random = new JLabel("Random Test Label");

public IMView (){
    super("Image manipulation");

    JPanel mainJPanel = new JPanel();
    mainJPanel.setLayout(new GridBagLayout());

    GridBagConstraints gc = new GridBagConstraints();

    originalImage = new ImagePanel();
    //first column

    gc.anchor = GridBagConstraints.LINE_START;
    gc.weightx = 0.5;
    gc.weighty = 0.5;

    gc.gridx = 0;
    gc.gridy = 0;
    mainJPanel.add(selectIMGFolder, gc);

    gc.gridx = 0;
    gc.gridy = 1;

    mainJPanel.add(originalImage, gc);

    gc.gridx = 0;
    gc.gridy = 2;
    mainJPanel.add(random, gc);

    //second column
    //brightness

    gc.gridx = 1;
    gc.gridy = 0;

    mainJPanel.add(brightnessLabel, gc);

    gc.gridx = 1;
    gc.gridy = 1;
    mainJPanel.add(brightness, gc);

    gc.gridx = 1;
    gc.gridy = 2;
    mainJPanel.add(contrastLabel, gc);

    gc.weighty = 10;
    gc.anchor = GridBagConstraints.FIRST_LINE_START;
    gc.gridx = 1;
    gc.gridy = 3;       
    mainJPanel.add(contrastSlider, gc);

    this.add(mainJPanel);
    this.setVisible(true);
    this.setPreferredSize(new Dimension(800, 600));
    this.pack();
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

//other code
}

Heres my simple custom panel:

public class ImagePanel extends JPanel {

Image image;

public ImagePanel(){
    this.setPreferredSize(new Dimension(400,300));

}   

//set image file some where

@Override
public void paintComponent(Graphics g){
    super.paintComponents(g);
    g.setColor(Color.red);
    g.fillRect(0, 0, 400,300);
    if(image != null){
         g.drawImage(image, 0,0, this);
    }

}

}

The below is the result of the code (where red square represents an image), I essentially want the sliders and labels on the right hand side to be packed together. If I don't add the custom panel to mainJPanel it seems to look how I want.

enter image description here

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Sun
  • 2,658
  • 6
  • 28
  • 33
  • *"My custom JPanel is simply used to display the loaded image"* Display the image in a label centered in a scroll-pane, as seen in [`ImageViewer`](http://stackoverflow.com/a/13512826/418556). – Andrew Thompson Dec 19 '12 at 00:25
  • See also [How to create screenshots?](http://meta.stackexchange.com/questions/99734/how-do-i-create-a-screenshot-to-illustrate-a-post) for some great tips on sizing and cropping. – Andrew Thompson Dec 19 '12 at 00:31
  • Thanks, this provides another way for me to display my images. But it didn't solve the problem. – Sun Dec 19 '12 at 01:26

2 Answers2

2

GridBagLayout is complex enough without laying out everything within a single container. Break up your form into areas of responsibility and use separate containers.

enter image description here

public class BadLayout08 {

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

    public BadLayout08() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new IMView();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class IMView extends JFrame {

        JButton selectIMGFolder = new JButton("Select Folder");
        JPanel originalImage;
//Labels and sliders to control image
        JLabel brightnessLabel = new JLabel("Brightness");
        JSlider brightness = new JSlider(-255, 255, 0);
        JLabel contrastLabel = new JLabel("Contrast");
        JSlider contrastSlider = new JSlider(-255, 255, 0);
        JLabel random = new JLabel("Random Test Label");

        public IMView() {
            super("Image manipulation");

            JPanel mainJPanel = new JPanel();
            mainJPanel.setLayout(new GridBagLayout());

            GridBagConstraints gc = new GridBagConstraints();

            originalImage = new JPanel();
            originalImage.setPreferredSize(new Dimension(400, 300));
            originalImage.setBackground(Color.RED);
            //first column

            gc.anchor = GridBagConstraints.LINE_START;

            gc.gridx = 0;
            gc.gridy = 0;
            mainJPanel.add(selectIMGFolder, gc);

            gc = new GridBagConstraints();
            gc.anchor = GridBagConstraints.LINE_START;
            gc.gridx = 0;
            gc.gridy = 1;
            mainJPanel.add(originalImage, gc);

            gc = new GridBagConstraints();
            gc.gridx = 0;
            gc.gridy = 2;
            mainJPanel.add(random, gc);

            //second column
            //brightness

            JPanel sidePane = new JPanel(new GridBagLayout());
            gc = new GridBagConstraints();

            gc.gridx = 1;
            gc.gridy = 0;

            sidePane.add(brightnessLabel, gc);

            gc.gridx = 1;
            gc.gridy = 1;
            sidePane.add(brightness, gc);

            gc.gridx = 1;
            gc.gridy = 2;
            sidePane.add(contrastLabel, gc);

            gc.weighty = 10;
            gc.anchor = GridBagConstraints.FIRST_LINE_START;
            gc.gridx = 1;
            gc.gridy = 3;
            sidePane.add(contrastSlider, gc);

            gc = new GridBagConstraints();
            gc.gridx = 1;
            gc.gridy = 1;
            gc.gridheight = GridBagConstraints.REMAINDER;
            gc.anchor = GridBagConstraints.NORTH;
            mainJPanel.add(sidePane, gc);

            this.add(mainJPanel);
            this.setVisible(true);
            this.setPreferredSize(new Dimension(800, 600));
            this.pack();
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
//other code
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

You can use BorderLayout in this situation. The red panel wants maximum horizontal and vertical stretch. All other components can be pushed to their minimum size against the red panel.

If you need to use GridBagLayout see this : http://blue-walrus.com/?p=582

Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225