JPanel仅显示添加的第一个自定义JComponent

时间:2019-01-20 00:15:44

标签: java swing graphics jpanel jcomponent

我编写了一个在屏幕上绘制三角形的程序。但是,仅显示第一个三角形。如何使多个自定义JComponent可见?

我已经尝试创建类似customers deleted的方法,但是后来我无法像i一样对此对象执行任何操作。 e。我希望每次单击三角形时颜色都会改变。为此,我需要一个draw(),但是它不适用于MouseListener方法。

View.java文件:

draw()

Triangle.java文件:

package test;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class View extends JPanel {

public View()
{


    setPreferredSize(new Dimension(300, 300));
    add(new Triangle(20, 50, Color.red)); //this one will react to mouseClicked
    add(new Triangle(100, 200, Color.pink)); //this one doesn't appear

}


public static void main(String []args)
{
    JFrame frame = new JFrame("Trianlge test");
    frame.add(new View());
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

}


public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Triangle p3 = new Triangle(60, 120, Color.blue); //this one won't react to mouseClicked()
    p3.draw(g);
}
}

2 个答案:

答案 0 :(得分:0)

JFrame frame = new JFrame();

首先,完全不需要View类中的该语句。您不会在组件的构造函数中创建JFrame实例。同样,您的代码也永远不会引用该变量,这很好地表明了不需要它。

但是,主要问题是您创建自定义组件的概念是错误的:

setPreferredSize(new Dimension(100, 100));

您尝试设置组件的首选大小。

add(new Triangle(100, 200, Color.pink)); //this one doesn't appear

但是随后您尝试自定义绘画尺寸(100,200),这超出了组件的大小。因此,绘制逻辑限制了组件的大小,因此您看不到任何要绘制的东西。

自定义绘制应该相对于组件的(0,0),而不是相对于父组件完成。

如果要在父面板上随机放置组件,则需要:

  1. 将父面板设置为使用空布局
  2. 设置添加到面板中每个组件的位置
  3. 设置添加到面板中每个组件的大小。

基本上,您需要接管布局管理器的功能。

您当前的绘画代码存在其他问题:

  1. 不要在绘画方法中调用repaint()。这本质上将导致无限的绘画循环。如果需要动画,则可以使用Swing计时器来安排动画。

  2. 不要直接调用paintComponent(...)。需要重绘组件时,Swing将调用paintComponent()。

但是,我建议,如果要在面板上绘制“形状”,则无需创建自定义组件。相反,您保留要绘制的Shapes的ArrayList,然后在面板的paintComponent()方法中遍历ArrayList以绘制每个形状。

有关此方法的示例,请查看在Custom Painting Approaches中找到的Draw On Component示例。

注意:

如果您确实希望能够处理鼠标事件,则需要使用Shape对象来表示您的形状以进行正确的命中检测。如果仅将形状显示为组件,则在组件的矩形区域中的任意位置单击,而不仅仅是实际绘制的三角形,都会检测到鼠标点击。 Shape类具有一个contains(...)方法,可用于确定您是否实际上单击了Shape。

请查看Playing With Shapes,以获取有关此概念的更多信息。

答案 1 :(得分:0)

public Triangle(int x, int y, Color c) { this.x = x; this.y = y; this.c = c; setPreferredSize(new Dimension(100, 100)); addMouseListener(this); // Set this border to see the boundaries of this component. // When you are done, you may remove this. setBorder(BorderFactory.createLineBorder(Color.black)); } 个组件设置边框,如下所示:

p3

然后,您可以更好地了解组件的范围。

粉红色三角形不可见,因为它在组件的边界之外。

p3三角形对鼠标的点击没有反应,因为它只是一个图形。只有组件会对鼠标和其他事件做出反应。

请注意,组件为矩形。因此,您添加的鼠标侦听器可在组件上的任何位置工作;不仅在三角形区域。

在此程序中,您以两种方式绘制三角形。
1.添加三角形组件。 (例如“ add(new Triangle(20,50,Color.red));”)
2.通过paintComponent()方法绘制docker rm "$(docker ps -q -f status=exited )"

从软件设计的角度来看,最好坚持一种方法。否则可能会造成混乱并且容易出错。