问题描述
它显示了在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");
}
});
}
}
推荐答案
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.
如果要检测击中,则可以覆盖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上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!