Java:通过静态调整大小和定位将 JComponent 添加到 JPanel

发布于 2024-11-01 14:33:02 字数 1708 浏览 5 评论 0原文

我有一个程序可以在 java 应用程序中读取和绘制 SVG 文件,而无需使用第三方库。我已经达到了可以通过将形状绘制到图形对象上来复制文件的程度,但是我想通过将侦听器应用于每个对象来使每个元素(矩形/圆形/直线等)可供选择。

为此,我的印象是,我需要创建一个扩展 JComponent 的类,在组件内绘制对象,并为要显示的每个元素添加一个侦听器。因此,我将拥有一组带有附加侦听器的容器组件(如果您可以这么称呼它们),每个组件都对应于文件中的特定元素。

然后,我需要将这些组件绘制到 JPanel 或合适的容器上,但是为此,我需要使用空布局并手动设置 JPanel/Container 中每个组件的位置和大小。

所以总而言之,虽然这正是我想要做的,但我想知道是否有一种更标准化的方法来向我不知道的图形对象添加侦听器?

这是我希望使用上述方法扩展的相关代码示例,我已经对其进行了很多简化,所以我希望它仍然有意义

public class View extends JComponent implements SVGViewport {

    // Model of the SVG document
    private SVGDocument document;

    /** Paint method */
    @Override
    protected void paintComponent(Graphics g) {
        paint2D((Graphics2D) g);
    }

    /** Paints the entire view */
    private void paint2D(Graphics2D g) {
        // Paint Document properties
        ....

        // Paint document Elements
        for (SVGElement elem : document) {  
            paintElement(g, elem);
        }
    }

    /** Paints a single element on the graphics context */
    public void paintElement(Graphics2D g, SVGElement elem) {

        //Get a drawable shape object for this element
        Shape shape = elem.createShape();

        //Set Fill, stroke, etc attributes for this shape
        ....
        // Fill the interior of the shape
        ....
        // Stroke the outline of the shape
        ....
        g.draw(shape);
    }

    /** Gets the document currently being displayed by the view. */
    public SVGDocument getDocument() {
        return document;
    }

    /** set and re-paint the document */
    public void setDocument(SVGDocument document) {
        this.document = document;
        repaint();
    }
}

I have a program that reads and draws an SVG file in a java application without the use of third party libraries. I have gotten to the point where I can replicate the file by drawing shape's onto a graphics object, however I would like to make each element (Rect/Circle/Line etc) selectable by applying listeners to each Object.

To do so I am under the impression I need to create a Class that extends JComponent, draws the Object within the component and adds a listener to it for each element that is to be displayed. So I would have a group of container components(if you can call them that) with listeners attached, each corresponding to a particular element in the file.

I then need to draw these components onto a JPanel or suitable Container, however to do so i would need to use a null layout and set the positions and size of each component within the JPanel/Container manually.

So in conclusion although this is exactly what I want to do, I am wondering if there is a more standardized approach to adding listeners to Graphics Objects that I am not aware of?

Here is a sample of the code in question that I am looking to extend by using the above approach, I've simplified it alot so I hope it still makes sense

public class View extends JComponent implements SVGViewport {

    // Model of the SVG document
    private SVGDocument document;

    /** Paint method */
    @Override
    protected void paintComponent(Graphics g) {
        paint2D((Graphics2D) g);
    }

    /** Paints the entire view */
    private void paint2D(Graphics2D g) {
        // Paint Document properties
        ....

        // Paint document Elements
        for (SVGElement elem : document) {  
            paintElement(g, elem);
        }
    }

    /** Paints a single element on the graphics context */
    public void paintElement(Graphics2D g, SVGElement elem) {

        //Get a drawable shape object for this element
        Shape shape = elem.createShape();

        //Set Fill, stroke, etc attributes for this shape
        ....
        // Fill the interior of the shape
        ....
        // Stroke the outline of the shape
        ....
        g.draw(shape);
    }

    /** Gets the document currently being displayed by the view. */
    public SVGDocument getDocument() {
        return document;
    }

    /** set and re-paint the document */
    public void setDocument(SVGDocument document) {
        this.document = document;
        repaint();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

银河中√捞星星 2024-11-08 14:33:02

JLayeredPane 是传统方法,如本示例所示。使用 paintComponent() 的替代方法可以在 GraphPanel 中看到

附录:关于 JLayeredPane< /a>,另请参阅此 教程,此相关示例,以及此变化

A JLayeredPane is the traditional approach, as seen in this example. An alternative approach using paintComponent() may be seen in GraphPanel.

Addendum: Regarding JLayeredPane, see also this tutorial, this related example, and this variation.

木落 2024-11-08 14:33:02

OOdium,

您所描述的当然听起来很合理,而且据我所知,2D API 中没有对事件的本机支持。如果视觉元素之间存在重叠,您必须小心。另一种方法是在画布(Z 顺序或玻璃窗格)顶部放置一个 JComponent ,负责确定单击了哪个项目,然后触发相应的事件。如果存在重叠的视觉实体,这可能是必要的。以下是 Sun 提供的分层文档: http://download.oracle .com/javase/tutorial/uiswing/components/rootpane.html

不过,我不是一个图形专家,考虑到程序员想要做你想做的事情的频率,我希望有一个标准的解决方案来满足你的要求做。您可能想尝试在 Google 上搜索用 Java 构建的 2D 游戏,看看是否可以学习他们的做法。

问候,

吉多

OOdium,

What you describe certainly sounds reasonable and, to my knowledge, there is not native support for events in the 2D API. You will have to be careful if there is overlap between the visual elements. Another way to go about it would be to have a JComponent on top of the canvas (Z-order or Glass Pane) that is responsible for determining which item was clicked and then firing the appropriate event. This might be necessary if there are overlapping visual entities. Here is the docs from Sun for the layering: http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html

I am not a graphics guy though and I expect there is a standard solution to your requirements given how often that a programmer would want to do what you want to do. You might want to try googling for 2D games built in Java and see if you can learn from what they did.

Regards,

Guido

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文