TextField в области прокрутки не отображается правильно - PullRequest
0 голосов
/ 17 января 2019

У меня проблема с отображением нескольких TextFields внутри ScrollPane, если я прокручиваю его вниз. Но, тем не менее, если я сам изменю размер окна, недостающие TextFields будут отображены. Я пробовал несколько способов рендеринга отсутствующих TextFields, но я не мог заставить его работать. Окно

Это класс Window, который я создаю при запуске программы:

public class Window {

    private JFrame frame;
    private JScrollPane scrollPane;
    private Model model;

    public Window() {
        new Thread() {
            {
                setName("Window Thread");
            }
            public void run() {
                initialize();
            }
        }.start();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 1200, 600);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setResizable(false);
        frame.setLayout(null);

        scrollPane = new JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setSize(frame.getWidth() - 10, frame.getHeight() - 30);
        frame.add(scrollPane);
        model = new ChatModel(frame.getWidth() - 10);
        scrollPane.setViewportView(model);
        frame.setVisible(true);
    }

    public void add(Data d) {
        while (model == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        model.add(d);
    }
}

Это панель, которая добавляет панели с текстовыми полями, на которых я пишу:

public class Model extends Panel {

    private ArrayList < Line > lines = new ArrayList < Line > ();
    private final int width;

    public Model(int width) {
        this.width = width;
        setLayout(null);
        setBounds(getX(), getY(), width, 5 * 30);
        setBackground(Color.RED);
    }

    public void add(Data d) {
        synchronized(getTreeLock()) {
            Line cl = new Line(d.txt, width);
            lines.add(cl);
            cl.setBounds(0, lines.size() * 30, width, 30);
            add(cl);
            setSize(width, (lines.size() + 1) * 30);
        }
    }

    private class Line extends Panel {
        TextField txt;

        public ChatLine(String data, int width) {
            setLayout(null);
            txt = new TextField(textUserS);
            txt.setBounds(0, 0, width, 30);
            add(txt);
            setBackground(Color.BLUE);
        }
    }
}

1 Ответ

0 голосов
/ 17 января 2019

Не используйте компоненты AWT в приложении Swing.

Компоненты Swing начинаются с "J" (JTextField, JPanel и т. Д.).

Не используйте пустой макет. Swing был разработан для использования с менеджерами верстки. Во-первых, панель прокрутки не будет работать должным образом, если панель, добавленная в область просмотра, не использует менеджер раскладки.

При динамическом добавлении компонентов на панель базовая логика выглядит следующим образом:

panel.add(...);
panel.revalidate();
panel.repaint();

Нет необходимости в синхронизированном блоке. Компоненты Swing должны быть обновлены с Event Dispatch Thread (EDT). Если ваш код не выполняется на EDT, вам нужно использовать SwingUtilities.invokeLater(...), чтобы поместить код на EDT. Прочитайте раздел из учебника по Swing на Параллелизм для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...