【问题标题】:Java - jpanel not showing all componentsJava - jpanel 未显示所有组件
【发布时间】:2014-03-31 14:43:30
【问题描述】:

我的应用遇到了令人沮丧的问题。我想要的(在提供的示例中)是 3 个填充矩形,如下所示:

##
 #

唉,只画了左上角的矩形。这是我的代码的 sscce 版本:

import static java.lang.System.out;
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;

public class Main {
    public static void main(String args[]) {
        Map map = new Map();

        Point[] poly1 = new Point[] { new Point(10, 10), new Point(40, 10), new Point(40, 40), new Point(10, 40) };
        Point[] poly2 = new Point[] { new Point(50, 10), new Point(80, 10), new Point(80, 40), new Point(50, 40) };
        Point[] poly3 = new Point[] { new Point(50, 50), new Point(80, 50), new Point(80, 80), new Point(50, 80) };

        Point[][] polys = new Point[][] { poly1, poly2, poly3 };

        ShowWindow(polys);
    }


    private static void ShowWindow(Point[][] polys) {
        GameWindow frame = new GameWindow(polys);
        frame.setVisible(true);
    }
}

class GameWindow extends JFrame {   
    public GameWindow(Point[][] polys) {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        MapPanel panel = new MapPanel(polys);
        Container c = getContentPane();
        c.setPreferredSize(panel.getPreferredSize());
        add(panel);
        pack();
    }
}

class MapPanel extends JPanel { 
    public MapPanel(Point[][] polys) {
        setLayout(null);
        for (Point[] poly : polys) {
            CountryPolygon boundaries = new CountryPolygon(poly);
            add(boundaries);
        }
        setBounds(0, 0, 800, 600);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(getBounds().width, getBounds().height);
    }
}

class CountryPolygon extends JComponent {
    private Path2D.Double CountryBounds;

    public CountryPolygon(Point[] points) {
        CountryBounds = GetBoundaries(points);
        setBounds(CountryBounds.getBounds());
    }

    private Path2D.Double GetBoundaries(Point[] points) {       
        Path2D.Double bounds = new Path2D.Double();
        bounds.moveTo(points[0].x, points[0].y);
        for(Point p : points) {
            if(p == points[0]) continue;
            bounds.lineTo(p.x, p.y);
        }
        bounds.closePath();

        return bounds;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g.create();
        g2.setColor(new Color(175, 100, 175));
        g2.fill(CountryBounds);
        g2.dispose();
    }

}

我的真实代码不太像这样,但问题却大同小异。您可能想知道为什么我不使用布局管理器。嗯,我正在尝试创建一个类似 RISK 的游戏,所以我有很多不规则的形状,它们必须都在正确的位置。

我对 Java 还是很陌生,通过谷歌搜索我找不到一个类似的问题。

感谢您的帮助!

【问题讨论】:

    标签: java swing drawing custom-component


    【解决方案1】:

    您的自定义绘画在 CountryPolygon 类中完成。由于您使用的是空布局,因此这些组件的默认大小为 (0, 0),因此多边形的绘制是在类的边界之外完成的,没有什么可看的。

    您需要设置每个组件的大小。

    不确定,但也许您可以使用Custom Painting Approaches 中的方法。 DrawOnComponent 示例保留要绘制的 ArrayList 矩形。在您的情况下,您可以将其更改为用于保存 Shape 对象,然后使用 Graphics2D 的 fillShape(...) 方法进行绘画。

    编辑:

    (30, 30) 的宽度/高度仍然是错误的

    Point[] poly2 = new Point[] { new Point(50, 10), new Point(80, 10), new Point(80, 40), new Point(50, 40) };
    

    您正在使用 (80, 10) 之类的点,它远远超出 (30, 30) 的大小。您确实需要将每个组件的大小设置为父面板的大小。

    【讨论】:

    • 这是不正确的:我在 CountryPolygon 类中调用 setBounds(),它设置了组件的大小和组件的位置。为了验证这一点,我从类内部调用了 System.out.println(getSize()),从 MapPanel 类的 for 循环调用了 System.out.println(boundaries.getSize())。对于所有创建的组件,两者都返回了 width=30 height=30,这是正确的。
    • 将所有对象的大小调整为 800x600 可使所有组件按预期可见。但是,我不明白这一点。如果我的 jpanel 的大小是 800x600,而我的代码使 poly1 的大小为 30x30 并且位置 x=10 y=10,那么为什么组件超出范围?
    • @OlaviMustanoja,从绘画的角度来看,位置无关紧要。绘制方法相对于组件进行绘制,而不是组件位置。因此,如果您想在 (80, 50) 处绘制一个点,则大小必须至少为 (80, 50)。查看Playing With Shapes。您可以使用ShapeComponent。此类将 x/y 偏移量转换回 (0, 0),因此该位置现在将控制组件的位置及其绘制。如果您曾经对组件进行“点击检测”,这一点很重要。
    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多