drawing a line in Java - line is not visible

jdek picture jdek · Jan 17, 2013 · Viewed 7.1k times · Source

I am learning Java on my own. Trying to create a frame with a line in it. It seemed pretty basic, but I can't see the line. The code compiles and I can't seem to understand why I can't see the line. I see other components in the frame. I am using 2 java files. One file is container file and the other file has the draw line code. They are part of package a1. Here is my code (please help):

Container File:

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

public class gameContainer {

    public static void addComponentsToPane(Container pane) {
        pane.setLayout(null);

        //add button to the pane
        JButton b3 = new JButton("B1");
        pane.add(b3);

        //add line to the pane
        drawingLine line1 = new drawingLine();
        pane.add(line1);

        //size and position all relatively          
        Insets insets = pane.getInsets();
        Dimension size;
        size = b3.getPreferredSize();        
        b3.setBounds(350+insets.left,15+insets.top,size.width+50,size.height+20);
        size = line1.getPreferredSize();
        line1.setBounds(350+insets.left,75+insets.top,size.width+50,size.height+20);    

    }

    private static void createAndShowGUI() {
        int l = 200, w = 80;

        //Create and set up the window.
        JFrame frame = new JFrame("Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Set up content pane
        addComponentsToPane(frame.getContentPane());

        //add menu bar
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Menu");
        menu.add(new JMenuItem("Do nothing"));
        menuBar.add(menu);
        frame.setJMenuBar(menuBar);

        // size and display root pane/window
        Insets insets = frame.getInsets();
        frame.setSize(500+insets.left+insets.right,300+insets.top+insets.bottom);
        frame.setLocation(w,l);
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
        });
    }

}

Draw line File:

package a1;
import javax.swing.*;
import java.awt.geom.Line2D;
import java.awt.Graphics2D;
import java.awt.Graphics;

public class drawingLine extends JPanel{

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Line2D line = new Line2D.Double(200, 300, 1000, 1000);
        //g2d.setColor(Color.black);
        g2d.draw(line);
        //g.drawLine(200, 300, 1000, 1000);
        //g.setColor(color.BLACK);

    }

}

Why am I not able to see the line?

Answer

David Kroukamp picture David Kroukamp · Jan 17, 2013

Your main problem is that you use null/Absolute layout.

You should have a read here:

1) You should use an appropriate LayoutManager (or nest together multiple LayoutManagers) and/or override getPreferredSize() of JComponent to return correct dimensions which fit the drawings.

2) Dont call setSize on JFrame rather call pack() before setting JFrame visible (with above in mind)

3) No need for adding to contentPane via getContentPane().add(..) as add(..) setLayout(..) and remove(..) have been forwarded to the contentPane.

4) Watch class names, stick to the java convention a class name begins with a capital letter and each new word thereafter the first letter should be capitilized i.e gameContainer should be GameContainer, drawingLine should be DrawingLine

Here is your code with above fixes implemented (not the most well layed out, but its only an example):

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;


public class GameContainer {

    public static void addComponentsToPane(JFrame frame) {

        JPanel buttonPanel=new JPanel();//create panel to hold button
        //add button to the pane
        JButton b3 = new JButton("B1");
        buttonPanel.add(b3);
        frame.add(buttonPanel, BorderLayout.EAST);//use contentPane default BorderLayout

        //add line to the pane
        DrawingLine line1 = new DrawingLine();
        frame.add(line1);

    }

    private static void createAndShowGUI() {

        //Create and set up the window.
        JFrame frame = new JFrame("Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Set up content pane
        addComponentsToPane(frame);

        //add menu bar
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Menu");
        menu.add(new JMenuItem("Do nothing"));
        menuBar.add(menu);
        frame.setJMenuBar(menuBar);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
class DrawingLine extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Line2D line = new Line2D.Double(10, 10, 100, 100);
        g2d.draw(line);

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }
}