метод рисования рисует за пределами jFrame, если первая координата 0,0

Первая координата в этом случае должна быть 0,0, а не 8,30. Что я делаю неправильно (я использую NetBeans)

import java.awt.Color;
import java.awt.Graphics;
public class TEST extends javax.swing.JFrame {

@Override
public void paint(Graphics g){
    super.paint(g);
    g.setColor(Color.blue);
    g.drawRect(8, 30, 200, 200);
    repaint();
}}

person VELIKI UM    schedule 06.01.2013    source источник
comment
g — это графический контекст кадра. Теперь строка заголовка также является частью фрейма. В результате (0,0) означает верхний левый угол кадра, а не верхний левый угол области рисования, как вы ожидаете.   -  person Extreme Coders    schedule 06.01.2013
comment
У рамок есть украшения, которые занимают место ВНУТРИ границ рамы. Рисовать непосредственно на фрейме не рекомендуется, так как 1. Вы столкнетесь с этой проблемой и 2. Фрейм содержит другие компоненты (панель содержимого, меню, слои и стеклянные панели). Ознакомьтесь с этим для получения дополнительной информации. Вы должны использовать пользовательский компонент (например, JPanel) и либо добавить его на панель содержимого, либо заменить им панель содержимого фрейма.   -  person MadProgrammer    schedule 07.01.2013


Ответы (2)


Добавьте JPanel в рамку и закрасьте ее. Координаты фрейма включают декорации (заголовок, границы и т. д.). Это будет выглядеть примерно так:

public class Test extends JFrame {
    public static void main(String[] args) {
        new Test();
    }
    private Test() {
        add(new MyPanel());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        setVisible(true);
    }
    private class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.blue);
            g.drawRect(8, 30, 200, 200);
        }
    }
}

Кроме того, не звоните repaint(); в paint();. Это вызовет бесконечный цикл и заморозит всю программу.

person tckmn    schedule 06.01.2013
comment
..Test extends JFrame.. Зачем расширять кадр? Просто используйте экземпляр одного из них. - person Andrew Thompson; 06.01.2013
comment
+1 AndrewThompson, @DoorKnob Также всегда создавайте компоненты Swing в потоке отправки событий и не вызывайте setSize, а вызывайте pack() для JFrame (и переопределяйте getPreferredSize() из JPanel - подробнее см. Мой ответ). +1 за советы paintComponent JPanel и repaint(). - person David Kroukamp; 06.01.2013
comment
@AndrewThompson Я просто пытался сделать ее максимально похожей на исходную программу. Обычно я бы этого не делал. - person tckmn; 06.01.2013
comment
@Doorknob Не давайте OP-код, который демонстрирует плохие методы, поскольку он / или она может подумать, что это правильный способ сделать это, и, таким образом, выучит неправильные методы, а скорее исправит свои ошибки для будущего IMO. - person David Kroukamp; 06.01.2013
comment
Спасибо мне очень помогло, хотя у меня были некоторые проблемы в начале, но я разобрался (я реализовал это в другой программе) - person VELIKI UM; 06.01.2013

Проблема в том, что ваш метод paint(..) не учитывает JFrame Insets, вызывая getInsets, который как состояние документов:

Если для этого компонента была установлена ​​граница, возвращает вставки границы.

этот код работает нормально:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        createAndShowGui();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                g.setColor(Color.blue);
                g.drawRect(0 + getInsets().left, 0 + getInsets().top, 200, 200);
            }
        };
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.pack();
        frame.setVisible(true);
    }
}

однако это не лучшая практика.

Скорее добавьте JPanel к JFrame и переопределите paintComponent(Graphics g) из JPanel, не забудьте вызвать super.paintComponent(g) в качестве первого вызова в переопределенном методе, а затем рисовать там (не забудьте переопределить getPreferredSize() и вернуть правильные Dimension, чтобы JPanel соответствовал своему рисунку/графическому содержимому) эта проблема будет больше не сохраняется, так как JPanel добавляется в правильных координатах на contentPane, например так:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        createAndShowGui();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
                g2d.setColor(Color.blue);
                g2d.drawRect(0, 0, 200, 200);
            }

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

        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

Вышеупомянутое включает Graphics2D и RenderingHints, т.е. сглаживание. Просто для красивых рисунков :)

person David Kroukamp    schedule 06.01.2013