在Java中绘制线条-线条不可见

在Java中绘制线条-线条不可见,java,swing,jpanel,paintcomponent,graphics2d,Java,Swing,Jpanel,Paintcomponent,Graphics2d,我正在自学Java。正在尝试创建包含线的框架。这看起来很基本,但我看不清界线。代码编译了,我似乎不明白为什么我看不到这行代码。我看到了框架中的其他组件。 我正在使用2个java文件。一个文件是容器文件,另一个文件具有绘制线代码。它们是a1包的一部分。 这是我的代码(请帮助): 容器文件: package a1; import javax.swing.*; import java.awt.*; public class gameContainer { public static voi

我正在自学Java。正在尝试创建包含线的框架。这看起来很基本,但我看不清界线。代码编译了,我似乎不明白为什么我看不到这行代码。我看到了框架中的其他组件。 我正在使用2个java文件。一个文件是容器文件,另一个文件具有绘制线代码。它们是a1包的一部分。 这是我的代码(请帮助):

容器文件:

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

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

    }

}
绘制线文件:

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

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

    }

}

为什么我看不到这行?

您的主要问题是使用了
null
/
Absolute
布局

您应该在此处阅读:

1) 应使用适当的
LayoutManager
(或将多个
LayoutManager
s嵌套在一起)和/或覆盖
JComponent
getPreferredSize()
,以返回符合图纸的正确尺寸

2) 不要在
JFrame
上调用
setSize
,而是在设置
JFrame
可见之前调用
pack()
(记住上面的内容)

3) 无需通过
getContentPane()添加到contentPane。添加(…)
作为
add(…)
setLayout(…)
remove(…)
已转发到contentPane

4) 注意类名,遵守java惯例类名以大写字母开头,其后的每个新词都应大写,即
gameContainer
应为
gameContainer
drawingLine
应为
drawingLine

下面是您实现了上述修复的代码(不是布局最合理的,但只是一个示例):

David Kroukamp已经展示了正确的(更简单,更不容易出错)方法。对于您的原始问题,修改原始代码如下:

line1.setBounds(350+insets.left,75+insets.top,size.width+50,size.height+20);    
line1.setBorder(BorderFactory.createEtchedBorder()); // add this line
Line2D line = new Line2D.Double(0, 0, 1000, 1000);
您的线从点200300开始,但您正在绘制它的面板的宽度为50+10,高度为20+10-至少在我的计算机上-这意味着该线位于
drawingLine
面板之外,这就是它无法绘制的原因。要验证是否按如下方式修改原始
drawingLine.paintComponent
中的线条:

line1.setBounds(350+insets.left,75+insets.top,size.width+50,size.height+20);    
line1.setBorder(BorderFactory.createEtchedBorder()); // add this line
Line2D line = new Line2D.Double(0, 0, 1000, 1000);
您将看到以下结果:

原始代码中的这一行:

pane.setLayout(null);
非常清楚-您没有使用布局管理器,或者换句话说,您选择使用。这意味着组件的坐标、宽度和高度必须由您预先计算和设置。但是如果你在某个地方犯了错误(正如你的例子很好地显示的那样),就很难发现。更不用说,例如,如果您想处理窗口大小调整。这就是存在的原因

我还建议阅读:


是的,就是这样。我以为我在适当地调整框架中的所有组件。我想我现在应该使用LayoutManager。稍后我们将回到这个问题。谢谢David Kroukamp。@jdek很高兴你知道问题出在哪里。看看我的最新答案。谢谢你+1.在您第一次发表评论之后,我确实使用了pack()。我有一些后续问题,但这个更新的答案解决了所有问题。谢谢你,谢谢你,林斯基。我理解绝对定位所涉及的问题。计算组件坐标的麻烦是不值得的。现在继续使用BorderLayout。我尝试在使用g2d.draw(line)之前使用g2d.drawImage在DrawingLine中的线条下添加一个图像。它不起作用。我只看到那条线。我想看看这条线后面的图像。