Search code examples
javaswingjpanellayout-managergraphics2d

Using Layout Manager with JPanel and Graphics 2D


I want to draw lines and more on a JPanel, add that to a JFrame and using .pack() afterwards. My problem is that I dont get how to use a Layout Manager in that particular case. Usually I add a button or something to the panel by using a gridBagLayout and I totally understand that. But with graphics 2D I kind of just draw directly to the panel. Therfore I cant use .pack() properly. Does somebody know how to pack() that jPanel the right way? My code looks like that:

public class NetworkViewPanel extends JPanel implements KeyListener, ActionListener {       
public NetworkViewPanel(NetworkAI network) {
    this.network = network;
    this.netList = network.getLayerList();
    addKeyListener(this);
    setFocusable(true);
    this.setLayout(new GridLayout(2, 2, 2, 2)); // does that even make sense ?

}

public void paint(Graphics g) {
    super.paint(g);
    g2 = (Graphics2D) g;


    if (showStandardView) {
        drawRectangles();
        drawLines();
    } else {
        drawRectangles();
        drawLinesSpecial(listIndex, xIndex);
    }
}

Greetings :)


Solution

  • You can layout a JPanel with a layout manager, and do custom painting on top of it.
    This does not prevent you from using pack()1.
    The following mre 2 demonstrates painting a line on a JPanel using a GridLayout:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.GridLayout;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class NetworkViewPanel extends JPanel{
    
        private final List<JLabel> labels;
    
        public NetworkViewPanel() {
            this.setLayout(new GridLayout(2, 2, 2, 2));
            this.setPreferredSize(new Dimension(400,300));//used by pack()
            labels = new ArrayList<>();
            addLabels(new String[]{ "A", "B" , "C" , "D"});
        }
    
        private void addLabels(String[] text){
    
            for(String t: text){
                JLabel label = new JLabel(t);
                label.setBorder(BorderFactory.createLineBorder(Color.BLUE));
                label.setHorizontalAlignment(JLabel.CENTER);
                add(label);
                labels.add(label);
            }
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g); //draw panel as layed out by layout manager
            drawLines(g);
        }
    
        private void drawLines(Graphics g) {
            //draw line between centers of first and last components
            int x1 = labels.get(0).getBounds().x + labels.get(0).getBounds().width /2;
            int y1 = labels.get(0).getBounds().y + labels.get(0).getBounds().height /2;
            int x2 = labels.get(labels.size()-1).getBounds().x + labels.get(labels.size()-1).getBounds().width/2;
            int y2 = labels.get(labels.size()-1).getBounds().y + labels.get(labels.size()-1).getBounds().height/2;
            g.setColor(Color.RED);
            g.drawLine(x1, y1, x2, y2);
        }
    
        public static void main(String[] args) {
    
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationRelativeTo(null);
            f.add(new NetworkViewPanel());
            f.pack();
            f.setVisible(true);
        }
    }
    


    1 See: What does .pack() do?
    2 Consider posting mre when asking or answering