о рисовании многоугольника в java

привет, я пытаюсь улучшить себя в 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();

    }

}

person quartaela    schedule 03.03.2013    source источник


Ответы (3)


JFrame не имеет paintComponent(Graphics g) метод. Добавьте аннотацию @Override, и вы получите компиляцию ошибка времени.

1) Используйте JPanel и переопределите paintComponent (вы бы добавили JPanel к JFrame viad JFrame#add(..))

2) Переопределите getPreferredSize(), чтобы вернуть правильные Dimension, которые соответствуют вашему рисунку на графическом объекте, иначе они не будут видны, поскольку размер JPanel без компонентов равен 0,0.

3) не вызывайте setSize для JFrame... вместо этого используйте правильный LayoutManager и/или переопределите getPrefferedSize() и вызовите pack() для JFrame после добавления всех компонентов, но перед тем, как сделать его видимым

4) Прочтите параллелизм в Swing, в частности о Поток отправки событий

5) схема именования классов часов должна начинаться с заглавной буквы, а каждая первая буква нового слова после этого должна быть заглавной

6) Также вам extend JFrame и у вас есть переменная JFrame? Уберите extend JFrame и оставьте переменную JFrame, так как нам не нужны 2 JFrame, и не рекомендуется расширять 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();
            }
        });
    }
}

Согласно вашему комментарию:

я готовлю карту, которая включает в себя множество полигонов, и вчера я использовал JPanel поверх JFrame, и я попытался проверить, была ли мышь внутри полигона с помощью 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();
            }
        });
    }
}
person David Kroukamp    schedule 03.03.2013
comment
на самом деле я готовлю карту, которая включает в себя множество полигонов, и вчера я использовал JPanel поверх JFrame, и я попытался проверить, была ли мышь внутри полигона с помощью MouseListener. позже я увидел, что mouseListener давал ложные ответы (например, мышь не находится внутри многоугольника, но ведет себя так, как будто она была внутри многоугольника). поэтому я удалил JPanel, и тогда это сработало. - person quartaela; 03.03.2013
comment
@quartaela Проблема была не в JPanel IMO, а в другом месте - person David Kroukamp; 03.03.2013
comment
ну ты идеальна!. большое спасибо. а можно еще один вопрос?. в чем разница между вызовом new JRisk() и вызовом внутри метода run(). неужели так сильно отличается. Я думаю, это имеет отношение к параллелизму? - person quartaela; 03.03.2013
comment
Рад помочь... Да, это связано с параллелизмом. Все компоненты Swing должны создаваться и управляться в потоке отправки событий. Блоки SwingUtilities.invokeXXX делают это за нас :) - person David Kroukamp; 03.03.2013

JFrame не расширяет JComponent, поэтому не переопределяет paintComponent. Вы можете проверить это, добавив аннотацию @Override.

Чтобы получить эту функциональность, извлеките paintComponent в новый класс, который расширяет JComponent. Не забудьте позвонить super.paintComponent(g), а не super.paintComponents(g).

person Reimeus    schedule 03.03.2013
comment
хорошо, но здесь http://stackoverflow.com/questions/15167342/arrayindexoutofboundsexception-error-while-drawing-a-polygon @camickr говорит, что я должен использовать paintComponent(), если я собираюсь использовать свинг? - person quartaela; 03.03.2013

Заменять

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);

}  
person christopher    schedule 03.03.2013
comment
ну, я использовал метод paint(), однако кто-то сказал, что если я собираюсь использовать свинг, а не awt, то я должен переопределить paintComponent() - person quartaela; 03.03.2013
comment
хорошо, теперь он говорит, что я переопределяю метод рисования, но не показывает многоугольник - person quartaela; 03.03.2013