Java Метод drawRect () имеет странный / неправильный размер - PullRequest
0 голосов
/ 01 апреля 2020

Итак, я пытаюсь нарисовать прямоугольник на JPanel (Rect), который затем добавляется в мой основной JFrame. Предполагается, что прямоугольник находится в середине моего окна, но вместо этого он находится за пределами окна.

То, что я пробовал:

  • Добавление JPanel в JFrame и добавление Rect в JPanel, без изменений.
  • При установке макета JFrames на null, прямоугольник исчезает нигде.

Соответствующий код:

Main . java

package sudoku_solver;

public class Main
{
    public static void main(String[] args)
    {
        int[][] board = Board.getBoard();
        Solver solver = new Solver(board);
        Interface gui = new Interface();

        gui.createFrame();
        gui.drawGrid(board);

        solver.solve();
        solver.print();
    }
}

Интерфейс. java

package sudoku_solver;

import java.awt.*;
import javax.swing.*;

public class Interface
{
    private static class Rect extends JPanel
    {
        private static final long serialVersionUID = 1L;

        int x;
        int y;
        int rectWidth;
        int rectHeight;
        Color color;

        public Rect(int _x, int _y, int _rectWidth, int _rectHeight, Color _color)
        {
            x = _x;
            y = _y;
            rectWidth = _rectWidth;
            rectHeight = _rectHeight;
            color = _color;
        }

        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;                                                                           
            g2d.drawRect(x, y, rectWidth, rectHeight);
            g2d.setColor(color);
        }
    }

    static JFrame frame;
    static int windowWidth = 580;
    static int windowHeight = 580;
    static int cellSize = windowWidth / 9;

    public void createFrame()
    {
        frame = new JFrame("Sudoku");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(windowWidth, windowHeight);
        frame.setVisible(true);
    }

    public void drawGrid(int[][] bo)
    {
        drawBorder();
    }

    private static void drawBorder()
    {
        Rect rect = new Rect(20, 20, windowWidth - 20, windowHeight - 20, Color.black);
        frame.add(rect);
    }
}

Выход:

Output I'm getting

Пытался найти других людей с такой же проблемой, но не смог их найти. Спасибо!

Ответы [ 2 ]

4 голосов
/ 02 апреля 2020

Проблема в том, что вы пытаетесь контролировать размер кадра. Это не то, как работает Swing. Помните, что размер кадра включает заголовок и границы. Таким образом, размер панели, добавляемой к кадру, НИКОГДА не будет соответствовать размеру рамки.

Вместо этого вы контролируете размер компонентов, добавляемых в рамку. Тогда размер кадра будет соответствующим образом основан на этих компонентах.

static int windowWidth = 580;
static int cellSize = windowWidth / 9;

Зачем вам выбирать ширину 580. Как вы получите равные размеры ячеек, поскольку 9 не делится поровну на 580?

Поэтому вместо этого следует указать ваш размер клетки. Затем на панели умножьте на 9, чтобы получить предпочтительный размер панели.

Rect rect = new Rect(20, 20, windowWidth - 20, windowHeight - 20, Color.black);

Кроме того, не задавайте значение 20 жестко в 4 разных местах. Опять же, у вас может быть параметр для строки класса "borderSize". Затем внутренне вы используете это значение.

Таким образом, параметры вашего класса Rect могут выглядеть примерно так: publi c Rect (int cellSize, int borderSize, Color _color) Теперь вам нужно реализовать метод getPreferredSize() из вас класс, так что компонент может рассчитать свой собственный предпочтительный размер. Что-то вроде:

@Override
public Dimension getPreferredSize()
{
    int size = (cellSize * 9) + (borderSize * 2);
    return new Dimension(size, size);
}

Теперь, когда вы делаете свою обычную окраску, все рисование выполняется относительно панели. Что-то вроде:

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;                                                                           
        int size = (cellSize * 9);
        g2d.drawRect(borderSize, borderSize, size, size);
        g2d.setColor(color);
    }

Поэтому, когда вы создаете экземпляр класса, вы будете использовать:

 public void createFrame()
{
    Rect rect = new Rect(50, 20, Color.black);
    frame = new JFrame("Sudoku");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(rect);
    frame.pack();
    //frame.setSize(windowWidth, windowHeight);
    frame.setVisible(true);
}
1 голос
/ 01 апреля 2020

Вы пишете:

new Rect(20, 20, windowWidth - 20, windowHeight - 20, Color.black);

Это должно быть

new Rect(20, 20, windowWidth - 40, windowHeight - 40, Color.black);

Потому что первая точка означает начальную локализацию, третья и четвертая означает, насколько длинным должен быть ваш прямоугольник. Так как вы забрали 20, а должно быть 40, потому что вы забрали только с левой стороны и забыли о правой стороне рамки.

...