#java #swing
#java #swing
Вопрос:
Я создаю панель, которая будет использоваться в более крупной программе; следующая программа по-прежнему иллюстрирует мой вопрос, но она выглядит немного сложнее, чем нужно, потому что есть места, которые я добавлю позже.
package sandbox;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SpacingPlay extends JFrame
{
private static final long serialVersionUID = 1L;
public static void main(String[] args)
{
SpacingPlay sp = new SpacingPlay();
sp.setVisible(true);
}
public SpacingPlay()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new DragNDropPanel();
add(panel);
pack();
}
class DragNDropPanel extends JPanel
{
private static final long serialVersionUID = 1L;
public DragNDropPanel()
{
JPanel currentImagePanel = getCurrentImagePanel();
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
leftPanel.add(currentImagePanel);
// other things will go here; I cut them out to make this simpler.
setLayout(new BorderLayout());
// put things in a containing panel so that they aren't stretched being in the WEST part of a borderlayout.
JPanel leftContainingPanel = new JPanel();
leftContainingPanel.add(leftPanel);
add(leftContainingPanel, BorderLayout.WEST);
}
private Component createStandardSpace()
{
return Box.createRigidArea(new Dimension(0, 15));
}
private JPanel getCurrentImagePanel()
{
JPanel currentImagePanel = new JPanel();
currentImagePanel.setLayout(new BoxLayout(currentImagePanel, BoxLayout.PAGE_AXIS));
JLabel currentImageLabel = new JLabel("none");
currentImageLabel.setBorder(BorderFactory.createDashedBorder(Color.BLUE));
currentImageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
Dimension defaultLabelSize = new Dimension(150,150); // was expecting this to enlarge the label.
currentImageLabel.setPreferredSize(defaultLabelSize);
currentImageLabel.setSize(defaultLabelSize);
JButton clearButton = new JButton("Clear");
clearButton.setAlignmentX(Component.CENTER_ALIGNMENT);
clearButton.setBorder(BorderFactory.createLineBorder(Color.GREEN));
currentImagePanel.add(currentImageLabel);
currentImagePanel.add(createStandardSpace());
currentImagePanel.add(clearButton);
currentImagePanel.setBorder(BorderFactory.createLineBorder(Color.ORANGE));
return currentImagePanel;
}
}
}
Я хотел бы currentImageLabel
, чтобы это был стандартный размер; Я намереваюсь, чтобы в него были вставлены разные изображения во время программы, и хочу, чтобы он получал их без изменения размера. Моя идея заключалась в том, чтобы установить размер и предпочтительный размер, а затем масштабировать изображения, которые я туда помещаю, до этого размера.
Однако defaultLabelSize
это не имеет того эффекта, который я ожидал. Метка переходит в панель BoxLayout; она добавляется, затем жесткий пробел, затем кнопка. Я ожидал, что метка будет иметь размер по умолчанию, а не уменьшена до минимально допустимого. Я вставил цветные границы, чтобы попытаться лучше понять, что происходит; похоже, что предпочтительный размер учитывается для общей панели BoxLayout, но не для размещения кнопки под меткой. РЕДАКТИРОВАТЬ: другими словами, я хочу, чтобы кнопка под меткой размещалась под меткой, когда метка должна быть больше. Но размер, который я указываю на ярлыке, похоже, не работает.
Что мне нужно сделать, чтобы исправить размер currentImageLabel
?
Ответ №1:
Не на 100%, почему размер метки соответствует только тексту, а не (жестко заданному) предпочтительному размеру. Я не смог воспроизвести это поведение, используя другие комбинации панелей и менеджеров компоновки.
Вы используете pack, поэтому все компоненты должны иметь желаемые размеры.
Dimension defaultLabelSize = new Dimension(150,150); // was expecting this to enlarge the label.
currentImageLabel.setPreferredSize(defaultLabelSize);
currentImageLabel.setSize(defaultLabelSize);
Несколько комментариев:
-
Установка размера никогда не будет работать. Менеджер компоновки всегда переопределяет размер / местоположение на основе правил менеджера компоновки.
-
Менеджер компоновки может использовать (или игнорировать) предпочтительные, минимальные и максимальные размеры компонента. В случае
BoxLayout
is пытается использовать предпочтительный размер, но будет учитывать минимальный и максимальный размеры (в зависимости от доступного пространства на родительской панели).
Что мне нужно сделать, чтобы исправить размер currentImageLabel ?
Итак, для достижения желаемой цели фиксированного предпочтительного размера для JLabel вы можете использовать:
Dimension defaultLabelSize = new Dimension(150,150); // was expecting this to enlarge the label.
currentImageLabel.setPreferredSize(defaultLabelSize);
currentImageLabel.setMinimumSize(defaultLabelSize);
currentImageLabel.setMaximumSize(defaultLabelSize);
//currentImageLabel.setSize(defaultLabelSize);
Редактировать:
искал, почему это, похоже, не работает
Для получения дополнительных разъяснений измените исходный код на:
currentImageLabel.setPreferredSize(defaultLabelSize);
System.out.println(currentImageLabel.getPreferredSize());
System.out.println(currentImageLabel.getMinimumSize());
System.out.println(currentImageLabel.getMaximumSize());
Вы увидите, что минимальные и максимальные размеры метки не затрагиваются.
Из пункта 2 выше вы увидите, что BoxLayout соответствует максимальному размеру.
Следовательно, также переопределяя максимальный размер, вы разрешаете отображать метку в предпочтительном размере.
Однако, когда вы вычисляете предпочтительный размер «currentImagePanel», (жестко заданный) предпочтительный размер метки используется при вычислении предпочтительного размера панели, так что панель отображается в предпочтительном размере.
Еще одна записка. «leftContainingPanel» не требуется. Вы можете просто добавить «Левую панель» в BorderLayout.ЗАПАД, так как BorderLayout будет учитывать ширину добавляемого вами компонента.
Комментарии:
1. Что ж, я чувствую себя немного лучше оттого, что ты тоже этого не знаешь. Я боялся, что это было что-то очевидное. Я только что обнаружил, что добавление параметра максимального размера дало эффект; кажется немного странным, но это так. Спасибо.
2. Ну, я искал, почему это, похоже, не работает, но я думаю, что вы действительно ответили на фактический вопрос. Добавлено принятие.