自定义的 JComponent 在自定义的 JPanel 中无法显示

3

我尝试了 add() 方法,但在试图将 Test 添加到 GraphicsTest 时未显示任何内容。 我应该如何添加它? 能否有人给我演示一下? 我已经包含了我正在使用的代码。

这是我的方式,但它不起作用。 能否有人向我展示或让我知道实际问题是什么?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;

public class Test extends JComponent
{
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.red);
        g2d.drawString("Hello", 50, 50);
        g2d.dispose();
    }
}

这是另一个类:

   import java.awt.Color;
   import java.awt.Graphics;
   import java.awt.Graphics2D;
   import java.awt.geom.Rectangle2D;
   import javax.swing.JPanel;

   public class GraphicsTest extends JPanel
   {
       private Graphics2D g2d;
       private String state;
       private int x, y;

   GraphicsTest()
   {
       Test t = new Test();
       t.setVisible(true);
       add(t);
   }

   @Override
   public void paintComponent(Graphics g)
   {
       super.paintComponent(g);
       g2d = (Graphics2D) g;

       g2d.setColor(Color.BLACK);
       g2d.drawString("STATE: " + state, 5, 15);
       g2d.drawString("Mouse Position: " + x + ", " + y, 5, 30);

       g2d.setColor(Color.red);
       Rectangle2D r2d = new Rectangle2D.Double(x, y, 10, 10);
       g2d.draw(r2d);

       g2d.dispose();
    }

    public void setState(String state) { this.state = state; }
    public String getState() { return state; }
    public void setX(int x) { this.x = x; repaint(); }
    public void setY(int y) { this.y = y; repaint(); }
}

那段代码对我来说运行良好,尽管当然我必须创建一个JFrame并将GraphicsTest添加到其中。 - Michael Myers
你看到Test对象“hello”了吗? - anon235370
1个回答

1

你的问题在于 g2d.dispose()。把它们移除,就可以解决了。我怀疑这可能会导致不同 jvm 上的不同行为。似乎发生的情况是 g2d 对象用于在 GraphicsTest 对象上绘制东西。然后同一个 g2d 对象试图在 Test 对象上绘制东西,但已经被处理掉了,所以不能绘制任何东西。有些情况下需要调用 g2d.dispose(),但这不是其中之一。

我为使您的代码正常工作还做了另一件事,那就是更改布局管理器:

setLayout(new BorderLayout());
add(t, BorderLayout.CENTER);

默认布局应该是流式布局。我不确定为什么它不能与流式布局一起工作。


我已经尝试了您的建议并删除了两个g2d.dispose(); 但仍无效。 - anon235370
1
哎呀,实际上我在代码中做了两个更改才使它工作。我没想到另一个更改会有影响。 - Jay Askren
谢谢!终于可以用了!我花了一整天的时间来尝试解决这个问题...Sun公司正在修复这个烦人的问题吗?还是有其他地方有记录? - anon235370
1
我不确定为什么 Flow Layout 不起作用。我的猜测是与未设置 Test 实例的大小有关。 - Jay Askren
1
+1 发现 dispose()。关于 Flow Layout 也正确。在 Test 中覆盖 getPreferredSize() 并检查 super.getPreferredSize() - trashgod
我尝试设置preferredSize,这应该基本上做同样的事情。但似乎没有起作用。 - Jay Askren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接