Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Не могу понять механизм наследования / 13 сообщений из 13, страница 1 из 1
15.08.2012, 16:01:20
    #37917948
Last1Cmen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
Читаю хорстмана ну и пытаюсь примеры рассмотреть

вот код из примера работы с заливками фигур внутри фрейма

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
/**
   @version 1.31 2002-07-06
   @author Cay Horstmann
*/

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

public class FillTest
{  
   public static void main(String[] args)
   {  
      FillFrame frame = new FillFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.show();
   }
}

/**
   A frame that contains a panel with drawings
*/
class FillFrame extends JFrame
{
   public FillFrame()
   {
      setTitle("FillTest");
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

      // add panel to frame

      FillPanel panel = new FillPanel();
      Container contentPane = getContentPane();
      contentPane.add(panel);
   }

   public static final int DEFAULT_WIDTH = 400;
   public static final int DEFAULT_HEIGHT = 400;  
}

/**
   A panel that displays filled rectangles and ellipses 
*/
class FillPanel extends JPanel
{  
   public void paintComponent(Graphics g)
   {  
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;

      // draw a rectangle

      double leftX = 100;
      double topY = 100;
      double width = 200;
      double height = 150;

      Rectangle2D rect = new Rectangle2D.Double(leftX, topY,
         width, height);
      g2.setPaint(Color.RED);
      g2.fill(rect);

      // draw the enclosed ellipse

      Ellipse2D ellipse = new Ellipse2D.Double();
      ellipse.setFrame(rect);
      g2.setPaint(new Color(0,  128, 128)); // a dull blue-green
      g2.fill(ellipse);
   }
}



вобщем у хорстмана написано что вызвав метод предка класса FillPanel setBackground() можно поменять цвет фона контейнера в котором и выводятся эти фигуры

т.е. в методе public void paintComponent(Graphics g) если сначала обратиться super.paintComponent(g) то потом не вопрос можно вызвать setBackground(цвет)

мне непонятно почему нельзя вызвать сразу setBackground(цвет) без вызова перед этим super.paintComponent(g) ? ведь setBackground должен наследоваться аж от Component (я по иерархии прошел и там хоть переопределеятеся метод в части классов но смысл тот же - передается параметр g в метод setBackground части из них только выше через super)
только в классе Component что-то с этим g происходит... ну так мой класс FillPanel наследуется таки от этого самого Component и по цепочке иерархии нигде по самой логике обработки внутри метода не переопределятся

но почему я не могу вызвать сразу setBackground без вызова предварительно super.paintComponent(g) я не понял... почему ? :(
...
Рейтинг: 0 / 0
15.08.2012, 16:12:14
    #37917980
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
Это не фича наследования, это фича того - как Swing работает(EDT)
...
Рейтинг: 0 / 0
15.08.2012, 16:16:47
    #37917993
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
А можно конкретно ткнуть где в книге про setBackground написано?
По-моему вызывать метод setBackground из paintComponent как-то глупо.
setBackground() меняет состояние компаненты.
paintComponent() отоброжает текущее состояние компаненты на graphics.
менять состояние во время отрисовки как-то глупо. К тому же это будет сильно тормозить на GUI, так как setBackground вызывает repaint() и оповещает всех propertyChangeLister-ов. Такое делают, а потом жалуются что Swing тормозит.

Механизмы наследования в Java тут как бы вообще не при чем.
...
Рейтинг: 0 / 0
15.08.2012, 17:34:40
    #37918201
Last1Cmen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
забыл никЭто не фича наследования, это фича того - как Swing работает(EDT)
ну вот с подобным выводом вчера я и лег спать
А можно конкретно ткнуть где в книге про setBackground написано?

7 издание русское, стр 332 первый том

т.е. применяю там

super.paintComponent(g);
setBackground(Color.PINK);

и закраска идет... т.е. пока я не вызову не переопределённый в FillPanel метод суперкласса (всё никак к этому термину не могу привыкнуть... лучше родительского имхо) JPanel который paintComponent() передав туда компонент текущий который g работать не будет :(

ну иногда ну никак не могу такое дао постичь

paintComponent() отоброжает текущее состояние компаненты на graphics.
менять состояние во время отрисовки как-то глупо.

ну а как тогда сделать лучше ? если надо поменять цвет после действий пользователя или как реакцию на что-то
...
Рейтинг: 0 / 0
15.08.2012, 17:43:37
    #37918223
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
Last1Cmen7 издание русское, стр 332 первый том

Там ничего не написано про то что setBackground() надо вызывать из paintComponent()
В этом ваша ключевая ошибка.

Last1Cmensuper.paintComponent(g);
setBackground(Color.PINK);

Так не нужно делать.

Last1Cmenи закраска идет...

потому что setBackground вызывает внутри repaint, который позже снова вызовет ваш paint, из которго вызовет super.paint, который наконец отрисует задвный вами фон. Это очень не адекватная цепочка.

Last1Cmenт.е. пока я не вызову не переопределённый в FillPanel метод суперкласса (всё никак к этому термину не могу привыкнуть... лучше родительского имхо) JPanel который paintComponent() передав туда компонент текущий который g работать не будет :(

Вы исследуете какие-то побочные эффекты. setBackground() не нужно вызывать внутри paintComponent(). Перечитайте ещё раз то что я написал выше про состояния. Попытайтесь понять.

Last1Cmenну а как тогда сделать лучше ? если надо поменять цвет после действий пользователя или как реакцию на что-то
Когда пользователь что-то делает, вызывается соответствующй listener. В нём вы вызываете setBackground(), чтобы поменять цвет.
Этот метод вызывает внутри repaint(), чтобы сообщить компаненте, что ей стоит как можно скорее перерисовать себя.
Потом вызовется метод paintComponent(), который и отрисует компаненту. Вы его для чего переопределили? Какуюто новую отрисовку добавляете? Не делайте в этом методе никаких вычислений. Это должен быть очень быстрый метод. Он просто берет текуще состояние свойств компаненты и отображает их.
...
Рейтинг: 0 / 0
15.08.2012, 17:58:25
    #37918256
Last1Cmen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
ммм... хорошо, я понял что так лучше не делать т.к. произойдет повторый вызов перерисовки (что понятное дело не есть гуд)

тот же хорстман говорит что paintComponent() вызывать для перерисовки некорректно и лучше использовать repaint() т.е. для первого вызова мне таки надо вызвать paintComponent() так вот где тогда определять цвет фона чтобы избежать повторного вызова ?

где-то ещё до стека ?

FillPanel panel = new FillPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
...
Рейтинг: 0 / 0
15.08.2012, 18:13:59
    #37918287
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
Last1Cmenммм... хорошо, я понял что так лучше не делать т.к. произойдет повторый вызов перерисовки (что понятное дело не есть гуд)
Если бы вы не поленились и заглянули в JavaDoc, то нашли бы там упоминание о вот этой статье:
http://java.sun.com/products/jfc/tsc/articles/painting/index.html

Last1Cmenтот же хорстман говорит что paintComponent() вызывать для перерисовки некорректно и лучше использовать repaint()

По-моему у вас опять вольные трактовки. paintComponent() вообще нельзя вызывать. Его вызывает менеджер отрисовки (RepaintManager). В то время как repaint это команда для менеджера отрисовки. Её нужно вызывать, если изменилось состояние, влияющее на отрисовку. Стоит обратить внимание, что такие методы как setBackground() вызывают repaint() самостоятельно.

Last1Cmenт.е. для первого вызова мне таки надо вызвать paintComponent()

Нет, не нужно.

Last1Cmenтак вот где тогда определять цвет фона чтобы избежать повторного вызова ?

В методе в котором вы конструируетe GUI, либо обновляете его состояние по какому-либо событию.

Last1Cmenгде-то ещё до стека ?

FillPanel panel = new FillPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
Это не стек.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
class Test extends JFrame{
 FillPanel panel = new FillPanel();

 public void initGui(){
   panel.setBackground(INITIAL_COLOR);
   Container contentPane = getContentPane();
   contentPane.add(panel);
 }

 public void actionPerformed(Event e){
   panel.setBackground(USER_COLOR);
 }
}
...
Рейтинг: 0 / 0
15.08.2012, 18:44:07
    #37918311
Last1Cmen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
BlazkowiczЕсли бы вы не поленились и заглянули в JavaDoc, то нашли бы там упоминание о вот этой статье:
http://java.sun.com/products/jfc/tsc/articles/painting/index.html

мда... без интернета дома никак вижу :)
а так толку мне о таком онлайн напоминании статьи в локальном джавадоке

непонято зачем вообще тогда упоминать о setBackground если по книге контекст в котором его следует применять ещё на рассматривался :)

ладно спасибо в любом случае пойду переваривать
...
Рейтинг: 0 / 0
05.07.2013, 02:56:38
    #38321321
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
Чтобы не создавать новую тему, запостю тут...

Есть код, который считается правильный а может и нет.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
public class SampleClass {
    public static void main(String[] args) {
        SiamCat simka = new SiamCat("Simka");
        NakedCat nakedSimka = simka.shave();
    }

    public static class NakedCat {
    }

    public static class NormalCat extends NakedCat {

        public NormalCat() {
            super();
        }

        public NormalCat(String name) {
            System.out.println("My name is " + name);
        }

        public NakedCat shave() {
            return this;
        }
    }

    public static class SiamCat extends NormalCat {
        public SiamCat(String name) {
            super(name);
        }
    }
}


Зачем оставлен в NormalCat дефолтный конструктор, т.к. с ним и без него работает правильно?
Ведь если дефолного нет, то он создастся автоматически, если такой понадобится.
Причем в нем еще вызывается суперконструктор, который является тоже дефолтным для NakedCat (т.к. в нем ничего нет).
Код: java
1.
2.
3.
 public NormalCat() {
            super();
        } 
...
Рейтинг: 0 / 0
05.07.2013, 10:28:57
    #38321503
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
В данном случае дефолтный конструктор NormalCat() не вызывается, и для работы примера он не нужен, так как есть явное обращение к коструктору с сигнатурой NormalCat(String name). Скорее всего, его сюда добавили чтобы запутать экзаменуемого;
Утверждение, что дефолтный конструктор создается автоматически - неверное, он создается автоматически только если не указано ни одного конструктора;
Вызов super(); в конструкторе NormalCat() можно опустить - компилятор вставит его за вас
...
Рейтинг: 0 / 0
05.07.2013, 10:30:58
    #38321508
maxkar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
rema174Зачем оставлен в NormalCat дефолтный конструктор, т.к. с ним и без него работает правильно?
Ведь если дефолного нет, то он создастся автоматически, если такой понадобится.

Нет. Не создастся. Конструктор по-умолчанию создается только если у класса не указаны другие конструкторы. Поэтому если его не указать, у NormalCat будет только один конструктор (с одним аргументом).

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

rema174Причем в нем еще вызывается суперконструктор, который является тоже дефолтным для NakedCat (т.к. в нем ничего нет).

Похоже на автогенерированный конструктор. Ни на что не влияет. Если не указать super(), родительский конструктор все равно будет вызван.
...
Рейтинг: 0 / 0
05.07.2013, 11:59:35
    #38321669
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
ivanraУтверждение, что дефолтный конструктор создается автоматически - неверное, он создается автоматически только если не указано ни одного конструктора
maxkarКонструктор по-умолчанию создается только если у класса не указаны другие конструкторы. Поэтому если его не указать, у NormalCat будет только один конструктор (с одним аргументом). В вашем примере конструктор без аргументов действительно не нужен. В других случаях может понадобиться.

ок, в данном случает дефолтный не нужен, разобрались.
не совсем понятно почему дефолный не создается (если он явно не прописан)?
например, изменим код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
public class SampleClass
{
    public static void main(String[] args) {
        SiamCat simka = new SiamCat("Simka");
        NakedCat nakedSimka = simka.shave();
        System.out.println("nakedSimka: "+nakedSimka.toString());
        NakedCat nk = new NakedCat();
        System.out.println("nk: "+nk.toString());
    }

    public static class NakedCat {
    }

    public static class NormalCat extends NakedCat {

        public NormalCat(String name) {
            System.out.println("My name is " + name);
        }

        public NakedCat shave() {
            return this;
        }
    }

    public static class SiamCat extends NormalCat {
        public SiamCat(String name) {
            super(name);
        }
    }
}


оставим в NakedCat только конструктор с параметром (не дефолтный), чтобы проверить, создастся дефолтный или нет и в мейне вызовем
Код: java
1.
2.
NakedCat nk = new NakedCat(); // чем не место для дефолтного конструктора?
System.out.println("nk: "+nk.toString()); //на выходе ...$NakedCat@1abab88 - значит и конструктор был создан/вызван?


другими словами, несмотря на то, что другие конструкторы (не дефолные) есть, дефолтный конструктор был вызван, чтобы создать объект nk - а откуда еще берутся объекты?
...
Рейтинг: 0 / 0
05.07.2013, 12:07:03
    #38321685
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу понять механизм наследования
хотел создать NormalCat, а написал NakedCat...
если прописать NormalCat nk = new NormalCat(); то это действительно будет ошибкой компиляции
авторjava: constructor NormalCat in class NormalCat cannot be applied to given types;
required: java.lang.String
found: no arguments
reason: actual and formal argument lists differ in length
т.е. и в самом деле дефолтный конструктор создается автоматически только если не указано ни одного конструктора
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Не могу понять механизм наследования / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]