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


Автор: Royan 25.7.2008, 12:08
Правильно ли я понимаю, что основное отличие JFrame от JPanel как контейнера заключается в том что в JFrame можно добавить только один компонент

Пример:

Код

public class SimpleTest extends JFrame {
    private ConcurrentHashMap<String, Integer> map;

    public SimpleTest() {
        super("Test");
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1.0;


        map = new ConcurrentHashMap<String, Integer>();
        JButton add = new JButton(new AbstractAction(){

            @Override
            public void actionPerformed(ActionEvent e) {
                map.put("test", new Random().nextInt());
            }
            
        });
        add.setText("Add");
        
        JButton print = new JButton(new AbstractAction(){

            @Override
            public void actionPerformed(ActionEvent e) {
                JFrame f = new JFrame("New frame");
                f.setSize(100, 100);
                f.setVisible(true);
            }
            
        });
        print.setText("Print");
        
        gridbag.setConstraints(add, c);
        
        JPanel panel = new JPanel();
        panel.setLayout(gridbag);
        
        
        add(add);
        gridbag.setConstraints(print, c);
        add(print);
        
//        add(panel);
        pack();
        setVisible(true);
    }

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

    }
}


Если же я буду добавлять в панель но все OK будет две кнопки. Вопрос на самом деле такой - где об этом написано?

Автор: dorogoyIV 25.7.2008, 13:11
Цитата(Royan @  25.7.2008,  12:08 Найти цитируемый пост)
Правильно ли я понимаю, что основное отличие JFrame от JPanel как контейнера заключается в том что в JFrame можно добавить только один компонент

я так не думаю. JFrame - это некая оболочка, в которой могут разместиться разные JPanel (также и другие компоненты).


Цитата(Royan @  25.7.2008,  12:08 Найти цитируемый пост)
Если же я буду добавлять в панель но все OK будет две кнопки

тут я не понял ??? какие две кнопки???

Автор: fixxer 25.7.2008, 13:37
Красавец! Компоненты добавляешь в JFrame, а LayoutManager кладешь в JPanel.
Замени
panel.setLayout(gridbag);
на 
this.setLayout(gridbag);
и будет тебе счастье.


Автор: dorogoyIV 25.7.2008, 14:02
вот еще для наглядности список контейнеров на пустом JFrame
Код

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

public class TestJFrame extends JFrame
{
 public static void main(String [] args)
 {
  JFrame f = new TestJFrame();

  Component [] comps = f.getComponents();
  for(int i = 0; i < comps.length; i++)
  {
   if(comps [i] instanceof Container)
    processContainer((Container)comps [i]);
  }
 }

 static void processContainer(Container c)
 {
  System.out.println(c);

  for(int i = 0; i < c.getComponents().length; i++)
  {
   if(c.getComponents()[i] instanceof Container)
    processContainer((Container)c.getComponents()[i]);
  }
 }
}

Автор: AntonSaburov 25.7.2008, 14:22
Читайте доки иногда

JFrame contains a JRootPane as its only child. The content pane provided by the root pane should, as a rule, contain all the non-menu components displayed by the JFrame.

Автор: fixxer 25.7.2008, 14:58
AntonSaburov, ты это к чему? 

Начиная с Java 5, JFrame#add(Component) эквивалентно JFrame#getContententPane().add(Component)

Код

protected void addImpl(Component comp, Object constraints, int index) {
        if(isRootPaneCheckingEnabled()) {
            getContentPane().add(comp, constraints, index);
        }
        else {
            super.addImpl(comp, constraints, index);
        }
    }



Автор: Royan 25.7.2008, 15:32
В общем все ясно в доках действительно все сказано: The default content pane will have a BorderLayout manager set on it. из-за которого меня и проглючило:

Фокус в действии
Код

package test;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimpleTest extends JFrame {
    public SimpleTest() {
        super("Test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());     
        panel.add(new JButton("Add"));
        panel.add(new JButton("Print"));
           
        add(panel);
        pack();
        setVisible(true);
    }

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


Комментируем строчку panel.setLayout(new BorderLayout());  все становится на "круги своя" обе кнопки видны

Автор: dorogoyIV 25.7.2008, 15:50
Цитата(Royan @  25.7.2008,  15:32 Найти цитируемый пост)
Комментируем строчку panel.setLayout(new BorderLayout());  все становится на "круги своя" обе кнопки видны

 smile 
тогда читай про LayoutManager
можно было написать например так: panel.add(new JButton("Print"), "South"); не убирая BorderLayout

Автор: AntonSaburov 25.7.2008, 16:56
Или вот - http://antonsaburov.narod.ru/articles/LayoutManager.html

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