JGoodies FormLayout и JWindow

У меня проблема со свингом, которую я не могу решить уже целый день. Я хочу показывать всплывающее окно в JWindow, если кто-то вводит JTextField. Но если макет использует JGoodies FormLayout с большим количеством компонентов в одной строке, то отображение будет повреждено.

У тебя есть идеи?

Скриншот после ввода нескольких букв во второе текстовое поле:

введите здесь описание изображения

После редактирования кода Jans и трехкратного ввода «a»:

введите здесь описание изображения

Код на Java:

package eu.eyan;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JWindow;

import com.jgoodies.forms.factories.CC;
import com.jgoodies.forms.layout.FormLayout;

    public class Snippet {
        public static void main(String[] args) {

            JTextField tf = new JTextField(10);

            JPanel panel = new JPanel();
            panel.setLayout(new FormLayout("p", "p,p,p"));
            panel.add(new JTextField("before"), CC.xy(1, 1));
            panel.add(tf, CC.xy(1, 2));
            panel.add(new JTextField("after"), CC.xy(1, 3));

            JFrame frame = new JFrame();
            frame.setLayout(new FormLayout("p,p,p", "p"));
            frame.add(new JLabel("bef"), CC.xy(1, 1));
            frame.add(panel, CC.xy(2, 1));
            frame.add(new JLabel("aft"), CC.xy(3, 1));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
            frame.pack();

            JWindow popup = new JWindow();
            popup.setLayout(new FormLayout("p", "p"));
            JLabel l = new JLabel("popup");
            popup.add(l, CC.xy(1, 1));
            popup.pack();

            tf.addKeyListener(new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {
                    popup.setVisible(true);
                }
            });
        }
    }

person Andras    schedule 04.09.2016    source источник
comment
Где упаковано окно? Кстати val panel = new JPanel(); Что такое val? Чтобы быстрее получить помощь, опубликуйте минимально воспроизводимый пример или Короткий, автономный, правильный пример.   -  person Andrew Thompson    schedule 04.09.2016
comment
Запаковано: frame.pack-› для приложения popup.pack -> для всплывающего окна JWindow val: как я писал код написан на Scala.   -  person Andras    schedule 04.09.2016
comment
Кажется, что popup не упакован, пока не будет обнаружен KeyEvent. Он должен быть упакован до того, как станет видимым!   -  person Andrew Thompson    schedule 04.09.2016
comment
Код сейчас на Java. @Andrew: расположение пакета не помогло.   -  person Andras    schedule 04.09.2016
comment
Хм.. Я не знаком с этим конкретным макетом, так что, надеюсь, эксперт скоро появится.   -  person Andrew Thompson    schedule 04.09.2016


Ответы (1)


Лучший способ получить помощь с макетом — предоставить эскиз вашего пользовательского интерфейса в виде изображения или в виде ASCII. Здесь я только догадываюсь, что вы имели в виду.

Во-первых, FormLayout — хороший макет; он создает переносимые макеты. В отличие от старых макетов, таких как BoxLayout или GridBagLayout, здесь используются диалоговые единицы вместо пикселей. Таким образом, можно создать переносимый макет для различных размеров экрана. На самом деле, FormLayout был первым менеджером компоновки Java, который позволял создавать действительно переносимые пользовательские интерфейсы. Другие два, которые могут это сделать, это MigLayout и GroupLayout.

Если можете, попробуйте вместо этого использовать MigLayout. MigLayout был вдохновлен FormLayout и значительно улучшил его. Например, в MigLayout вы используете установку зазоров один раз, тогда как в FormLayout вам приходится утомительно учитывать зазоры при создании макета.

Исправления:

1) Вызовите метод pack() перед методом setVisible().

2) Не используйте ненужные панели для создания макета. Вы, наверное, видели несколько примеров, когда для создания макета использовались панели. Это произошло потому, что такие менеджеры, как BoxLayout, были настолько упрощены, что они нам были нужны. С FormLayout и MigLayout в этом нет необходимости.

3) Вам также необходимо добавить пробелы в макет в блоках диалогов.

Вот пример того, чего, по моему мнению, вы могли бы захотеть достичь:

package com.zetcode.formlayoutex;

import com.jgoodies.forms.factories.CC;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JWindow;

public class FormLayoutEx {

    public static void main(String[] args) {

        JTextField tf = new JTextField(10);

        JFrame frame = new JFrame();
        frame.setLayout(new FormLayout("6dlu, p, 5dlu, p:g, 3dlu", 
                "6dlu, p, 4dlu, p, 4dlu, p, 6dlu"));
        frame.add(new JLabel("Before"), CC.xy(2, 2));
        frame.add(new JTextField("before"), CC.xy(4, 2));
        frame.add(tf, CC.xywh(2, 4, 3, 1));
        frame.add(new JLabel("After"), CC.xy(2, 6));
        frame.add(new JTextField("after"), CC.xy(4, 6));


        frame.pack();
        frame.setTitle("FormLayout example");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        JWindow popup = new JWindow();
        popup.setLayout(new FormLayout("p", "p"));
        JLabel l = new JLabel("popup");
        popup.add(l, CC.xy(1, 1));
        popup.pack();

        tf.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                popup.setVisible(true);
            }
        });
    }
}

Снимок экрана:

введите здесь описание изображения

person Jan Bodnar    schedule 04.09.2016
comment
Привет, спасибо за ответ, но проблема, как я уже упоминал, заключается в том, что в одной строке больше компонентов. Если вы измените свой код таким образом, ошибка все равно появится: frame.add(new JLabel(Middle), CC.xy(2, 4));//новая строка frame.add(tf, CC.xywh(4, 4, 1, 1));//новое ограничение - person Andras; 04.09.2016
comment
Привет, Ян, посмотри на новый скриншот в вопросе после строки: После редактирования кода Яна и трехкратного ввода sowly - person Andras; 05.09.2016