1

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 :)

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Ollowain
  • 55
  • 6
  • Please show the GUI that you're desiring vs the one you're getting. Images would help greatly. Also post a little more code, code that is complete, compiles, runs and shows the GUI. – Hovercraft Full Of Eels Mar 16 '20 at 12:12
  • Also, what components are you placing on this drawing JPanel that need to be layed out? You may need/want to create a custom layout manager if it is for an unusual game such as backgammon or cribbage. – Hovercraft Full Of Eels Mar 16 '20 at 12:14
  • 1
    Again, a compilable and runnable code post, essentially a [mre] (please check out the link) as well as images (as requested above), will help in greatly increasing our understanding of your question, code and problem. – Hovercraft Full Of Eels Mar 16 '20 at 12:25
  • 2
    You should override paintComponent in your JPanel class, rather than paint. You don't need a layout manager for the drawing JPanel. Your JFrame may need a master JPanel if you're going to have any Swing components in a control JPanel. Take a look at https://stackoverflow.com/questions/34981403/bufferedimage-not-being-cleared-before-each-rendering/35002727#35002727 for an example of a Swing application with a drawing JPanel. – Gilbert Le Blanc Mar 16 '20 at 13:02
  • 2
    You certainly can use `pack()`, but pack() will set each component to its preferred size (subject to the layout of its parent). Your NetworkViewPanel needs to override [getPreferredSize](https://docs.oracle.com/en/java/javase/13/docs/api/java.desktop/java/awt/Component.html#getPreferredSize%28%29). Setting a layout doesn’t affect the preferred size if your panel has no child components. – VGR Mar 16 '20 at 14:41

1 Answers1

2

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
c0der
  • 18,467
  • 6
  • 33
  • 65