Вопрос по swing, java – Как остановить JLabel, изменяя его размер при изменении текста?

3

Я генерирую несколько JComponents в коде и использую макет GridBag для их упорядочения. Мой макет состоит из 12 строк и 3 столбцов, причем каждая строка состоит из JSlider, JCheckBox и JLabel. Вот код, который я использую для создания пользовательского интерфейса:

final int NUM_MOTORS = 12;

// This is the panel I'm adding the components to.
pnlMotorSliders.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

for (int i = 0; i < NUM_MOTORS; ++i) {
    c.gridy = i;

    // Create the slider
    JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 10, 4085, 10);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.weightx = 0.9;
    pnlMotorSliders.add(slider, c);

    // Create the checkbox
    JCheckBox checkBox = new JCheckBox();
    checkBox.setOpaque(true);
    checkBox.setBackground(Color.blue);
    c.fill = GridBagConstraints.NONE;
    c.gridx = 1;
    c.weightx = 0.1;
    pnlMotorSliders.add(checkBox, c);

    // Create the current label
    JLabel label = new JLabel("0");
    label.setBorder(BorderFactory.createLineBorder(Color.red));
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 2;
    c.weightx = 0.2;
    pnlMotorSliders.add(label, c);
}

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я устанавливаю текст в любом из JLabels, они меняют свою ширину и влияют на остальную часть макета, даже если ширина текста, который я задаю, кажется намного меньше, чем ширина JLabel. Следующие два скриншота демонстрируют, что я имею в виду (красная и синяя границы были для целей отладки):

Я установил текст в нижней части JLabel на "-12". Несмотря на то, что JLabel выглядит намного шире, чем текст, он изменил свой размер, затрагивая остальную часть макета.

Почему это происходит и что я могу сделать, чтобы предотвратить это?

Если вы препятствуете расширению метки по мере необходимости для размещения ее текста, она может стать нечитаемой; Большеhere. trashgod

Ваш Ответ

4   ответа
0
label.setPreferredSize(new Dimension(width, height));

Minimum и / илиMaximum ничего не сделал для меня. Кроме того, для меня на Java 8 мне нужно было использоватьDimension, или не было изменений в предыдущих, неподходящих размерах.

5

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

label.setMinimumSize(width, height);
label.setPreferedSize(width, height);
label.setMaximumSize(width, height);

Также убедитесь, что для заполнения GridBagConstraints # установлено значение NONE, хотя я не уверен, что это все еще необходимо (я так думаю).

EDIT: кстати, чтобы избавиться от этих неприятных пунктирных линий вокруг сфокусированного компонента, вы можете просто установить его как не фокусируемый:

slider.setFocusable(false);
Спасибо, это похоже на работу. Я немного поэкспериментировал и обнаружил, что мне нужно только вызвать setPreferredSize, чтобы установить размер JLabel. Два других, кажется, не имеют значения. Также спасибо за совет по setFocusable. Вопрос, который у меня сейчас возникает, почему я столкнулся с этой проблемой в первую очередь? В моем исходном макете метка была шире, чем нужно, но при изменении текста она по-прежнему меняла ширину, хотя текст был явно намного меньше, чем метка. Amr Bekhit
@ AmrBekhit Да, setPreferredSize достаточно, если есть свободное место. Но если нет, другие компоненты уберут его, и ярлык будет вынужден быть меньше (или больше). Но для вашего приложения я думаю, setPreferredSize достаточно. Причина, по которой он изменился, заключается в том, что, если он не задан, предпочтительный размер метки зависит от отображаемого текста. Кстати:label.setHorizontalAlignment(JLabel.RIGHT); может быть тоже полезно. ;) brimborium
Если это не фокусируется, как настроить его с клавиатуры? Catalina Island
@ CatalinaIsland Вы не можете (если вы не создадите KeyListener, который изменяет его косвенно). Но, на мой взгляд, JSlider следует модифицировать с помощью мыши, а не клавиатуры в любом случае. ;) brimborium
нет, какая бы проблема, настройка размера подсказок компонентан решени ... вместо этого используйте достойный LayoutManager kleopatra
1

только если у вас нет компонентов, заполняющих их по горизонтали в GridBagLayout.

Еще одно решение - убрать вес, который вы поместили на компоненты в этом столбце GridBagLayout. Затем вы можете контролировать ширину столбца вручную. Простой способ сделать это (во время разработки) - поместить JLabel в столбец с нулевой высотой и желаемой шириной.

Почему это? Вам нужно разобраться, как работает GridBagLayout:

The GridBagLayout изменяет размеры своих столбцов в соответствии с требуемым пространством, а затем использует весовые коэффициенты для выделения «оставшегося» пространства так, чтобы результирующие ширины столбцов затем складывались в общую ширину панели. Пространство, необходимое для каждого столбца, вычисляется путем нахождения самых широких компонентов в этом столбце.

Пространство, требуемое для каждого компонента, определяется путем запроса его ширины. В вашем случае JLabel с "0" меньше, чем JLabel с "-12", поэтому столбец меняет размер.

Оставшееся пространство выделяется на основе горизонтальных весов, назначенных компонентам в каждом столбце. Веса суммируются, и проценты для каждого столбца определяются на основе процента этого столбца от общего числа.

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

Третье решение - просто не использовать GridBagLayout.

0

Предпочтительным размер ваших ярлыков с помощьюJLabel#setPreferredSize(Dimension).

Таким образом, тызамо размер компонента и попросите менеджера макета не изменять его размер.

Похоже, это не работает. Я добавил следующую строку при создании метки:label.setSize(new Dimension(50, label.getPreferredSize().height)); и установите GridBag Fill на NONE. К сожалению, метка игнорирует мое измерение, использует его размер по умолчанию и меняет свою ширину при изменении текста. Я пытался установить размер метки как до, так и после добавления его в родительский контейнер. Amr Bekhit
Я отредактировал оригинальный ответ. Сделал немного кодирования и похоже, что просто установкаpreferredSize достаточно (независимо от того, чтоfill значение есть). Проверьте, работает ли он у вас, я выложу код, если вам нужно. npe
нет, какая бы проблема, настройка размера подсказок компонентан решени ... вместо этого используйте достойный LayoutManager kleopatra

Похожие вопросы