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


Автор: axod 17.2.2005, 20:51
Вот пример самой простенькой проги:
Код

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

public class MainC extends JFrame {

    private MyPanel myPanel;
   
       public MainC() {
       super("My Window");

       // 1-
       myPanel = new MyPanel();
       JPanel panel = new JPanel();
       panel.add(myPanel, BorderLayout.NORTH);
       getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
       // 2-
   }


   public static void main(String args[]) {
       MainC mainc = new MainC();
       mainc.setDefaultCloseOperation(EXIT_ON_CLOSE);
       mainc.setSize(640, 480);
       mainc.setVisible(true);
   }
}

   class MyPanel extends JPanel {
   public MyPanel() {
       setBackground(Color.white);
       Dimension dim = new Dimension(340, 240);
       this.setMinimumSize(dim);
   }
}


Здесь MyPanel расширяет класс JPanel и в конструкторе главного класса фрейма создаётся
объект на него и помещается в другой JPanel.

Проблема в том что MyPanel создаётся в виде маленького квадратика, а мне нужно чтоб он был на весь фрейм, внутри другого JPanel.

Если заменить код между комментариями на:
Код

       //1-
       myPanel = new MyPanel();
      getContentPane().add(new JScrollPane(myPanel), BorderLayout.CENTER);
       // 2-



То я получу желаемый результат, НО мне надо так как описано выше.
Жду ответа пожалуйСто.

Автор: LSD 17.2.2005, 21:07
Цитата(axod @ 17.2.2005, 20:51)
panel.add(myPanel, BorderLayout.NORTH);

Объясни зачем для единственного компонента тебе нужно помещать его наверх другой панели? И вообще зачем две вложенных панели если нет других компонентов?

Автор: Domestic Cat 17.2.2005, 21:10
Код

myPanel = new MyPanel();
       MyPanel panel = new MyPanel();
       panel.add(myPanel);
       getContentPane().add(new JScrollPane(panel));

Автор: axod 17.2.2005, 21:38
М-да спасибо.
Цитата

Объясни зачем для единственного компонента тебе нужно помещать его наверх другой панели? И вообще зачем две вложенных панели если нет других компонентов?


Я же написал что ЭТО простейшая прога что можно выдумать.

Ещё маленький вопросик у меня вообще MyPanel используется для прорисовочки и очень умных взаимосвязей с другими классами

написав
Цитата

      myPanel = new MyPanel();
      MyPanel panel = new MyPanel();
      panel.add(myPanel);
      getContentPane().add(new JScrollPane(panel));

Я не получу батву, ведь к примеру на фрейме у меня пусть должен быть JPanel c кнопками,
JPanel с ещё кнопками и myPanel - ом и ещё другие JPanel. А myPanel просто используется как область прорисовки.

Спасибо за ответ.

Автор: Domestic Cat 17.2.2005, 21:43
Цитата
Я не получу батву,


В смысле, неурожай нa свеклу чтоль?

Цитата
А myPanel просто используется как область прорисовки.


Попробуй ради интереса без "области прорисовки". С разными лейаут менеджерами.

Автор: axod 17.2.2005, 21:56
Цитата

В смысле, неурожай нa свеклу чтоль?

Да я просто имел ввиду что JPanel где я реализую свой paint() буду также использовать как вместилеще других объектов без всяческих нежелательных последствиях.

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

Автор: Domestic Cat 17.2.2005, 21:59
Цитата
Да я просто имел ввиду что JPanel где я реализую свой paint() буду также использовать как вместилеще других объектов без всяческих нежелательных последствиях.


Проще сделать отдельную панель для рисования.
Добавлено @ 22:01
Между прочим contentPane - тоже панель, поэтому еще проще dобавить в MainC метод
Код

   public void paintComponent(Graphics g)
   {
       g.setColor(Color.GREEN);
       g.fillRect(100, 100, 200, 200);
   }

Автор: axod 17.2.2005, 22:12
Да я и делал вообще отдельную панель для рисования просто унаследованая от JPanel и
в которой я реализую метод paintComponent(Graphics2D g2D){...}
просто когда я засовывал эту панель в другую у меня был маленький белый квадратик.

Ну вообще на вопрос мой ответил, спасибо.

Автор: Domestic Cat 17.2.2005, 22:31
Я имел в виду ложить myPanel не на panel а на contentPane.

Автор: axod 17.2.2005, 22:40
Ладно попробую спасибо! Но мои вопросы ещё будут.

Автор: djGri 21.2.2005, 19:09
2 axod
u JPanel - by default stoit FlowLayout - poetomu ti videl malenkuju knopku

Автор: Domestic Cat 21.2.2005, 19:12
Он пользовал BorderLayout -
Цитата
panel.add(myPanel, BorderLayout.NORTH);

Автор: djGri 22.2.2005, 15:51
Цитата(Domestic @ 21.2.2005, 18:12)
Он пользовал BorderLayout -

Цитата
panel.add(myPanel, BorderLayout.NORTH);


Неа! BorderLayout.NORTH - это Dimension
Надо так:
Код

// 1-
      myPanel = new MyPanel();
      JPanel panel = new JPanel();
      panel.setLayout( new BorderLayout());
      panel.add(myPanel, BorderLayout.NORTH);
      getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
      // 2-

Автор: AntonSaburov 22.2.2005, 16:00
Цитата(djGri @ 22.2.2005, 15:51)
BorderLayout.NORTH - это Dimention

Что-то ты похоже путаешь - это String.
И вообще использовать тогда надо так:
Код

panel.add(BorderLayout.NORTH, myPanel);

В добавлении сначала идет указание места, а потом только компонент.

Автор: djGri 22.2.2005, 16:09
Цитата(AntonSaburov @ 22.2.2005, 15:00)
Цитата(djGri @ 22.2.2005, 15:51)
BorderLayout.NORTH - это Dimention

Что-то ты похоже путаешь - это String.
И вообще использовать тогда надо так:
Код

panel.add(BorderLayout.NORTH, myPanel);

В добавлении сначала идет указание места, а потом только компонент.

в jdk 4.2 - так не работает

Автор: AntonSaburov 22.2.2005, 16:16
Этот код прекрасно собирается под 1.4.2

Код

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

public class Focus extends JFrame
{
 public Focus()
 {
   JButton btn = new JButton("OK");
   getContentPane().add(BorderLayout.NORTH, btn);
   
   setBounds(100,100,500,500);
 }

 public static void main(String[] args)
 {
   Focus my = new Focus();
   my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   my.setVisible(true);
 }
}

Автор: djGri 22.2.2005, 16:28
AntonSaburov
В этом случае работает:
Код

getContentPane().add(BorderLayout.NORTH, btn);


А в этом нет:
Код

myPanel = new MyPanel();
      JPanel panel = new JPanel();
      panel.add(myPanel, BorderLayout.NORTH);



Это потому, что у JFrame - default layout = Border Layout

Автор: AntonSaburov 22.2.2005, 17:12
Я не понимаю, почему у тебя panel.add имеет параметры в странном порядке ?

А кроме того у панели по умолчанию другой layout.

Автор: djGri 22.2.2005, 17:50
Цитата(AntonSaburov @ 22.2.2005, 16:12)
А кроме того у панели по умолчанию другой layout.

Да - Flow


Цитата(AntonSaburov @ 22.2.2005, 16:12)
Я не понимаю, почему у тебя panel.add имеет параметры в странном порядке ?


panel.add ( Container, int )

Автор: Domestic Cat 22.2.2005, 18:51
contentPane имеет дефаултом BorderLayout, потому contentPane.add(panel, BorderLayout.CENTER) добавит панель в центр. У JPanel дефаулт - FlowLayout, и дейсвительнo есть метод add(Component, int) который добавляет на позицию int. Поэтому panel.add(myPanel, BorderLayout.CENTER) добавит явно нe в центр.
Плохo, когда нет енумов, тогда б сразу выдалo ошибку.

Автор: AntonSaburov 22.2.2005, 19:27
BorderLayout.CENTER имеет тип String.

Автор: Domestic Cat 22.2.2005, 19:33
Извиняусь, я имел в виду метод add(Component, Object).

Автор: AntonSaburov 22.2.2005, 19:40
Посмотрел наконец первый пример - все там корректно. Просто установка размеров для MyPanel не дает эффекта. И не должно. JPanel возвращает самый маленький размер для FlowLayout. А он и будет минимальным, т.к. никаких элементов не находится на панели.
Там и получается ма-а-а-аленькая панелька в самом верху.

Так что пример работает корректно. Что ты хочешь получить на самом деле ?

Автор: Domestic Cat 22.2.2005, 19:45
Прикол в том, что в этом методе add в качствe констрейнта можно указывать все чтo угодно, если стоит FlowLayout . Например
Код

public class B extends JFrame
{  

   B()
   {
       setSize(300, 300);
       
       getContentPane().setLayout(new FlowLayout());
       getContentPane().add(new Button("Hello"), new JButton());
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setVisible(true);
   }
   
   public static void main(String[] args)    
   {
       new B();
   }
   
}

Автор: AntonSaburov 22.2.2005, 20:04
Так FlowLayout никаких условий не использует.

Вот прямо из описания:
"Also notifies the layout manager to add the component to this container's layout using the specified constraints object."

Т.е. этот объект используют только те лэйауты, которые в нем нуждаются. FlowLayout к ним не относиться. Попробуй пример, в котором просто изменен лэйаут у панели - все увидишь. Отругается, что фигню дали.

Код

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

public class MainC extends JFrame {

   private MyPanel myPanel;
 
      public MainC() {
      super("My Window");

      // 1-
      myPanel = new MyPanel();
      JPanel panel = new JPanel();
      panel.setLayout(new GridBagLayout());
      panel.add(myPanel, BorderLayout.NORTH);
      getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
      // 2-
  }


  public static void main(String args[]) {
      MainC mainc = new MainC();
      mainc.setDefaultCloseOperation(EXIT_ON_CLOSE);
      mainc.setSize(640, 480);
      mainc.setVisible(true);
  }
}

  class MyPanel extends JPanel {
  public MyPanel() {
      setBackground(Color.white);
      Dimension dim = new Dimension(340, 240);
      this.setMinimumSize(dim);
  }
}


Автор: Domestic Cat 22.2.2005, 20:24
Дык понятно, но сам факт наличия метода сбивает с толку. Для BorderLayout все сработае; в других случаях чловек начинает писать .add(myPanel, BorderLayout.NORTH); и думаеt чтo работает с BorderLayout.

Автор: AntonSaburov 22.2.2005, 20:39
По уму наверно надо было бы действительно описать какой-нибудь интерфейс для констрэйнтов и тогда понятности было бы больше.

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