Почему панель не окрашена?

#java #swing #colors #java-2d #paintcomponent

#java #качать #Цвет #java-2d #paintcomponent

Вопрос:

код

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

class tester {
   public static void main(String args[]) {
     JFrame fr = new JFrame();
     JPanel p = new JPanel();
     p.setBackground(Color.RED);
     p.paintImmediately(20,20,500,500);  
     fr.add(p);
     fr.setVisible(true);
     fr.setSize(2000,2000);
  }
}
  

Я получаю панель, полностью окрашенную в красный цвет. Почему я не получаю строку? Как я могу это получить?

Комментарии:

1. какая строка? В конце концов получил ваше намерение из ответа @aioobe 🙂 Кстати, при чтении руководства, как было предложено, пожалуйста, не пропустите главу о соглашениях об именовании Java, изучите их и придерживайтесь их

Ответ №1:

Я получаю панель, полностью окрашенную в красный цвет.

Это потому, что вы задали фон и не делали никакой дальнейшей покраски…

Почему я не получаю строку? Как я могу это получить?

Это не способ сделать это. Почему вы вызываете paintImmediately ? Вот что говорится в документации:

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

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

Я предлагаю вам прочитать о рисовании в AWT / Swing.


Чтобы получить что-то вроде этого

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

вы могли бы изменить свой код следующим образом:

 JFrame fr = new JFrame();
JPanel p = new JPanel() {
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawLine(20, 20, 500, 500);
    }
};
p.setBackground(Color.RED);
fr.add(p);
fr.setVisible(true);
fr.setSize(200, 200);
  

Комментарии:

1. @ aioobe спасибо. На самом деле я хочу сохранить все то же самое и просто добавить строку. Именно по этой причине я думал о том, чтобы снова не вызывать repaint / paint . Есть ли способ, которым я могу рисовать линии, не вызывая метод рисования снова, а просто добавляя строку поверх того, что было нарисовано методом рисования

2. Нет, вы не можете вызывать g.drawLine и ожидать, что он останется на панели навсегда. Это не так, как это работает. (Тогда вам нужно было бы нарисовать строку на некотором буферизованном изображении и нарисовать изображение на панели.) Вы не можете сохранить свой код неизменным и просто добавить «линию рисования». Приведенный мной код — это решение, наиболее близкое к вашему коду.

3. @ aioobe @ grassPro Это можно сделать, установив условие в методе рисования. Метод рисования работает if до тех пор, пока не захочет OP, и работает else , когда захочет OP. paint(Gra g) { if(firstTime) {//...} else {//...} }

4. это плохая идея, поскольку при первом рисовании компонента он может быть намного меньше, чем когда вы фактически устанавливаете его размер, упаковываете его, разворачиваете окно, называете его … и тогда у предоставленного Graphics объекта будет неприятный набор клипов…

5. @ aioobe Да, это может быть плохой идеей, но что означает «набор неприятных клипов»?