【问题标题】:about drawing a Polygon in java关于在java中绘制多边形
【发布时间】:2013-02-17 18:07:02
【问题描述】:

您好,我正在努力提高自己对 java2D 的了解,首先我正在处理绘制多边形。但是,我看不到框架上的多边形。我阅读了一些教程和示例,但正如我所说,我遇到了问题。这是绘制多边形的示例代码;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;

import javax.swing.JFrame;

public class jRisk extends JFrame {


    private JFrame mainMap;
    private Polygon poly;

    public jRisk(){

        initComponents();

    }

    private void initComponents(){

        mainMap = new JFrame();
        mainMap.setSize(800, 600);
        mainMap.setResizable(false);

        mainMap.setVisible(true);
        mainMap.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        int xPoly[] = {150,250,325,375,450,275,100};
        int yPoly[] = {150,100,125,225,250,375,300};

        poly = new Polygon(xPoly, yPoly, xPoly.length);

    }

    protected void paintComponent(Graphics g){

        super.paintComponents(g);

        g.setColor(Color.BLUE);
        g.drawPolygon(poly);

    }   

    /**
     * @param args
     */
    public static void main(String[] args) {

        new jRisk();

    }

}

【问题讨论】:

    标签: java swing polygon java-2d paintcomponent


    【解决方案1】:

    JFrame 不会扩展 JComponent,因此不会覆盖 paintComponent。您可以通过添加 @Override 注释来检查这一点。

    要获得此功能,请将paintComponent 提取到扩展JComponent 的新类中。不要忘记拨打super.paintComponent(g) 而不是super.paintComponents(g)

    【讨论】:

    • 好的,但在这里http://stackoverflow.com/questions/15167342/arrayindexoutofboundsexception-error-while-drawing-a-polygon @camickr 说如果我要使用swing,我应该使用paintComponent()?
    【解决方案2】:

    替换

    protected void paintComponent(Graphics g){
    
        super.paintComponents(g);
    
        g.setColor(Color.BLUE);
        g.drawPolygon(poly);
    
    }   
    

    protected void paint(Graphics g){
    
        super.paint(g);
    
        g.setColor(Color.BLUE);
        g.drawPolygon(poly);
    
    }  
    

    【讨论】:

    • 好吧,我使用的是paint()方法,但是有人告诉我如果我要使用swing而不是awt,我应该覆盖paintComponent()
    • 好的,现在它说我覆盖了paint方法但是它不显示多边形
    【解决方案3】:

    JFrame 没有paintComponent(Graphics g) 方法。添加@Override annotation,你会得到一个编译时错误。

    1) 使用JPanel 并覆盖paintComponent(您可以将JPanel 添加到JFrame 通过JFrame#add(..)

    2) 覆盖 getPreferredSize() 以返回正确的 Dimensions,它适合您在 Graphics 对象上的绘图,否则它们不会被视为 JPanel 没有组件的大小为 0,0

    3) 不要在JFrame 上调用setSize...而是使用正确的LayoutManager 和/或覆盖getPrefferedSize() 并在添加所有组件之后但在设置为可见之前在JFrame 上调用pack()

    4) 阅读Concurrency in Swing,特别是关于Event Dispatch Thread

    5) 手表类命名方案应该以大写字母开头,之后的每个新单词的第一个字母都应该大写

    6) 你也有extend JFrame 并且有一个变量JFrame?去掉 extend JFrame 并保留 JFrame 变量,因为我们不想要 2 个 JFrames 并且扩展 JFrame 不是好的做法,除非添加功能

    这是您的代码,上面已修复(请原谅图片质量,但必须调整大小,否则将变为 800x600):

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Polygon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class JRisk {
    
        private JFrame mainMap;
        private Polygon poly;
    
        public JRisk() {
    
            initComponents();
    
        }
    
        private void initComponents() {
    
            mainMap = new JFrame();
            mainMap.setResizable(false);
    
            mainMap.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            int xPoly[] = {150, 250, 325, 375, 450, 275, 100};
            int yPoly[] = {150, 100, 125, 225, 250, 375, 300};
    
            poly = new Polygon(xPoly, yPoly, xPoly.length);
            JPanel p = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(Color.BLUE);
                    g.drawPolygon(poly);
                }
    
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(800, 600);
                }
            };
            mainMap.add(p);
            mainMap.pack();
            mainMap.setVisible(true);
    
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new JRisk();
                }
            });
        }
    }
    

    根据您的评论:

    我正在准备一张包含许多多边形的地图,昨天我 在 JFrame 上使用了 JPanel,我试图检查鼠标是否在里面 与 MouseListener 的多边形。后来我看到mouseListener给了 错误响应(就像鼠标不在多边形内但它起作用 就像它在多边形内一样)。所以我删除了JPanel然后它 工作过

    这里是带有MouseAdapter 和覆盖mouseClicked 的更新代码,以检查点击是否在多边形内。

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Polygon;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class JRisk {
    
        private JFrame mainMap;
        private Polygon poly;
    
        public JRisk() {
            initComponents();
        }
    
        private void initComponents() {
    
            mainMap = new JFrame();
            mainMap.setResizable(false);
    
            mainMap.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            int xPoly[] = {150, 250, 325, 375, 450, 275, 100};
            int yPoly[] = {150, 100, 125, 225, 250, 375, 300};
    
            poly = new Polygon(xPoly, yPoly, xPoly.length);
    
            JPanel p = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(Color.BLUE);
                    g.drawPolygon(poly);
                }
    
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(800, 600);
                }
            };
    
            MouseAdapter ma = new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent me) {
                    super.mouseClicked(me);
    
                    if (poly.contains(me.getPoint())) {
                        System.out.println("Clicked polygon");
                    }
    
                }
            };
            p.addMouseListener(ma);//add listener to panel
            mainMap.add(p);
    
            mainMap.pack();
            mainMap.setVisible(true);
    
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new JRisk();
                }
            });
        }
    }
    

    【讨论】:

    • 其实我正在准备一张包含大量多边形的地图,昨天我在 JFrame 上使用了 JPanel,我尝试使用 MouseListener 检查鼠标是否在多边形内。后来我看到 mouseListener 给出了错误的响应(就像鼠标不在多边形内,但它的行为就像它在多边形内一样)。所以我删除了JPanel,然后它就起作用了。
    • @quartaela 问题不在于 JPanel IMO,而是在其他地方
    • 你是完美的!多谢。我可以再问一个问题吗?调用new JRisk() 和在run() 方法中调用它有什么区别。差别这么大吗?我猜它与并发有关?
    • 很高兴帮助...是的,它与并发有关。所有 Swing 组件都应该在 Event Dispatch Thread 上创建和操作。 SwingUtilities.invokeXXX 块为我们做到了 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2011-12-30
    • 2012-01-07
    • 2016-05-20
    • 2015-01-01
    相关资源
    最近更新 更多