简体   繁体   中英

getHeight() and getWidth() both return 0

I am trying to create a grid in a JPanel with lines, and to do this, I draw evenly spaced horizontal and vertical lines until I reach the end of the JPanel. I use a class called Drawing which extends JPanel and is the object I add to the window. Below is my code.

public final class Drawing extends JPanel {

    public Drawing() {
        super();
        setBackground(new Color(255, 255, 255));
        setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));

        GroupLayout workspacePanelLayout = new GroupLayout(this);
        setLayout(workspacePanelLayout);
        workspacePanelLayout.setHorizontalGroup(workspacePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 343, Short.MAX_VALUE));
        workspacePanelLayout.setVerticalGroup(workspacePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE));

        initWorkSpace();
    }

    private static class Line {

        final int x1;
        final int y1;
        final int x2;
        final int y2;
        final Color color;

        public Line(int x1, int y1, int x2, int y2, Color color) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.color = color;
        }
    }

    private final LinkedList<Line> lines = new LinkedList<>();

    public void addLine(int x1, int x2, int x3, int x4) {
        addLine(x1, x2, x3, x4, Color.black);
    }

    public void addLine(int x1, int x2, int x3, int x4, Color color) {
        lines.add(new Line(x1, x2, x3, x4, color));
        repaint();
    }

    public void clearLines() {
        lines.clear();
        repaint();
    }

    @Override
    private void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Line line : lines) {
            g.setColor(line.color);
            g.drawLine(line.x1, line.y1, line.x2, line.y2);
        }
    }

    public void initWorkSpace() {
        int x = 0;
        int y = 0;
        while (x < this.getWidth()) {
            addLine(x, 0, x, this.getHeight(), new Color(153, 153, 153));
            x += getSpacing();
        }
        while (y < this.getHeight()) {
            addLine(0, y, this.getWidth(), y, new Color(153, 153, 153));
            y += getSpacing();
        }
    }
}

The problem is that 'this.getHeight()' and 'this.getWidth()' both return 0 so the grid doesn't get drawn. drawing the lines works fine, its just that the panel apparently has no dimension. How do I solve this.

Not the main problem but you need to override the getPreferredSize() method of your class to return the size.

Each component is responsible for determining its own preferred size. Then the layout manager can use this information when the panel is added to a parent panel.

Of course this assumes the parent panel is using a layout manager which you should be doing.

For more information and working examples read the section from the Swing tutorial on Custom Painting

The real problem is when you invoke the following method:

    initWorkSpace();

All components have a zero size when the component is created. So when the above method is invoked from the constructor the size will always be zero.

If your painting code is dynamic which means it changes as the frame is resized, then you need to invoke that logic inside the paintComponent() method.

Or if your logic is too complex to execute every time the component is repainted, you can add a ComponentListener to the panel and handle the componentResized method and invoke that method.

Also, I'm not sure why you are using a GroupLayout when you are doing custom painting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM