当前位置: 首页 > 知识库问答 >
问题:

JComponent不绘制到JGroup

濮阳赞
2023-03-14

我有一个扩展JComponent的自定义组件,它覆盖了方法paintComponent(Graphics g),但当我尝试将其添加到我的JPanel时,它就是不起作用,什么都没有绘制。这是我的代码:

public class SimpleComponent extends JComponent{

int x, y, width, height;

public SimpleComponent(int x, int y, int width, int height){
    this.x = x;
    this.y = y;
}

@Override
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.BLACK);
    g2.fillRect(x, y, width, height);
}
}


public class TestFrame{
public static void main(String[] args){
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel.setPreferredSize(new Dimension(400, 400));
    frame.add(panel);
    frame.pack();
    frame.setResizable(false);

    SimpleComponent comp = new SimpleComponent(10, 10, 100, 100);
    panel.add(comp);
    frame.setVisible(true);
}
}

共有2个答案

穆毅然
2023-03-14

哇!绝对不是正确答案!

你犯下的第一个绝对大罪就是在一个非EDT线程中完成这一切!!!这里没有解释的空间……网上只有大约300亿个地方可以了解它。

一旦所有这些代码在EDT(事件调度线程)中的可运行状态下执行,那么:

您不需要覆盖preferredSize(尽管如果需要可以)……但您确实需要设置它。

您绝对不应该直接设置尺寸(高度和宽度,或setSize())!

您需要做的是获得java.awt。容器面板,在您的示例中,用于“布局自身”…有一种方法容器。doLayout(),但正如API文档中所说:

使该容器布局其组件。大多数程序不应直接调用此方法,而应调用validate方法。

因此,解决方案是:

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100);
comp.setPreferredSize( new Dimension( 90, 90 ) );
panel.add(comp);

// the key to unlocking the mystery
panel.validate();

frame.setVisible(true);

顺便说一句,请从我的经验中获益:我花了好几个小时努力理解所有这些验证、无效、paintComponent、paint等东西,但我仍然觉得我只触及了表面。

韩季
2023-03-14

它工作得很好——组件正在添加到JPanel中,但它有多大?如果在呈现GUI后检查此项,您可能会发现组件的大小为0,0。

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100);
panel.add(comp);
frame.setVisible(true);

System.out.println(comp.getSize());

考虑让JComponent重写getPreferredSize并返回一个有意义的维度:

public Dimension getPreferredSize() {
  return new Dimension(width, height);
}

如果您想使用x和y,您可能还希望覆盖getLocation()

编辑
您还需要设置宽度和高度字段!

public SimpleComponent(int x, int y, int width, int height) {
  this.x = x;
  this.y = y;
  this.width = width; // *** added
  this.height = height; // *** added
}
 类似资料:
  • null null 问题是,在ArrayList中有相当多的形状之后,paintComponent()方法的执行会变慢。 例如,自定义画笔。 在画布上拖动画笔时,我必须向ArrayList添加一个类型为“CustomBrush extends Shape”的新形状 所以只需一次划动,我就可以在ArrayList中得到数百个形状 问题是: 如何将100个形状对象“打包”成一个,使一次笔触成为Arra

  • 问题内容: 我几乎让repaint()Jcomponent工作了。我让它正常工作,然后 尝试进行绝对定位,但现在不起作用。 Class 2: (This is the JComponent that I am trying to set) 我将组件添加到Container中,然后将容器添加到JPanel中,然后将JPanel添加到JFrame中。我认为这 应该可行。我有设定的首选尺寸。我曾经使它工

  • 问题内容: 我正在尝试构建 Paint 应用程序,并且在DrawingArea类中做错了什么。问题是当我尝试绘制第二个形状时,第一个形状或图形是自动删除的,因此我需要一些解决方法的想法。所有答案都可以接受。感谢帮助。 有部分 DrawingArea.class 代码: 问题答案: 您需要: 将要绘制的形状存储在列表中,然后在paintComponent()方法中绘制列表中的所有形状,或者 将形状绘

  • 我在artPanel JPanel类中实现了MouseListener和MouseMotionListener。看来这解决了我的一些问题。但有几个问题: 您可以在这里下载我的java文件,以便更容易地识别问题。 我想不通的问题: “行”按钮无法正确创建行。我一直在玩mouseListener方法,但我无法使其工作。我希望它在单击和拖动鼠标的同时只画一条线。 其他按钮可以正确绘制形状。然而...当我

  • 将显示JFrame和JPanel,但paintComponent方法不在JPanel上绘制。我只看到我添加的JLabel、JTextField和JButton,而没有看到应该在JPanel上绘制的内容。

  • 介绍 (Introduction) 类JComponent是除顶级容器之外的所有Swing组件的基类。 要使用从JComponent继承的组件,必须将组件放在其根是顶级SWING容器的包含层次结构中。 Class 声明 (Class Declaration) 以下是javax.swing.JComponent类的声明 - public abstract class JComponent ex