简体   繁体   中英

drawing a line in Java - line is not visible

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?

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 LayoutManager s) 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 ie 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):

在此处输入图片说明

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);
    }
}

The proper (better to say, easier, much less error prone) way to do it has been shown by David Kroukamp. As for your original question, modify the original code like this:

line1.setBounds(350+insets.left,75+insets.top,size.width+50,size.height+20);    
line1.setBorder(BorderFactory.createEtchedBorder()); // add this line

Your line starts at point 200,300 but the panel you're drawing it in has width of 50+10 and height of 20+10 - on my computer at least - which means that the line is outside of the drawingLine panel and that's why it doesn't get drawn. To verify that modify the line in your original drawingLine.paintComponent like this:

Line2D line = new Line2D.Double(0, 0, 1000, 1000);

and you will see the following result:

在此处输入图片说明

This line in your original code:

pane.setLayout(null);

is pretty clear - you are using no layout manager, or in other words you chose to useabsolute positioning . This means that the coordinates, widths and heights of components must be precalculated and set by you. But if you make a mistake somewhere (as your example nicely shows) it'll be hard to detect. Not to mention, for example if you want to handle window resizing. That's why LayoutManagers exist.

I recommend reading also:

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