Содержимое Swing JTabbedPane

По какой-то причине макеты не хотят работать внутри JTabbedPane. Вместо того, чтобы перетекать на следующую «строку», он просто действует так, как если бы у него было бесконечное горизонтальное пространство :( Однако добавление всего непосредственно в кадр без JTabbedPane работает нормально...

В моем кадре:

JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP);
this.getContentPane().add(this.tabbedPane);
JPanel tab = new TestTab();
tabs.add("Test", tab)

И мой конструктор TestTab (расширяет JPanel)

contentBox = new Box(BoxLayout.Y_AXIS);

JPanel groupPanel = new JPanel();
groupPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
groupPanel.setBorder(BorderFactory.createTitledBorder("Group"));

//add some paired items to it. The intention is each of these "sub groups"
//should stay together,with the sub groups themselves being liad out left to
//right, top to bottom
for(int i=0; i<10; ++i)
{
    String label = "Button " + i;
    Box itemBox = new Box(BoxLayout.X_AXIS);
    JButton buttonA = new JButton(label + " A");
    JButton buttonB = new JButton(label + " B");
    itemBox.add(buttonA);
    itemBox.add(buttonB);
    groupPanel.add(itemBox);
}

contentBox.add(groupPanel);
//will be more content stuff to be added vertically below,
//suppose will have same issue
this.add(contentBox);

person will    schedule 21.05.2011    source источник


Ответы (2)


Это не имеет ничего общего с панелями с вкладками, поскольку ваша проблема возникнет, если вы просто добавите JPanel TestTab в панель содержимого JFrame. Возможно, вам нужно управлять размером вашего contentBox Box, установив его предпочтительный размер? Возможно, вы хотите использовать GridLayout, а не FlowLayout? Лично мне нравится использовать GridLayout вот так:

  JPanel groupPanel = new JPanel();
  //!! groupPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
  groupPanel.setLayout(new GridLayout(0, 2, 5, 5));

Но также, когда вы публикуете подобную проблему, попробуйте опубликовать компилируемый исполняемый код, чтобы мы могли сами увидеть проблему. Не заставляйте нас создавать код самостоятельно, поскольку именно вы просите бесплатный совет и, следовательно, должны приложить усилия, чтобы другим было легко помогать вам. Я прошу SSCCE, подобный этому:

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

public class TestTabsTest {
   private static void createAndShowUI() {
      JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP);
      JPanel tab = new TestTab();
      tabs.add("Test", tab);

      JFrame frame = new JFrame("TestTabsTest");
      frame.getContentPane().add(tabs);
      //frame.getContentPane().add(new TestTab());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

class TestTab extends JPanel {
   private Box contentBox;

   public TestTab() {
      contentBox = new Box(BoxLayout.Y_AXIS);
      //contentBox.setPreferredSize(new Dimension(600, 600));

      JPanel groupPanel = new JPanel();
      //!! groupPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
      groupPanel.setLayout(new GridLayout(0, 2, 5, 5));
      groupPanel.setBorder(BorderFactory.createTitledBorder("Group"));

      // add some paired items to it. The intention is each of these
      // "sub groups"
      // should stay together,with the sub groups themselves being liad out left
      // to
      // right, top to bottom
      for (int i = 0; i < 10; ++i) {
         String label = "Button " + i;
         Box itemBox = new Box(BoxLayout.X_AXIS);
         JButton buttonA = new JButton(label + " A");
         JButton buttonB = new JButton(label + " B");
         itemBox.add(buttonA);
         itemBox.add(buttonB);
         groupPanel.add(itemBox);
      }

      contentBox.add(groupPanel);
      // will be more content stuff to be added vertically below,
      // suppose will have same issue
      this.add(contentBox);
   }
}
person Hovercraft Full Of Eels    schedule 21.05.2011
comment
Хорошо, я предоставлю полные классы в будущем. Причина, по которой я не использую gridlayout в первую очередь, заключается в том, что для моего (реального проекта) окно шириной около 1500 может отображать все красиво в одной строке, но не у всех есть такой большой экран или он хочет его максимизировать... Кроме того, несмотря на то, что setprefered size, кажется, работает, он, кажется, полностью игнорирует изменение размеров окна, а componentResized, похоже, не вызывается до тех пор, пока некоторое время после завершения изменения размера - person will; 21.05.2011
comment
Кроме того, только что поигравшись с предпочтительными размерами, нет ли способа установить только предпочтительную ширину и позволить макету иметь дело с высотой, а не пытаться угадать, какой должна быть высота? - person will; 21.05.2011

Вместо того, чтобы перетекать на следующую «линию»,

Похоже, макет переноса может помочь.

person camickr    schedule 21.05.2011
comment
Ницца. Я всегда хотел возиться с созданием своих собственных менеджеров компоновки, и ваш исходный код и комментарии к нему очень помогут, спасибо! - person Hovercraft Full Of Eels; 21.05.2011
comment
@Hovercraft Full Of Eels, Пит (вы Пит, не так ли?), этот менеджер компоновки не лучший пример пользовательского менеджера компоновки, поскольку он фактически не выполняет компоновку компонентов. FlowLayout по-прежнему выполняет всю компоновку. Этот класс пересчитывает предпочтительный размер только тогда, когда он определяет, что компоненты действительно упакованы. Лучшим примером кода макета будет Relative Layout или Overlap Layout, которые можно найти в моем блоге. Эти менеджеры компоновки выполняют фактическую компоновку компонентов, а также вычисляют предпочтительный размер. Или посмотрите исходный код FlowLayout. - person camickr; 22.05.2011