Ответ 1
Сначала код, затем объяснение. Попробуйте следующее:
import java.awt.Cursor;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutTest extends JFrame {
private JPanel panel;
private JLabel lblResumenAuto;
private JLabel lblResumenAutoResult;
private JLabel lblResumenRazonSocial;
private JLabel lblResumenRazonSocialResult;
private JLabel lblResumenPeriodo;
private JLabel lblResumenPeriodoResult;
private JLabel lblResumenFechaHora;
private JLabel lblResumenFechaHoraResult;
public MigLayoutTest() {
run();
}
public void run() {
panel = new JPanel();
panel.setLayout(new MigLayout("debug, fill",
"[left, 15%]10[left, 35%]10[left, 15%]10[left, 35%]", "[center]10[center]"));
lblResumenAuto = new JLabel("MY LABEL 1111111111111");
lblResumenAutoResult = new JLabel("1111111111111111111111");
panel.add(lblResumenAuto, "sg label");
panel.add(lblResumenAutoResult, "sg value");
lblResumenRazonSocial = new JLabel("MY LABEL 2222222222");
lblResumenRazonSocialResult = new JLabel("2222222222222222222222");
panel.add(lblResumenRazonSocial, "sg label");
panel.add(lblResumenRazonSocialResult, "sg value, wrap");
lblResumenPeriodo = new JLabel("MY LABEL 33333333333333");
lblResumenPeriodoResult = new JLabel("3333333333333333333333333333333333333333333333333333333");
panel.add(lblResumenPeriodo, "sg label");
panel.add(lblResumenPeriodoResult, "sg value");
// poner el texto como html puede tener otra linea, porque es muy largo
lblResumenFechaHora = new JLabel("<html>MY LABEL <br /> 4444444444444444</html>");
lblResumenFechaHoraResult = new JLabel("4444444444444444444444444");
panel.add(lblResumenFechaHora, "sg label");
panel.add(lblResumenFechaHoraResult, "sg value");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
getContentPane().add(panel);
pack();
setVisible(true);
setLocationRelativeTo(null);
setResizable(true);
}
public static void main(String[] args) {
MigLayoutTest test = new MigLayoutTest();
}
}
Объяснение моих изменений:
Теперь, кроме упрощения кода и макета, я использовал "debug" в пределах ограничений макета, чтобы увидеть, что на самом деле происходит с макетом. Я предлагаю использовать его в любое время, когда что-то пойдет не так с макетом - он делает MigLayout
рисовать границы компонентов и ячеек, визуализируя потенциальные проблемы.
Я удалил ненужные mainframe
и p
- если вам действительно нужно это для вложенного макета, попробуйте добавить его, как только вы решите внутренний макет по своему вкусу.
Что касается p
и panel
- возможно, вам нужны два разных макета, один вложенный в другой, но это фактический источник вашей проблемы. p
имел также собственный макет сетки,
p.add(panel,"cell 0 0");
вы помещаете panel
в верхнюю левую ячейку p
- вот почему panel
не был распределен по всему окну, а сидел в верхнем левом углу.
Как вы видите без p
, он позитивно позиционируется в середине экрана без постоянного размера, все еще отображая все компоненты, но, что более важно, он имеет 50% размера окна для первого и 50% для последних двух колонны. Это было достигнуто путем предоставления компонентам "группы размеров":
Дает компоненту имя группы размеров. Все компоненты, имя группы размеров получит тот же BoundSize (min/preferred/max). это используется для обеспечения того, чтобы все компоненты группы одинакового размера такой же минимальный/предпочтительный/максимальный размер, который является самым большим компонентом в группа. Можно использовать пустое имя "".
И это также изменяет размеры, как должно!
Вложенная компоновка также могла быть корнем другой проблемы - не знаете, не заметили ли вы ее, или она просто не появилась на вашей машине, но если бы я попытался изменить размер вашего окна, panel
стал шире и шире ( никогда не суше), даже если я скрою окно. В какой-то момент он стал шире, чем само окно, и даже тогда расширялся при каждом изменении размера.
Далее - установка размеров в постоянное значение не имеет смысла, поскольку после pack
менеджер компоновки начинает определять все, основываясь на предпочтительных размерах окна и его содержимого. Кроме того, вы никогда не знаете, какой размер является вашим экраном пользователей, поэтому любой постоянный размер может быть одинаково плохим, если его эффективно использовать. Лучше управлять размером через контент и доступную среду выполнения. С вашим кодом на моей машине потребовалось все доступное горизонтальное пространство на моих двух экранах (2 x 1280) и отлично выглядело.
Я также думаю, что вам не нужно запускать фрейм с помощью EventQueue.invokeLater
, просто создайте MigLayoutTest
и это он.
ИЗМЕНИТЬ после собственного ответа OP
Настройка размера с помощью setBounds(0, 0, 1250, 500)
до pack
работает некорректно (под этим я подразумеваю, чтобы размер окна был таким). Даже на скриншоте ниже OP собственный ответ не высок на 500 пикселей. Вот что я получаю в Windows 7 с JDK 1.8.0_91:
Размер моего экрана - 1280 x 1024, размер окна программы - 914 x 301.
Я бы предложил использовать одно из следующих действий:
Чтобы установить его на постоянный размер 1250 x 500 пикселей, переместите setSize
между pack
и setVisible
:
...
pack();
setSize(1250, 500);
Я бы использовал setSize
, setBounds
не имеет смысла, так как, вызывая setLocationRelativeTo(null)
, вы все равно центрируете окно программы на экране, так что начало немедленно отклоняется.
Чтобы максимизировать горизонтальную ориентацию, а высота должна быть 500 пикселей, установите предпочтительный размер основного окна перед pack
:
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setPreferredSize(new Dimension(screenSize.width, 500));
И чтобы максимизировать горизонтально и позволить предпочтительную высоту, поскольку она была изначально:
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setPreferredSize(new Dimension(screenSize.width, getPreferredSize().height));
Конечно, вы можете сделать окно размером 1250 x 500 большим, установив его предпочтительный размер, а не используя setSize
.
Проблема с изменением размера сейчас не такая большая, но она все еще там - сделайте окно более широким, чем узкое. Вы заметите, что panel
становится шире, даже если окно сузилось. Проблема в том, что компонент panel
не становится достаточно большим, чтобы сначала заполнить один столбец p
(BTW вы можете добавить флаг "debug" для каждого MigLayout, а также для panel
- он затем набросает все внутренние компоненты также).
Чтобы заполнить родительский контейнер, добавьте его так:
p.add(panel, "cell 0 0, grow");
Теперь это полная ширина p
с самого начала, и изменение размера работает как ожидалось.
Относительно запуска JFrame
с помощью invokeLater
- мы запускаем наши главные окна, как правило, без него, и у них никогда не было проблем, поскольку никаких взаимодействий с Swing не было, пока первый кадр не был виден, но я только что заметил, что это считается лучшей практикой - даже в учебниках Oracle. Похоже, я тоже кое-что узнал: -).
Сравнение окна кадра с добавлением и без добавления с выражением
Тестовый сценарий: запустите приложение и измените его размер.
Как вы видите на первом снимке экрана размер компонента меньше ширины столбца - похоже, что компонент находился за размером столбца при изменении размера. На втором скриншоте ширина компонента остается такой же, как ширина столбца. Как я сказал ранее, причиной может быть сочетание Java и/или операционной системы, я не знаю. Но, очевидно, это ведет себя по-другому и на моей машине менее оптимальной.