2016-01-19 2 views
1

Я искал и пытался решить проблемы, с которыми я столкнулся при изменении размера GridBagLayout, но безрезультатно. Проблемы:Какие параметры следует использовать для разрешения этой проблемы изменения размера GridBagLayout?

  1. таскаю в нижней части окна JDialog вниз, чтобы сделать его выше; панель поиска (над панелью в нижнем скриншоте) продолжала становиться выше, просто добавляя пустое пространство, которое не нужно для его содержимого (я не хочу, чтобы это пустое пространство занимало высоту от прокручивающейся таблицы ниже).

  2. Если я перемещаю правую сторону окна, чтобы сделать его немного более узкой, панель прокрутки становится слишком короткой, хотя мой экран и окно могут отображаться на его полной высоте; появляется вертикальная полоса прокрутки (. Я не люблю панели для прокрутки по вертикали, по горизонтали только)

Мои JDialog, который держит ниже компонентов в верхней правой части использует ниже менеджера компоновки и ограничений:

JPanel  level 1   uses GridBagLayout Setting 1 (see below) 
JScrollPane level 2   uses GridBagLayout Setting 1 
JPanel  level 3   uses GridBagLayout Setting 2 
JPanel  level 4   uses GridBagLayout Setting 2 
JPanel  level 5   uses GridBagLayout Setting 2 
JPanel  level 5   uses GridBagLayout Setting 2 

GridBagLayout.GridBagConstraints (с)

Установка 1:

c.fill = GridBagConstraints.BOTH; 
c.weightx = 99.0; 
c.weighty = 99.0; 

Установка 2:

c.fill = GridBagConstraints.NONE; 
c.weightx = 1.0; 
c.weighty = 1.0; 

Первоначально это мой JDialog, если я не использую JScrollPane:

enter image description here

Если я перетащить окно, чтобы сделать его больше, размер JPanel (который я использовал до того, как я использовал JScrollPane, чтобы сделать его прокручиваемым по горизонтали) остается таким, какой он есть. Я хочу добиться такого же поведения, только чтобы я сделал его горизонтально прокручиваемым.

Какой менеджер макета следует использовать для решения этой проблемы изменения размера? Если мне нужно действительно использовать GridBagLayout, какие ограничения/настройки следует использовать? Я был бы очень признателен за любое предложение. Спасибо!

ОБНОВЛЕНИЕ 1 ------------------------------------------- -----------

Пожалуйста, ознакомьтесь с приведенным ниже примером кода примера. Обе прокручиваемые панели (КРАСНЫЙ и ГОЛУБОЙ) используют GridBagConstraints.BOTH, weightx и weighty, равные 99.0. Я хочу, чтобы красная панель имела высоту, достаточную для того, чтобы содержать текстовое поле. Я также хочу, чтобы при перетаскивании диалогового окна, чтобы увеличить окно, высота красной панели остается неизменной. Обратите внимание, что на фактическом экране может меняться количество содержимого обеих панелей (существуют кнопки добавления/минуса), поэтому настройка минимального размера панели (для изменения размера) не поможет. Пожалуйста, посоветуйте, как я должен идти по этому делу. Благодаря!

package cfr.view.search; 

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 

import javax.swing.JDialog; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.border.EmptyBorder; 

public class GBLSample extends JDialog { 

    private JPanel contentPane; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        GBLSample frame = new GBLSample(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public GBLSample() { 
     setBounds(100, 100, 350, 400); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 
     GridBagLayout gbl_contentPane = new GridBagLayout(); 
     contentPane.setLayout(gbl_contentPane); 

     // RED PANEL ------------------------------------------------ 
     JScrollPane sp1 = new JScrollPane(); 
     GridBagConstraints gbc1 = new GridBagConstraints(); 
     gbc1.fill = GridBagConstraints.BOTH; 
     gbc1.weightx = 99.0; 
     gbc1.weighty = 99.0; 
     contentPane.add(sp1, gbc1); 

     JPanel redPanel = new JPanel(); 
     redPanel.setBackground(Color.RED); 
     JTextField field = new JTextField(20); 
     GridBagConstraints gbc2 = new GridBagConstraints(); 
     gbc2.anchor = GridBagConstraints.PAGE_START; 
     gbc2.fill = GridBagConstraints.NONE; 
     contentPane.add(field, gbc2); 

     redPanel.add(field); 
     sp1.setViewportView(redPanel); 

     // BLUE PANEL ------------------------------------------------ 
     JScrollPane sp2 = new JScrollPane(); 
     GridBagConstraints gbc3 = new GridBagConstraints(); 
     gbc3.fill = GridBagConstraints.BOTH; 
     gbc3.gridx = 0; 
     gbc3.gridy = 1; 
     gbc3.weightx = 99.0; 
     gbc3.weighty = 99.0; 
     contentPane.add(sp2, gbc3); 

     JPanel bluePanel = new JPanel(); 
     bluePanel.setBackground(Color.BLUE); 
     sp2.setViewportView(bluePanel); 
    } 
} 

ОБНОВЛЕНИЕ 2 ---------------------------------------- --------------

По-прежнему имеют ту же проблему с размером JPanel, что и # 1 выше. Задача 1

enter image description here

+1

Рассмотрите возможность использования [runnable example] (https://stackoverflow.com/help/mcve), который демонстрирует вашу проблему. Это не дамп кода, а пример того, что вы делаете, что подчеркивает проблему, с которой вы сталкиваетесь. Это приведет к меньшему путанице и лучшим ответам – MadProgrammer

+0

Чтобы остановить появление вертикальных полос прокрутки, вы можете использовать политику 'VERTICAL_SCROLLBAR_NEVER' (см. [Oracle Docs JScrollPane] (https://docs.oracle.com/javase/tutorial/uiswing/components /scrollpane.html)). И действительно, сейчас немного сложно понять вашу проблему. – hamena314

+1

Спасибо за ваши комментарии, я добавил пример кода, который, надеюсь, опишет проблему, которую я хочу исправить. Любые советы будут высоко ценится. Большое спасибо. –

ответ

1

попробовать этот код:

package test; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.border.EmptyBorder; 

public class GridBagLayoutSample extends JFrame { 

private JPanel contentPane; 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       GridBagLayoutSample frame = new GridBagLayoutSample(); 
       frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

/** 
* Create the frame. 
*/ 
public GridBagLayoutSample() { 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 450, 300); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(contentPane); 
    GridBagLayout gbl_contentPane = new GridBagLayout(); 
    gbl_contentPane.columnWidths = new int[]{0, 0}; 
    gbl_contentPane.rowHeights = new int[]{50, 0, 0}; 
    //the 1.0 value in columnWeights let redPanel and scrollPane (that contain bleuPanel) grow horizontally 
    //the 1.0 value is in the first index so it affect the first column 
    //you still need to use a valid value for gbc_redPanel.fill and gbc_scrollPane.fill; 
    gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE}; 
    //the 0.0 value of rowWeights => components in first row will not grow 
    //the 0.0 value of rowWeights => components in second row will grow 
    gbl_contentPane.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE}; 
    contentPane.setLayout(gbl_contentPane); 

    JPanel redPanel = new JPanel(); 
    redPanel.setBackground(Color.RED); 
    GridBagConstraints gbc_redPanel = new GridBagConstraints(); 
    gbc_redPanel.insets = new Insets(0, 0, 5, 0); 
    gbc_redPanel.fill = GridBagConstraints.BOTH; 
    gbc_redPanel.gridx = 0; 
    gbc_redPanel.gridy = 0; 
    contentPane.add(redPanel, gbc_redPanel); 

    JScrollPane scrollPane = new JScrollPane(); 
    GridBagConstraints gbc_scrollPane = new GridBagConstraints(); 
    gbc_scrollPane.fill = GridBagConstraints.BOTH; 
    gbc_scrollPane.gridx = 0; 
    gbc_scrollPane.gridy = 1; 
    contentPane.add(scrollPane, gbc_scrollPane); 

    JPanel bleuPanel = new JPanel(); 
    bleuPanel.setBackground(Color.BLUE); 
    //scrollpane work with the preferred size of the component in the viewportView 
    //try to change this values 
    bleuPanel.setPreferredSize(new Dimension(400, 400)); 
    scrollPane.setViewportView(bleuPanel); 
} 

}

добавить это в ваш код

gbl_contentPane.rowHeights = new int[]{40, 0, 0}; 
gbl_contentPane.rowWeights = new double[]{0.0,0.0, 1.0, Double.MIN_VALUE}; 
gbc1.gridx = 0; 
gbc1.gridy = 0; 

и удалить этот

gbc1.weightx = 99.0; 
gbc1.weighty = 99.0; 
+0

Спасибо за ваше предложение, но я думаю, что я хочу немного отличаться от вашего сценария. Можете ли вы проверить мой вышеприведенный образец и дополнительный комментарий? –

+0

это не могло решить мою проблему. Высота панели поиска является переменной (зависит от типа), следовательно; Я не могу установить rowHeights явно. –

1

Я искал и пытался решить проблемы, с которыми столкнулся GridBagLayout, но безрезультатно.

Добро пожаловать в GridBagLayout.

Прежде всего следует отметить, что в

 JPanel redPanel = new JPanel(); 
     redPanel.setBackground(Color.RED); 
     JTextField field = new JTextField(20); 
//  GridBagConstraints gbc2 = new GridBagConstraints(); 
//  gbc2.anchor = GridBagConstraints.PAGE_START; 
//  gbc2.fill = GridBagConstraints.NONE; 
//  contentPane.add(field, gbc2); 

     redPanel.add(field); 
     sp1.setViewportView(redPanel); 

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

Я хочу, чтобы красная панель имела высоту, достаточную для того, чтобы содержать текстовое поле.

Об этом позаботится менеджер по планировке. Однако, если вы измените размер окна вручную, чтобы панели не было достаточно места, появятся полосы прокрутки, если панель находится в JScrollPane. Вы можете попробовать @OverridegetMinimumSize панели getPreferredSize, но не все менеджеры макетов уважают это, я считаю.

Несмотря на это, я не понимаю, почему вам требуется панель прокрутки для красной панели вообще.

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

Тогда вы должны установить его weighty на 0.

Примечание: не используйте подчеркивание (_) в неконечное имен переменных в соответствии с именования Java (gbl_contentPane должны быть gblContentPane).

Редактировать

Ниже приведен пример динамического изменения размера выделенной для redPanel. Я использую BorderLayout для панели контента (также предложенной Dan O) для простоты.

public class GBLSample extends JDialog { 

    private JPanel contentPane; 
    private JScrollPane redSP = new JScrollPane(new RedPanel()); 

    public static void main(String[] args) { 

     EventQueue.invokeLater(() -> { 
      GBLSample frame = new GBLSample(); 
      frame.setVisible(true); 
     }); 
    } 

    private class RedPanel extends JPanel { 

     RedPanel() { 

      setLayout(new GridBagLayout()); 
      setBackground(Color.RED); 

      GridBagConstraints c = new GridBagConstraints(); 
      c.anchor = GridBagConstraints.FIRST_LINE_START; 
      add(new JTextField(10), c); 
      c.weightx = 1; 
      c.gridx = 1; 
      add(new JComboBox<>(), c); 
      c.weightx = 0; 
      c.gridx = 0; 
      add(new JComboBox<>(), c); 
      c.gridx = 1; 
      add(new JComboBox<>(), c); 
      c.weighty = 1; 
      c.gridx = 0; 
      c.gridy = 2; 
      add(new JButton("SSSS"), c); 
     } 

     @Override 
     public Dimension getPreferredSize() { 

      Dimension dim = super.getPreferredSize(); 
      JScrollBar sb = redSP.getHorizontalScrollBar(); 
      if (!sb.isShowing()) 
       return dim; 
      return new Dimension(dim.width, dim.height + sb.getHeight()); 
     } 
    } 

    public GBLSample() { 

     setBounds(100, 100, 350, 400); 
     contentPane = new JPanel(new BorderLayout()); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 

     // RED PANEL ------------------------------------------------ 
     redSP.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); 
     contentPane.add(redSP, BorderLayout.PAGE_START); 

     // BLUE PANEL ------------------------------------------------ 
     JPanel bluePanel = new JPanel(); 
     bluePanel.setBackground(Color.BLUE); 
     contentPane.add(new JScrollPane(bluePanel)); 
    } 
} 

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

+0

Спасибо @ user1803551. Очень ценю вашу помощь. Если я изменю свой весовый на 0, перетащите окно влево, чтобы сделать его немного более узким, мое текстовое поле на красной панели перестало существовать. –

+0

Несмотря ни на что, я не понимаю, почему вам нужна панель прокрутки для красной панели вообще. <- Моя панель поиска содержит много содержимого, цели панели прокрутки помогают тем, у кого узкие экраны. Помимо использования панели прокрутки, есть ли у вас другое предложение, которое сделает прокрутку красной панели? –

+0

@IamRiz Насколько маленький экран? Мобильное устройство? У них есть свои собственные парадигмы дизайна GUI. – user1803551

1

Возможно, GridBagLayout может не подойти для вашего текущего пользовательского интерфейса, а BorderLayout будет работать лучше? Поместите красную панель в BorderLayout.NORTH и положите синюю панель в BorderLayout.CENTER. Компоненты в области CENTER будут увеличиваться и уменьшаться при изменении размера диалогового окна, а предпочтительный размер вашей красной панели будет соблюдаться как +/-.

+0

В то время как использование 'BorderLayout' проще для текущего состояния графического интерфейса, я бы не пошел на консультацию« * не используйте «GridBagLayout' *». Это вполне приемлемо как в практическом, так и в образовательном плане, поскольку мы не можем знать, как будет развиваться GUI. – user1803551

+0

oh абсолютно - GBL можно определенно использовать здесь. Но какой-то язык в вопросе («Какой менеджер макета должен использовать для решения этой проблемы с изменением размера? Если мне действительно нужно использовать GridBagLayout, какие ограничения/настройки следует использовать?»), Казалось, оставляют вещи открытыми для альтернатив. –

+0

Правда. Тогда, возможно, подумайте о том, чтобы перефразировать что-то вроде «Я бы рекомендовал не использовать ...» или «это более подходит для использования ... чем использовать ...» с упоминанием «в текущем состоянии GUI»? – user1803551

0

К сожалению, в переопределенной системе JPanel.getMinimumSize() была обнаружена ошибка, из-за которой моя панель поиска вышла из строя. Я смог найти исправление для него уже без изменения каких-либо настроек с помощью настроенного менеджера компоновки системы. Тем не менее, большое спасибо за все ваши ответы и помощь.

Смежные вопросы