Как расположить компоненты только в вертикальной полосе прокрутки?
У меня сложный вопрос, я нигде не могу найти ответ.
вот пример:
public static void main(final String[] args) {
final JFrame frame = new JFrame("test");
final JPanel bigPane = new JPanel(new GridLayout(0, 1));
frame.setContentPane(new JScrollPane(bigPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
bigPane.add(new JTextField("reterterter ertertrert erterter ert"));
bigPane.add(new JTextField(" ertertrert erterter ert"));
bigPane.add(new JTextField("reterterter ertertrert ert"));
bigPane.add(new JTextField("reterterter ertertrert erterter "));
frame.pack();
frame.setSize(frame.getSize().width/2, frame.getSize().height);
frame.setVisible(true);
}
Здесь явно текстовые поля обрезаны. Точнее, bigPane режется. Но я бы хотел, чтобы текстовые поля были изменены, а не вырезаны, чтобы мы могли их использовать.
Поскольку горизонтальная полоса прокрутки запрещена, я хотел бы, чтобы макет забывал предпочтительную ширину вида (bigPane) и всегда заставлял ширину вида соответствовать ширине области просмотра. Как будто не было бы виртуального видового экрана для горизонтального направления, только в вертикальном.
Я не могу найти решение, и даже не взломать, спасибо, если вы можете помочь.
Нико.
PS: похоже, что код для ViewportLayout не содержит никакого кода для этого
PS2: вот шапка результата кода выше http://www.nraynaud.com/kilombo/testLayout.png с правой стороны.
3 ответа
Я думаю, что "правильный" способ сделать это - использовать интерфейс Scrollable:
public class ScrollPaneWidthTrackingPanel extends JPanel implements Scrollable {
private static final long serialVersionUID = 1L;
public ScrollPaneWidthTrackingPanel(LayoutManager layoutManager) {
super(layoutManager);
}
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return Math.max(visibleRect.height * 9 / 10, 1);
}
public boolean getScrollableTracksViewportHeight() {
return false;
}
public boolean getScrollableTracksViewportWidth() {
return true;
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return Math.max(visibleRect.height / 10, 1);
}
}
Затем две строки вашего кода должны измениться на:
final ScrollPaneWidthTrackingPanel bigPane = new ScrollPaneWidthTrackingPanel(new GridLayout(0, 1));
frame.setContentPane(new JScrollPane(bigPane));
И компоненты всегда должны заполнять всю ширину JScrollPane, независимо от размера кадра. Это изменение имеет побочный эффект, что компоненты теперь не будут заполнять высоту JScrollPane. Чтобы решить эту проблему, добавьте следующий код в начало метода getScrollableTracksViewportHeight:
if (getParent() instanceof JViewport) {
JViewport viewport = (JViewport) getParent();
return component.getPreferredSize().height < viewport.getHeight();
}
Использовать JTextField
конструктор, который принимает int
в качестве параметра. Это количество видимых символов в текстовом поле. Вы можете использовать setText
инициализировать содержимое поля (при необходимости).
В качестве альтернативы, установите максимальные и предпочтительные размеры (setMaximumSize
, setMinimumSize
) текстовых полей соответственно.
Из JavaDoc:
Параметры:
текст - текст, который будет отображаться, или нуль
столбцы - количество столбцов, используемых для расчета предпочтительной ширины; если столбцы установлены в ноль, предпочтительной шириной будет то, что естественно получается в результате реализации компонента
Так как вы вызываете конструктор 0, вы получаете реализацию "все, что естественно получается", которая принимает длины ваших слишком длинных строк. Простое обращение к конструктору столбцов с ненулевым значением исправит это за вас. Попробуйте эти строки:
bigPane.add(new JTextField("reterterter ertertrert erterter ert",3));
bigPane.add(new JTextField(" ertertrert erterter ert",3));
bigPane.add(new JTextField("reterterter ertertrert ert",3));
bigPane.add(new JTextField("reterterter ertertrert erterter ",3));
Вот скриншот полученной панели: