Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > перересовка субкомпонентов


Автор: godun 14.11.2006, 01:09
имеется класс наследованный от Jcomponent который для простоты примера является прямоугольником

Код

public class MyComponent extends JComponent {

        public void paintComponent(Graphics g){
            super.paintComponents(g);                        
            g.fillRect(10, 100,50,10);
        }                
}



он добавлен на обнакновенную Jпанель котороая Находиться в JFrame

Код

public class MyPanel extends JPanel {
    private MyComponent myComponent;
    
    public MyPanel(){
        myComponent= new MyComponent();
        this.add(myComponent);
    }
    
    public void paintComponent(Graphics g){
        super.paintComponents(g);        
               //myComponent.paint(g);
    }
}

public class MyFrame extends JFrame{
    private MyPanel myPanel;    
    
    public MyFrame () {    
        this.setSize(640, 500);
        this.setResizable(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            myPanel = new MyPanel();                
        this.getContentPane().add(myPanel);
        
        this.setVisible(true);
    }    
}

вообщем при вызове перерисовки моего фрэйма в главной программе вызывается перерисвока панели а затем моего компонента, т.е. paintComponent(Grpahics g) вызывается нормально но переисовка самого компонента не происходить, проблема лежит в том что метода переисовки компонента не получает "правильной" ссылки на Graphics g. Если же вызывать напрямую  myComponent.paint(g) в теле метода MyPanel::paintComponent(Grpahics g) то компонент рисуется нормально.
Правильно ли так делать и почему paintComponent() омоего компонента не получает нужной ссылки на графику.

Автор: powerOn 14.11.2006, 12:13
Ты забыл добавить свой компонент на панель, поэтому он и не отображается. Попробуй так:
Код

class MyComponent extends JComponent {
    public void paintComponent(Graphics g){
        super.paintComponents(g);
        g.setColor(Color.BLUE); 
        
        g.fillRect(0, 0, 100, 100);
    }
}

class MyPanel extends JPanel {
    private MyComponent myComponent;
    
    public MyPanel(){
        myComponent = new MyComponent();
        this.add(myComponent, BorderLayout.CENTER);
    }
}
public class MyFrame extends JFrame{
    private MyPanel myPanel;
    
    public MyFrame() {
        this.setSize(640, 500);
        this.setResizable(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        myPanel = new MyPanel();
        myPanel.setLayout(new BorderLayout());
        myPanel.add(new MyComponent(), BorderLayout.CENTER );
        getContentPane().add(myPanel, BorderLayout.CENTER);
        
        setVisible(true);
    }
    public static void main(String[] args) {
        new MyFrame();
    }
}




Автор: godun 14.11.2006, 16:09
непонимаю зачем 2 раза добавлять мой компонет.... 1 раз в конструктуре MyPanel() a 2 ой раз в конструктуре  MyFrame()..

при создании MyPanel мой компонент автоматом туда добавляется.

проблема в том что метода отрисовки MyComponent не получает правильную графику...
а с прямым вызовом myComponent.paint(g); (у меня в камментах) все работает! smile 

Автор: LSD 14.11.2006, 16:40
Замени:
Код
    public void paintComponent(Graphics g){
        super.paintComponents(g);        
               //myComponent.paint(g);
    }

на
Код
    public void paintComponent(Graphics g){
        super.paintComponent(g);        
               //myComponent.paint(g);
    }


Добавлено @ 16:41 
Да и вообще нафиг надо было переопределять метод, если ничего полезного ты там не делаешь...

Автор: godun 14.11.2006, 16:52
@LSD

эти классы я взял для примера как можно более проще, чтоб яснее проблема была..


на super.paintComponent(g);   уже заменял резултат прежний..

говрю ж работает только с myComponent.paint(g);

или я что то недопонимаю или неправильно вообще все составил.

Добавлено @ 16:54 
еще раз

функция myComponent::paintComponent(g) вызывается нормально, не происходит лишь отрисвока прямоугольника   g.fillRect(10, 100,50,10);
 как бы метода получает неверную ссылку на графику... почему? smile 

Автор: LSD 14.11.2006, 17:02
Проблема в том, что по умолчанию у JPanel стоит FlowLayout, а он ставит компоненту те размеры которые он "предпочитает". По умолчанию JComponent "предпочитает" - нулевой размер.
Сделай так:
Код
public MyPanel()
{
  super(new BorderLayout());
  myComponent = new MyComponent();
  this.add(myComponent);
}


Добавлено @ 17:03 
Цитата(godun @  14.11.2006,  16:52 Найти цитируемый пост)
функция myComponent::paintComponent(g) вызывается нормально, не происходит лишь отрисвока прямоугольника   g.fillRect(10, 100,50,10); как бы метода получает неверную ссылку на графику... почему?

Да нормальная у него ссылка. Система рисования Swing давно проверена и отлажена, ошибки если в ней и есть, то не такие топорные.

Автор: godun 14.11.2006, 17:18
помогло... спасибо
действительно 0-размер =) ...

но только почему с 
myComponent.paint(g);
работетало и так...

Автор: LSD 14.11.2006, 17:40
Цитата(godun @  14.11.2006,  17:18 Найти цитируемый пост)
но только почему с 
myComponent.paint(g);
работетало и так...

Потому что, ты при рисовании плевал на размер компонента. Когда ты получаешь Graphics в методе paint() то у него уже сделан clipping не позволяющий тебе рисовать за пределами компонента (именно на такой случай). У тебя компонент нулевого размера, и область рисования тоже.

Автор: godun 14.11.2006, 20:49
здорово...

чтобы изменить размер компонента с 1х1 пиксел можно пользоваться setSize(int, int) для компонента или использовать отличный от FlowLayout лайаут на панели например GridBagLayout?

спасибо еще раз за ответы.

Автор: powerOn 14.11.2006, 20:54
Цитата(godun @  14.11.2006,  20:49 Найти цитируемый пост)
чтобы изменить размер компонента с 1х1 пиксел можно пользоваться setSize(int, int) для компонента или использовать отличный от FlowLayout лайаут на панели например GridBagLayout?

Менеджеров расположении много, и из них каждый имеет свои особенности. Почитай про них http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html.

Автор: LSD 14.11.2006, 21:23
Или у нас в FAQ: http://vingrad.ru/JAVA-JAV-000105.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)