0

everyone. I would like to have custom JPanels ( I prefer absolute position layout for my use) in GridLayout. GridLayout is in ScrollPane.

public class App extends JFrame {
    public App() {
        super("bamlOperator");
        JPanel panel = new JPanel(new GridLayout(0, 1));
        JScrollPane scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        panel.add(new MyCustomPanel());
        panel.add(new MyCustomPanel());
        panel.add(new MyCustomPanel());
        panel.add(new MyCustomPanel());
        panel.add(new MyCustomPanel());
        panel.add(new MyCustomPanel());

        pack();
        setVisible(true);
    }

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

And MyPanel :

public class MyCustomPanel extends JPanel {

    private JLabel aaa = new JLabel("aaa:");
    private JLabel bbb = new JLabel("bbb");
    private JLabel ccc = new JLabel("ccc:");

    public MyCustomPanel() {

        setPreferredSize(new Dimension(100,100));
        JPanel amlPanel = new JPanel();
        amlPanel.setLayout(null);
        amlPanel.setBounds(0,0,100,100);
        aaa.setBounds(10,20,30,40);
        amlPanel.add(aaa);
        bbb.setBounds(20,30,40,50);
        amlPanel.add(bbb);
        ccc.setBounds(30,40,50,60);
        amlPanel.add(ccc);
        add(amlPanel);
    }
}

But it doesnt work.

I said, I prefer absolute position layout but I know It is bad practice. I can use another but I need JPanel something like this :

Project of JPanel

enter image description here

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
M. Lup
  • 5
  • 6
  • *"But it doesnt work."* is not a description of a problem. Please describe what you are experiencing and what you are expecting instead. – Ben Jun 20 '18 at 08:50
  • does new MyCosutomPanel() means new AMLPanel() ? – Gimhani Jun 20 '18 at 09:00
  • @Gimhani That's correct, I've already improved. – M. Lup Jun 20 '18 at 09:10
  • @Ben It does mean : I have blank frame with GridLayout. – M. Lup Jun 20 '18 at 09:10
  • So, your fundamental problem is you're mixing absolute layouts with layout managers - the problem is `MyCustomPanel` isn't providing any sizing hints which the layout manager can use to make better decisions about how best to layout your component. So, if you really want to use absolute layouts, you're going to have to do ALL the work that the layout management API would have done for you – MadProgrammer Jun 20 '18 at 09:17
  • @MadProgrammer Okay, I understand, I do not have to necessarily use absolute layout. I just want my custom panel to look exactly like I posted above in the picture. Which layout manager will be the best for that? – M. Lup Jun 20 '18 at 09:27
  • @M.Lup There's no such thing as "pixel perfect", especially now days – MadProgrammer Jun 20 '18 at 09:28

2 Answers2

2

So, your fundamental problem is you're mixing absolute layouts with layout managers - the problem is MyCustomPanel isn't providing any sizing hints which the layout manager can use to make better decisions about how best to layout your component. So, if you really want to use absolute layouts, you're going to have to do ALL the work that the layout management API would have done for you

Can you tell me which layout manager will be the best for my use?

All of them. Don't get fixated on a single layout manager achieving everything your want, instead, combine them together to produce the results you're after.

I don't have your "exact" requirements, but I was able to achieve this by using BorderLayout and GridBagLayout

For example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class Test extends JFrame {
    public static void main(String[] args) {
        new Test();
    }

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new MainPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MainPane extends JPanel {

        public MainPane() {
            // You could use a GridLayout, but GridBagLayout will
            // honour the preferred sizs of each component
            setLayout(new GridBagLayout());
            setBorder(new EmptyBorder(10, 10, 10, 10));
            GridBagConstraints gbc = new GridBagConstraints();
            add(new LeftPane(), gbc);
            add(new MiddleLeftPane(), gbc);
            add(new MiddlePane(), gbc);
            add(new RightPane(), gbc);
        }

    }

    public class LeftPane extends JPanel {

        public LeftPane() {
            setLayout(new GridBagLayout());

            JPanel main = new JPanel(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            for (int index = 0; index < 6; index++) {
                if (index % 2 == 0) {
                    gbc.anchor = GridBagConstraints.LINE_START;
                } else {
                    gbc.anchor = GridBagConstraints.LINE_END;
                }
                main.add(new JLabel("Label"), gbc);
            }

            gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(main, gbc);

            gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            add(new JButton("Button"));
        }

    }

    public class MiddleLeftPane extends JPanel {

        public MiddleLeftPane() {
            setLayout(new BorderLayout());
            BufferedImage img = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.drawLine(0, 0, 200, 200);
            g2d.drawLine(200, 0, 0, 200);
            g2d.dispose();

            JLabel label = new JLabel(new ImageIcon(img));
            label.setBorder(new LineBorder(Color.GRAY));
            add(label);
        }

    }

    public class RightPane extends JPanel {

        public RightPane() {
            setLayout(new BorderLayout());
            BufferedImage img = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.drawLine(0, 0, 200, 200);
            g2d.drawLine(200, 0, 0, 200);
            g2d.dispose();

            JLabel label = new JLabel(new ImageIcon(img));
            label.setBorder(new LineBorder(Color.GRAY));
            add(label);
        }

    }

    public class MiddlePane extends JPanel {

        public MiddlePane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(4, 4, 4, 4);

            add(new JButton("Button"), gbc);
            gbc.gridx++;
            add(new JButton("Button"), gbc);

            gbc.gridwidth = 2;
            gbc.gridx = 0;
            gbc.gridy = 2;
            add(new JButton("Button"), gbc);

            gbc.gridy = 1;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(new JScrollPane(new JTextArea("Text Area", 5, 10)), gbc);
        }

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I just started making a layout based on your tips. What you just presented is exactly what I need! Thanks for your help and I'm getting ready for modification :) – M. Lup Jun 20 '18 at 10:46
  • Can you tell me how I can move the left panel up to the left, center the center, and the right panel up to the right? – M. Lup Jun 20 '18 at 10:58
  • I really don't understand. Do you mean you want to align them to the top, left/right positions? – MadProgrammer Jun 20 '18 at 20:37
  • One of the simplest ways to do it, is to set the `GridBagConstraints` `weightx` property to `1` for `MiddlePane` when adding it to the `MainPane` - just remember to reset it to `0` before adding any additional components after it – MadProgrammer Jun 21 '18 at 20:20
  • Okay, it works when all Pane's are visible. But when I will hide MiddleLeftPane, RightPane and MiddlePane, LeftPane isn't align to left side. – M. Lup Jun 22 '18 at 08:26
  • Can you help? ad – M. Lup Jun 25 '18 at 07:24
  • You're making the components invisible? Layout managers won't include hidden components in their layout calculations – MadProgrammer Jun 25 '18 at 07:51
1

You are using a null layout for layout of your custom panel. When you add this inside another panel of grid layout, since the sizes are not set, it would not be painted. Try using a proper layout for your custom panel as well. And, see the answer for Using a JPanel with a null layout .

Gimhani
  • 1,318
  • 13
  • 23
  • Thanks for your reply. I undestand now, Can you tell me which layout manager will be the best for my use? You can see what I to achieve on picture. – M. Lup Jun 20 '18 at 09:25
  • @M.Lup still you have only added panels of labels to the main panel. Better to organize the main panel first (1*5 grid layout for example) and then add those child panels with a proper layout (grid layout or flow layout for example). – Gimhani Jun 20 '18 at 09:33
  • `MyCustomPanel()` does not use null layout – c0der Jun 20 '18 at 09:37
  • @c0der amlpanel layout is null. It need to be changed to a proper layout. – Gimhani Jun 20 '18 at 09:38