Java 自定义JComponent(一行)不';我不会出现在JPanel上

Java 自定义JComponent(一行)不';我不会出现在JPanel上,java,swing,user-interface,java-2d,Java,Swing,User Interface,Java 2d,它显示了jframe上没有jpanel的行,但是当我将它添加到jpanel时,它没有显示。我尝试将jpanel的布局管理器设置为null,但没有结果。我想使用JComponents绘制线条,因为我希望它们可以单击 Main.java文件: import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.Mo

它显示了jframe上没有jpanel的行,但是当我将它添加到jpanel时,它没有显示。我尝试将jpanel的布局管理器设置为null,但没有结果。我想使用JComponents绘制线条,因为我希望它们可以单击

Main.java文件:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(500, 500);

    //Parent Panel
    JPanel panel = new JPanel();
    panel.setBackground(Color.YELLOW);
    panel.setLayout(null);

    //Add Line To Panel
    Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

    panel.add(line);
    panel.repaint();

    frame.add(panel);
    frame.setVisible(true);
  }
}

class Line extends JComponent {

   private final Point2D start, end;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLUE);
        g2.setStroke(new BasicStroke(2.0F));
        g2.draw(new Line2D.Double(start,end));
    }

    public Line( Point2D start, Point2D end){
        this.start = start;
        this.end = end;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouse clicked");
            }
        });
    }
}

在行构造函数中添加自定义大小。

公共行(点2D开始,点2D结束){…

this.setSize(200200);}

更新后也适用于
绘制的图形

建议从
JComponent
更改为
JPanel
,以便查看
背景

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(500, 500);

    //Parent Panel
    JPanel panel = new JPanel();
    panel.setSize(300,300);
    frame.add(panel);
    panel.setBackground(Color.YELLOW);
    panel.setLayout(null);

    //Add Line To Panel
    Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));
    panel.add(line);

    frame.setVisible(true);
  }
}

class Line extends JPanel {

   private final Point2D start, end;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setBackground(Color.RED);
        g2.setColor(Color.BLUE);
        g2.setStroke(new BasicStroke(2.0F));
        g2.draw(new Line2D.Double(start,end));
        Rectangle r = g2.getClipBounds();
        System.out.println(r.x+":"+r.y);
    }

    public Line( Point2D start, Point2D end){

        this.start = start;
        this.end = end;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouse clicked at "+e.getX()+":"+e.getY());

            }
        });
        int max_x = (int) Math.max(start.getX(), end.getX());
        int max_y = (int) Math.max(start.getY(), end.getY());
        System.out.println("max x="+max_y+",y="+max_y);
        setSize(max_x,max_y);
        setVisible(true);
        setBackground(Color.GREEN);
    } 
}


注意:只允许内部绿色点击

在行构造函数中添加自定义大小。

公共行(点2D开始,点2D结束){…

this.setSize(200200);}

更新后也适用于
绘制的图形

建议从
JComponent
更改为
JPanel
,以便查看
背景

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(500, 500);

    //Parent Panel
    JPanel panel = new JPanel();
    panel.setSize(300,300);
    frame.add(panel);
    panel.setBackground(Color.YELLOW);
    panel.setLayout(null);

    //Add Line To Panel
    Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));
    panel.add(line);

    frame.setVisible(true);
  }
}

class Line extends JPanel {

   private final Point2D start, end;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setBackground(Color.RED);
        g2.setColor(Color.BLUE);
        g2.setStroke(new BasicStroke(2.0F));
        g2.draw(new Line2D.Double(start,end));
        Rectangle r = g2.getClipBounds();
        System.out.println(r.x+":"+r.y);
    }

    public Line( Point2D start, Point2D end){

        this.start = start;
        this.end = end;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouse clicked at "+e.getX()+":"+e.getY());

            }
        });
        int max_x = (int) Math.max(start.getX(), end.getX());
        int max_y = (int) Math.max(start.getY(), end.getY());
        System.out.println("max x="+max_y+",y="+max_y);
        setSize(max_x,max_y);
        setVisible(true);
        setBackground(Color.GREEN);
    } 
}

注意:只允许内部绿色点击

它在jframe上显示了没有jpanel的行,但当我将它添加到jpanel时,它没有显示

Swing组件负责确定自己的首选尺寸

将构件添加到配电盘时,布局管理器将根据布局管理器的规则设置构件的大小/位置

将组件添加到框架时,实际上是将其添加到框架的内容窗格中,该框架是默认使用
BorderLayout
Jpanel
。因此,构件的大小可以填充框架中的可用空间

panel.setLayout(null);
然后将组件添加到具有空布局的面板中。现在,您负责设置组件的大小/位置。如果不知道,则大小为(0,0),因此没有任何可绘制的内容

您应该重写类的
getPreferredSize()
方法以返回组件的首选大小。然后,布局管理员可以完成他们的工作

如果您确实需要一个空布局,那么组件的大小应该在应用程序代码中设置,而不是在Line类本身中设置

但现在我的线路有一个大容器,可以监听任何点击

如果需要命中检测,则覆盖
contains(…)
方法

以下是实施上述建议的基本示例:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Line extends JComponent
{
   private Line2D.Double line;

    public Line( Point2D start, Point2D end)
    {
        line = new Line2D.Double(start, end);

        addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                System.out.println("mouse clicked");
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setColor( Color.BLUE );
        g2.setStroke( new BasicStroke(2.0F) );
        g2.draw( line );
    }

    @Override
    public Dimension getPreferredSize()
    {
        Rectangle bounds = line.getBounds();

        int width = bounds.x + bounds.width;
        int height = bounds.y + bounds.height;

        return new Dimension(width, height);
    }

    @Override
    public boolean contains(int x, int y)
    {
        double distance = line.ptSegDist( new Point2D.Double(x, y) );

        return distance < 2;
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);

        //Parent Panel
        JPanel panel = new JPanel();
        panel.setBackground(Color.YELLOW);

        //Add Line To Panel
        Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

        panel.add(line);
        panel.repaint();

        frame.add(panel);
        frame.setVisible(true);
    }
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.Line2D;
导入java.awt.geom.Point2D;
导入java.awt.Rectangle;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类行扩展了JComponent
{
专用线路2D。双线;
公用线(点2D起点、点2D终点)
{
line=新Line2D.Double(开始、结束);
addMouseListener(新的MouseAdapter()
{
@凌驾
公共无效mouseClicked(MouseEvent e)
{
System.out.println(“鼠标点击”);
}
});
}
@凌驾
受保护组件(图形g)
{
超级组件(g);
图形2d g2=(图形2d)g;
g2.setColor(Color.BLUE);
g2.设定行程(新基本行程(2.0F));
g2.画(线);
}
@凌驾
公共维度getPreferredSize()
{
矩形边界=line.getBounds();
int width=bounds.x+bounds.width;
int height=bounds.y+bounds.height;
返回新尺寸(宽度、高度);
}
@凌驾
公共布尔包含(int x,int y)
{
双距离=line.ptSegDist(新点2d.double(x,y));
返回距离<2;
}
公共静态void main(字符串[]args)
{
JFrame=新JFrame();
frame.setDefaultCloseOperation(关闭时退出frame);
框架。设置尺寸(500500);
//父面板
JPanel面板=新的JPanel();
面板.立根背景(颜色.黄色);
//将线添加到面板
直线=新线(新点2D.Double(20,20),新点2D.Double(180180));
面板。添加(行);
panel.repaint();
框架。添加(面板);
frame.setVisible(true);
}
}
它在jframe上显示了没有jpanel的行,但当我将它添加到jpanel时,它没有显示

Swing组件负责确定自己的首选尺寸

将构件添加到配电盘时,布局管理器将根据布局管理器的规则设置构件的大小/位置

将组件添加到框架时,实际上是将其添加到框架的内容窗格中,该框架是默认使用
BorderLayout
Jpanel
。因此,构件的大小可以填充框架中的可用空间

panel.setLayout(null);
然后将组件添加到具有空布局的面板中。现在,您负责设置组件的大小/位置。如果不知道,则大小为(0,0),因此没有任何可绘制的内容

您应该重写类的
getPreferredSize()
方法以返回组件的首选大小。然后,布局管理员可以完成他们的工作

如果您确实需要一个空布局,那么组件的大小应该在应用程序代码中设置,而不是在Line类本身中设置

但现在我的线路有一个大容器,可以监听任何点击

如果需要命中检测,则覆盖
contains(…)
方法

以下是实施上述建议的基本示例:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Line extends JComponent
{
   private Line2D.Double line;

    public Line( Point2D start, Point2D end)
    {
        line = new Line2D.Double(start, end);

        addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                System.out.println("mouse clicked");
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setColor( Color.BLUE );
        g2.setStroke( new BasicStroke(2.0F) );
        g2.draw( line );
    }

    @Override
    public Dimension getPreferredSize()
    {
        Rectangle bounds = line.getBounds();

        int width = bounds.x + bounds.width;
        int height = bounds.y + bounds.height;

        return new Dimension(width, height);
    }

    @Override
    public boolean contains(int x, int y)
    {
        double distance = line.ptSegDist( new Point2D.Double(x, y) );

        return distance < 2;
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);

        //Parent Panel
        JPanel panel = new JPanel();
        panel.setBackground(Color.YELLOW);

        //Add Line To Panel
        Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

        panel.add(line);
        panel.repaint();

        frame.add(panel);
        frame.setVisible(true);
    }
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.Line2D;
导入java.awt.geom.Point2D;
导入java.awt.Rectangle;
接口信息处理器