Несколько графических объектов из метода

У меня была задача нарисовать шашечную доску. Вот мой класс кадра

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JTabbedPane;

public class AppFrame extends JFrame {
    public AppFrame() {
        setTitle("Kółko i kwadracik");
        setSize(1000, 1500);
        setLocationRelativeTo(null);
        initGUI();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void initGUI() {
        setLayout(new BorderLayout());

        JTabbedPane tabPane = new JTabbedPane();
        tabPane.addTab("Plansza", new PlanszaGry());
        tabPane.addTab("Obrazek", new PanelZObrazkiem());
        tabPane.addTab("Wykres", new Wykres());
        tabPane.addTab("Warcaby", new Warcaby());
        tabPane.addTab("4 Warcaby", new Warcaby4());

        add(tabPane, BorderLayout.CENTER);
    }
}

Чем класс для создания одной доски для шашек, это новый Warcaby()

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;

import javax.swing.JPanel;

public class Warcaby extends JPanel {
    public void paint(Graphics g) {
        super.paint(g);

        setBackground(Color.WHITE);

        Graphics2D g2 = (Graphics2D) g;

        Stroke defaultStroke = g2.getStroke();

        int y = 9; // tu ustawiamy liczbę linii (czyli w sumie wilekość planszy)

        // linie planszy do gry
        for (int i = 0; i <= y; i++) {
            float dash[] = { 10.0f };
            Stroke lineStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
                    BasicStroke.JOIN_MITER);
            g2.setStroke(lineStroke);
            g2.setColor(Color.BLACK);
            int x = i * 100;
            g2.draw(new Line2D.Double(100 + x, 100, 100 + x, 100 * y));// linie
                                                                        // pionowe

            g2.draw(new Line2D.Double(100, 100 + x, 100 * y, 100 + x)); // linie
                                                                        // poziome

        }

        // Plansza do gry (czarne/białe pola)
        for (int a = 1; a < y; a++) {
            if (a % 2 != 0) {
                for (int b = 1; b < y; b++) {
                    if (b % 2 == 0) {

                        g.setColor(Color.black);
                        g.fillRect(b * 100, a * 100, 100, 100);
                    }
                }
            } else {
                for (int b = 1; b < y; b++) {
                    if (b % 2 != 0) {

                        g.setColor(Color.black);
                        g.fillRect(b * 100, a * 100, 100, 100);
                    }
                }
            }

        }
    }
}

Моя следующая задача - нарисовать 4 доски рядом друг с другом, учитель дал мне подсказку создать метод рисования одной доски с информацией о ее положении. Я не могу понять, как даже начать. Я начал с этого:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;

import javax.swing.JPanel;

public class Warcaby4 extends JPanel {

    public void Warcaby(Graphics g, int x, int y) {
        super.paint(g);
        setBackground(Color.WHITE);
        Graphics2D g2 = (Graphics2D) g;
        Stroke defaultStroke = g2.getStroke();
        float dash[] = { 10.0f };
        Stroke lineStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
                BasicStroke.JOIN_MITER);
        g2.setStroke(lineStroke);
        g2.setColor(Color.BLACK);

        for (int i = 0; i <= y; i++) {

            x = i * 100;
            g2.draw(new Line2D.Double(100 + x, 100, 100 + x, 100 * y));// linie
                                                                        // pionowe

            g2.draw(new Line2D.Double(100, 100 + x, 100 * y, 100 + y)); // linie
                                                                        // poziome

        }

        // Plansza do gry (czarne/białe pola)
        for (int a = 1; a < y; a++) {
            if (a % 2 != 0) {
                for (int b = 1; b < y; b++) {
                    if (b % 2 == 0) {

                        g.setColor(Color.black);
                        g.fillRect(b * 100, a * 100, 100, 100);
                    }
                }
            } else {
                for (int b = 1; b < y; b++) {
                    if (b % 2 != 0) {

                        g.setColor(Color.black);
                        g.fillRect(b * 100, a * 100, 100, 100);
                    }
                }
            }

        }
    }
}

Теперь не знаю где и как это 4 раза прокричать, правильно ли я вообще делаю? Пожалуйста, дайте мне несколько предложений. :)


person EyeMaze    schedule 02.12.2015    source источник
comment
ТЛ; ДР. Рассмотрите возможность переноса этого на обмен стеками проверки кода.   -  person Mad Physicist    schedule 03.12.2015
comment
@MadPhysicist . Я не могу понять, как даже начать ‹- код должен быть уже написан   -  person Caridorc    schedule 03.12.2015
comment
Следующее предложение: Я начал с этого   -  person Mad Physicist    schedule 03.12.2015
comment
@MadPhysicist Начать недостаточно. Он должен работать так, как этого хочет OP. Code Review не выполняет запросы функций.   -  person Mast    schedule 03.12.2015
comment
@MadPhysicist, если я пишу половину программы, программа еще не написана и не работает полностью. См.: codereview.stackexchange.com/help/on-topic.   -  person Caridorc    schedule 03.12.2015
comment
Почему бы не добавить свой Warcaby компонент к GridLayout и добавить четыре его экземпляра?   -  person MadProgrammer    schedule 03.12.2015


Ответы (2)


Моя следующая задача - нарисовать 4 доски рядом друг с другом, учитель дал мне подсказку создать метод рисования одной доски с информацией о ее положении. Я не могу понять, как даже начать. Я начал с этого:

Почему бы просто не использовать повторно уже имеющийся компонент? Например, используя GridLayout, вы можете просто создать столько компонентов, сколько вам нужно...

введите здесь описание изображения

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class AppFrame {

    public static void main(String[] args) {
        new AppFrame();
    }

    public AppFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridLayout(2, 2));
                frame.add(new Warcaby());
                frame.add(new Warcaby());
                frame.add(new Warcaby());
                frame.add(new Warcaby());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Warcaby extends JPanel {

        public Warcaby() {
            setBackground(Color.WHITE);
            setBorder(new EmptyBorder(5, 5, 5, 5));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

//            setBackground(Color.WHITE);
            Graphics2D g2 = (Graphics2D) g;

            Insets insets = getInsets();
            int horontialPadding = insets.left + insets.right;
            int verticalPadding = insets.top + insets.bottom;

            int width = getWidth() - horontialPadding;
            int height = getHeight() - verticalPadding;

            int size = Math.min(width, height) / 10;

            int xOffset = insets.left + ((width - (size * 10)) / 2);
            int yOffset = insets.top + ((height - (size * 10)) / 2);

            for (int vertical = 0; vertical < 10; vertical++) {
                for (int horzontial = 0; horzontial < 10; horzontial++) {
                    int x = horzontial * size;
                    int y = vertical * size;
                    g2.setColor(Color.WHITE);
                    if (vertical % 2 == 0) {
                        if (horzontial % 2 == 0) {
                            g2.setColor(Color.BLACK);
                        }
                    } else if (horzontial % 2 != 0) {
                        g2.setColor(Color.BLACK);
                    }
                    g2.fillRect(xOffset + x, yOffset + y, size, size);
                }
            }
            g2.setColor(Color.BLACK);
            g2.drawRect(xOffset, yOffset, size * 10, size * 10);
        }
    }
}

Извините, я оптимизировал ваш код рисования, теперь он может изменять размер в зависимости от доступного места.

Кроме того, вы НИКОГДА не должны обновлять состояние пользовательского интерфейса из какого-либо метода рисования (например, вызывать setBackground), это очень плохая идея, которая может привести к бесконечному циклу рисования, который потребляет циклы вашего процессора и делает вашу систему непригодной для использования (да, Я сделал это)

Как правило, вы должны предпочесть paintComponent paint. См. Рисование в AWT и Swing и Выполнение пользовательского рисования для более подробной информации

person MadProgrammer    schedule 02.12.2015
comment
Спасибо за советы, я только начал изучать графику. Ваш код выглядит действительно продвинутым по сравнению с моим, хе-хе :) - person EyeMaze; 03.12.2015
comment
Не совсем, это основная концепция того, что вы уже сделали, я просто сделал ее более вариативной, но это потому, что я хотел лучше контролировать размер платы. Базовая концепция использования GridLayout должна работать для вашего кода (но вы должны обратить внимание на getPreferredSize ;)) - person MadProgrammer; 03.12.2015

Мне удалось выполнить это задание самостоятельно. Вот код на случай, если у кого-то возникнет аналогичная проблема.

public void paint(Graphics g) {
        super.paint(g);

        rysujWarcaby((Graphics) g, 50, 50);
        rysujWarcaby((Graphics) g, 50, 500);
        rysujWarcaby((Graphics) g, 500, 50);
        rysujWarcaby((Graphics) g, 500, 500);

}

public void rysujWarcaby(Graphics g, int x, int y) {
        int xx = 1;
        int nr = 9;
        setBackground(Color.YELLOW);
        Graphics2D g2 = (Graphics2D) g;
        Stroke lineStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
                        BasicStroke.JOIN_MITER);
        g2.setStroke(lineStroke);
        g2.setColor(Color.BLACK);

        for (int i = 0; i < nr; i++) {

                xx = i * 50;
                g2.draw(new Line2D.Double(x + xx, y, xx + x, y + 50 * 8));

                g2.draw(new Line2D.Double(x, y + xx, x + 50 * 8, y + xx));

        }

}
person EyeMaze    schedule 02.12.2015