Размер окна Java Swing не соответствует результату AWT canvas - PullRequest
1 голос
/ 24 октября 2019

Я хотел нарисовать прямоугольник с шириной 80% и высотой 80% от исходного окна в JPanel.

Вот мой класс драйвера

public class driver {
    public static void main(String[] args) {
        System.out.println("test");
        Window myWindow = new Window();
        myWindow.add(new GraphPanel());
        myWindow.settings();
    }
}

Вот мой JPanel:

import javax.swing.*;

public class Window extends JFrame {

    private static final int width = 1100;
    private static final int height = 600;

    public void settings(){
        setSize(width,height);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static int[] getWindowSize(){
        int[] output = new int[]{width, height};
        return output;
    }
}

и прямоугольник холста:

import java.awt.*;

public class GraphPanel extends Canvas {
    public void paint(Graphics g){
        setBackground(Color.WHITE);
        setForeground(Color.DARK_GRAY);

        int[] windowSize = Window.getWindowSize();

        //Not working as intented
        g.drawRect(windowSize[0]/10, windowSize[1]/10, 8*windowSize[0]/10, 8*windowSize[1]/10);
    }
}

И вот результат, я не могу опубликовать изображение, вот ссылка https://i.imgur.com/6D1gEF7.png

Как вы можете видеть,это явно не по центру, высота примерно на 30 пикселей и ширина около 20. Я понятия не имею, как это произошло, поэтому мой вопрос: кто-нибудь знает, что могло вызвать это?

1 Ответ

0 голосов
/ 24 октября 2019

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

Первое, что я хотел бы сделать, это изменить свой GraphPanel, чтобы он определял его preferredSize, независимо от окна. Таким образом, вместо этого вы управляете системой управления макетом.

Далее, я бы использовал фактический физический размер компонента, чтобы основывать ваши расчеты на

int width = (int) (getWidth() * 0.8);
int height = (int) (getHeight() * 0.8);

Я бы также рекомендовал переместитьsetBackground и setBackground из paint метода. Это вызовет новый цикл боли и создаст беспорядок.

public class GraphPanel extends Canvas {

    private static final int PREF_WIDTH = 1100;
    private static final int PREF_HEIGHT = 600;

    public GraphPanel() {
        setBackground(Color.WHITE);
        setBackground(Color.DARK_GRAY);
    }

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

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

        int width = (int) (getWidth() * 0.8);
        int height = (int) (getHeight() * 0.8);

        int x = (getWidth() - width) / 2;
        int y = (getHeight() - height) / 2;

        //Not working as intented
        g.drawRect(x, y, width, height);
    }
}

Затем я обновил бы ваш класс Window, чтобы он использовал pack вместо setSize. Это «упаковывает» окно вокруг контента, принимая во внимание декорации фрейма.

public class Window extends JFrame {

    public void settings() {
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Хотя я бы поставил под сомнение вопрос о расширении с JFrame, но я получаю тему.

Кстати, если вы не собираетесь использовать высокопроизводительную графику, требующую полного контроля над подсистемой рисования, я бы порекомендовал начать с компонентов на основе Swing или даже с JavaFX

...