Создание текстового поля, которое динамически изменяет его ширину - PullRequest
2 голосов
/ 05 апреля 2011

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

Вот что я получил:

final JTextField searchField = new JTextField("Enter your search terms");
searchField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
final JPanel controls = new JPanel(new BorderLayout());
controls.add(searchField, BorderLayout.CENTER);
controls.add(new JPanel(){{
    add(new JButton("Search")); add(new JButton("I'm Feeling Lucky"));
}}, BorderLayout.LINE_END);

Казалось бы, такое поведение обычно желательно, и его должно быть легко реализовать, но мне не повезло после просмотра всех учебных пособий по Oracle / Sun и результатов поиска Google.

У кого-нибудь есть какие-нибудь решения для этого?Мне нужно придерживаться стандартных компонентов Java Swing - пожалуйста, никаких сторонних библиотек.

Спасибо!

Ответы [ 4 ]

2 голосов
/ 05 апреля 2011

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

Вот пример использования gridbaglayout для этого вопроса ...

import java.awt.BorderLayout;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

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

public class GridBagLayoutExample extends JFrame {

    GridBagLayoutExample() {
        initUI();
    }


    private void initUI() {
        final JTextField searchField = new JTextField("Enter your search terms"); 
        final JPanel controls = new JPanel(new GridBagLayout()); 
        GridBagConstraints c = new GridBagConstraints();
        c.weightx=1.0;
        c.fill=GridBagConstraints.HORIZONTAL;
        controls.add(searchField,c); 
        controls.add(new JPanel(){
            {     
            add(new JButton("Search")); add(new JButton("I'm Feeling Lucky")); }}); 
        setLayout(new BorderLayout());
        add(controls, BorderLayout.NORTH);
        pack();
    }


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new GridBagLayoutExample().setVisible(true);

            }
        });
    }
}
1 голос
/ 05 апреля 2011

это проблема из двух частей:

a) все xxSize (xx = min / max / pref) являются простыми подсказками для LayoutManager. Каждый LayoutManager имеет свое собственное поведение, если / как / когда он учитывает эти подсказки, и если / как / когда он нарушает один или несколько, если общее пространство больше или меньше, чем соответствует сумме pref для всех компонентов в контейнере. Нет никакого способа, кроме как узнать, что делает (документация ... эм ... субоптимальная)

b) JTextField немного сумасшедший, позволяя его высоте расти бесконечно, если позволяет пространство. Подразумевается, что даже менеджеры LayoutManers, которые уважают max (как, например, BoxLayout), не имеют шансов сделать это, max - это Integer.MAX_VALUE (или Short.MAX? Забыли). Чтобы заставить его вести себя, создайте подкласс и переопределите maxSize, чтобы вернуть преф высоту:

@Override
Dimension getMaximumSize() {
   Dimension max = super.getMaximumSize();
   max.height = getPreferredSize().height; 
   return max;
}
0 голосов
/ 05 февраля 2019

Использование BoxLayout .

JTextField search_field = new JTextField("Enter search term");
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(search_field);

Это будет динамически изменять размер текстового поля при изменении размера фрейма.

0 голосов
/ 05 апреля 2011

Вы должны иметь возможность использовать горизонтальный BoxLayout.

searchField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25)); 

Не стоит угадывать высоту текстового поля.

Dimension d = searchField.getPreferredSize();
d.width = Integer.MAX_VALUE;
searchField.setMaximumSize(d);

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

...