Я подготовил 2 тестовых примера в стиле JUnit (извините за странный вид теста, я действительно не знаю, как утверждать пользовательский интерфейс) для второго примера я выборочно обрезаю строку, но я хочу иметь возможность вставить длинную строку и чтобы пользовательский интерфейс правильно обрезал ее.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.WindowEvent;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.junit.jupiter.api.Test;
public class testing {
@Test
public void howItsSupposedToLook() {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setVisible(true);
frame.setSize(1000, 900);
JPanel leftPanel = new JPanel();
leftPanel.setBackground(Color.GREEN);
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
// this is how it should look
JLabel fileLabel3 = new JLabel(
"<html><div style=\"padding-left:1px;padding-top:10px\"><div style=\"border:1px;font-size: 10px;line-height: 11px; height:23px;overflow:hidden;width:"
+ (100) + "px;white-space:nowrap;\">" + "fsdfesfevvveeeg" + "</div></div></html>");
leftPanel.add(fileLabel3);
//no more differences between the two from here
frame.add(leftPanel, BorderLayout.LINE_START);
JPanel centerPAnel = new JPanel();
centerPAnel.setBackground(Color.RED);
frame.add(centerPAnel, BorderLayout.CENTER);
frame.validate();
frame.repaint();
boolean open = true;
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(WindowEvent winEvt) {
System.exit(0);
}
});
while (open) {
}
}
@Test
public void failedTest() {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setVisible(true);
frame.setSize(1000, 900);
JPanel leftPanel = new JPanel();
leftPanel.setBackground(Color.GREEN);
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
// this is how it actually looks
JLabel fileLabel = new JLabel(
"<html><div style=\"padding-left:1px;padding-top:10px\"><div style=\"border:1px;font-size: 10px;line-height: 11px; height:23px;overflow:hidden;width:"
+ (100) + "px;white-space:nowrap;\">"
+ "fsdfesfevvveeegggggggggggggggggggggggevevsdffffffffffffffffffffffffffffffffffffffffffffffffffffffffh"
+ "</div></div></html>");
fileLabel.setMaximumSize(new Dimension(100, 40));
//no more differences between the two from here
leftPanel.add(fileLabel);
frame.add(leftPanel, BorderLayout.LINE_START);
JPanel centerPAnel = new JPanel();
centerPAnel.setBackground(Color.RED);
frame.add(centerPAnel, BorderLayout.CENTER);
frame.validate();
frame.repaint();
boolean open = true;
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(WindowEvent winEvt) {
System.exit(0);
}
});
while (open) {
}
}
}
как это должно выглядеть (первый (изготовленный) пример):
как это выглядит на самом деле:
мне кажется, что макет неправильно распознает длину JPanel. Кто-нибудь знает, что с этим делать?
да, я заметил это (в начале я пробовал скрытый режим переполнения и режим многоточия, но мне пришлось отказаться от этого)
Ваша проблема - одна из каскадных проблем. Использование BoxLayout
в BorderLayout
и тот факт, что большая часть CSS, вероятно, была проигнорирована. У вас также будут проблемы, поскольку текст не будет переноситься, потому что он хочет переноситься на границу слова, а не на границу символа.
Предложение — вместо этого используйте нередактируемый JTextArea
, установите перенос слов, как демонстрирует второй пример здесь
@MadProgrammer текст, который невозможно обернуть, предназначен для того, чтобы иметь список элементов и поместить их как можно больше в представление, отображать только первую строку каждого конца, если это необходимо (да, это, вероятно, плохо UX, но я не думаю, что они будут пользователями, кроме меня, в ближайшем или далеком будущем :D)
Тогда не используйте BorderLayout
, это даст столько места, сколько запрашивает компонент preferredSize
. Играть с setPreferredSize
— тоже плохая идея, так как на результат влияет множество факторов. «Другая» идея может состоять в том, чтобы использовать JList
и определить значение ячейки prototype
, которое соответствует ограничениям длины символа, но это будет зависеть от настроек шрифта (поэтому, когда размер шрифта изменится, ширина изменится)
Просто используйте
fileLabel.setPreferredSize(new Dimension(100, 40));
Вместо
fileLabel.setMaximumSize(new Dimension(100, 40));
Этот установщик сообщает, какой размер должен использоваться как «предпочтительный» для этого компонента, когда он помещается в контейнер с менеджером компоновки.
PS: извините за мой английский
Проблема возникает из-за использования чисел, отличных от фактического предпочтительного размера, который рассчитывается во время выполнения и может варьироваться в зависимости от платформы. См. также Должен ли я избегать использования методов set(Preferred|Maximum|Minimum) Size в Java Swing?
Начнем с того факта, что поддержка Swing HTML/CSS ограничена и не поддерживает текущий стандарт (я думаю, что HTML 3ish, не могу вспомнить поддержку CSS).