自定义JComponent(一条线)未显示在JPanel上 [英] Custom JComponent (A Line) Doesn't Show Up On JPanel

查看:61
本文介绍了自定义JComponent(一条线)未显示在JPanel上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

It shows the line without jpanel on jframe, but it doesn't when I add it to jpanel. I've tried setting the layout manager of jpanel to null but no result. I want to use JComponents for drawing lines because I want them clickable.

Main.java文件:

Main.java file:

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

推荐答案

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

It shows the line without jpanel on jframe, but it doesn't when I add it to jpanel

Swing组件负责确定自己的首选大小.

Swing components are responsible for determining their own preferred size.

将组件添加到面板时,布局管理器将根据布局管理器的规则设置组件的大小/位置.

When you add a component to a panel, the layout manager will then set the size/location of the component based on the rules of the layout manager.

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

When you add a component to the frame you really add it to the content pane of the frame which is a Jpanel which uses a BorderLayout by default. So the component is sized to fill the space available in the frame.

panel.setLayout(null);

然后将组件添加到具有空布局的面板中.现在,您负责设置组件的大小/位置.如果您不设置尺寸,则为(0,0),因此无需绘制任何内容.

You then added the component to a panel with a null layout. Now you are responsible for setting the size/location of the component. If you don't the size is (0, 0) so there is nothing to paint.

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

You should override the getPreferredSize() method of your class to return the preferred size of the component. Then layout managers can do their job.

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

If you really need a null layout, then the size of the component should be set in the application code, not it the Line class itself.

但是现在我的生产线有一个很大的容器,可以监听所有点击,

But now my line has a big container that listens for any clicks,

如果要检测击中,则可以覆盖contains(...)方法.

If you want hit detection then you override the contains(...) method.

这是实现以上建议的基本示例:

Here is a basic example implementing the above suggestions:

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

这篇关于自定义JComponent(一条线)未显示在JPanel上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆