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

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


我已经尝试创建类似draw()方法的东西,但是我无法对这个对象执行任何操作,例如,我希望在单击它时更改三角形的颜色。为此,我需要 aMouseListener但它不适用于该draw()方法。


查看.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);

}

}

三角.java 文件:


    package test;


import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.geom.GeneralPath;


import javax.swing.JComponent;


public class Triangle extends JComponent implements MouseListener{


private int x,y;

private Color c;

public Triangle(int x, int y, Color c)

{

    this.x = x;

    this.y = y;

    this.c = c;

    setPreferredSize(new Dimension(100, 100));

    addMouseListener(this);

}


public void paintComponent(Graphics g)

{

    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D) g;

    GeneralPath path = new GeneralPath();


    g2d.setColor(c);

    path.moveTo(x, y);

    path.lineTo(x, y);

    path.lineTo(x+50, y);

    path.lineTo(x, y-50);

    path.closePath();

    g2d.fill(path);

    repaint();

}


ITMISS
浏览 192回答 2
2回答

墨色风雨

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了解有关此概念的更多信息。

GCT1015

为组件设置边框,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()从软件设计的角度来看,最好坚持一种方法。否则,它可能会令人困惑并且容易出错。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java