2 回答

TA贡献1853条经验 获得超6个赞
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) 进行,而不是相对于父组件。
如果您想在父面板上随机定位组件,那么您需要:
将父面板设置为使用空布局
设置您添加到面板的每个组件的位置
设置添加到面板的每个组件的大小。
基本上你需要接管布局管理器的功能。
您当前的绘画代码的其他问题:
不要在绘画方法中调用 repaint()。这基本上会导致无限的绘画循环。如果您需要动画,您可以使用 Swing Timer 来安排动画。
不要直接调用paintComponent(...)。当组件需要重新绘制时,Swing 将调用paintComponent()。
但是,我建议如果您想在面板上绘制形状,那么您就忘记了创建自定义组件。相反,您保留要绘制的形状的 ArrayList,然后在面板的 paintComponent() 方法中遍历 ArrayList 以绘制每个形状。
有关此方法的示例,请查看自定义绘画方法Draw On Component
中的示例。
笔记:
如果您真的希望能够处理鼠标事件,那么您需要使用 Shape 对象来表示您的形状以进行正确的命中检测。如果您只是将您的形状显示为一个组件,那么如果您单击组件矩形区域中的任何位置,就会检测到鼠标点击,而不仅仅是您实际绘制的三角形部分。该类Shape
有一个 contains(...) 方法,您可以使用该方法来确定您是否实际单击了 Shape。
查看Playing With Shapes了解有关此概念的更多信息。

TA贡献1827条经验 获得超4个赞
为组件设置边框,Triangle如下所示:
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三角形不会对鼠标点击做出反应,因为它只是一个绘图。只有组件对鼠标和其他事件做出反应。
请注意,组件的形状是矩形。因此,您添加的鼠标侦听器可以在组件的任何位置工作;不仅在三角形区域。
您在这个程序中以两种方式绘制三角形。
1. 通过添加三角形组件。(如“add(new Triangle(20, 50, Color.red));”)
2.通过绘制方法p3。paintComponent()
从软件设计的角度来看,最好坚持一种方法。否则,它可能会令人困惑并且容易出错。
添加回答
举报