Повторная верстка самой программы Java Swing - PullRequest
2 голосов
/ 17 июля 2009

У меня всегда возникают проблемы с макетами Java, но главное, что меня сейчас беспокоит, это то, что при изменении содержимого, в частности, при изменении его размеров, оно не выкладывается должным образом. Возьмите пример ниже:

package layouttest;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class LayoutTestStart extends JFrame implements ActionListener
{
    static JButton button= new JButton("Expand");
    static JTextArea f = new JTextArea("A medium sized text");
    static LayoutTestStart lst;

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI()
    {
         lst  = new LayoutTestStart();
        lst.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel all = new JPanel();

        button.addActionListener(lst);

        all.add(button);
        all.add(f);
        lst.getContentPane().add(all);

        lst.setVisible(true);
        lst.pack();
    }
    @Override
    public void actionPerformed(ActionEvent e)
    {
        f.setText(f.getText()+"\n"+f.getText());

        // this doesn't work
        f.invalidate();

        // this does but it's cheating
//      lst.pack();
    }
}

Единственный способ заставить это работать - это вызвать lst.pack (), но это обман, так как каждый компонент должен иметь ссылку на свой JFrame, который запутывается, когда компонент является отдельным классом. Какой способ работы этого примера предпочтителен?

Ответы [ 5 ]

3 голосов
/ 17 июля 2009

revalidate вместо invalidate. invalidate просто помечает контейнер как необходимый макет. revalidate делает это и затем планирует validate.

Кстати: я предлагаю: избегать расширения от JFrame и других компонентов; избежать множественного наследования интерфейса и избежать (изменяемой) статики.

2 голосов
/ 18 июля 2009

Ну, как правило, пользователям не нравится, когда размер фрейма меняется каждый раз, когда они нажимают ввод. Рама должна быть рассчитана на рост. Таким образом, вы должны определить текстовую область, чтобы иметь заданное количество строк и столбцов. Затем вы добавляете текстовую область в область прокрутки и добавляете область прокрутки в рамку. Затем при изменении данных полосы прокрутки будут появляться или исчезать по мере необходимости.

Однако если вам действительно нужен динамически изменяемый фрейм, вам следует использовать pack (). Вы можете использовать:

SwingUtilities.windowForComponent(...) 

где Компонент является исходным компонентом ActionEvent, чтобы найти Окно для упаковки ().

0 голосов
/ 25 января 2010

Аннулирование или проверка только на JTextArea не работает, вы должны изменить размер верхнего кадра, так как он не обновляет его размер автоматически Например, вы можете сделать это так (немного изменив код, чтобы удалить статические переменные):

package layouttest;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;    

public class LayoutTestStart extends JFrame implements ActionListener{

private JTextArea f = new JTextArea("A medium sized text");

public LayoutTestStart(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel all = new JPanel();
    JButton button = new JButton("Expand");
    button.addActionListener(this);

    all.add(button);
    all.add(f);
    getContentPane().add(all);
}

@Override
public void actionPerformed(ActionEvent e){
    javax.swing.SwingUtilities.invokeLater(new Runnable(){           
        @Override
        public void run(){
            f.setText(f.getText() + "\n" + f.getText());
            setSize(getPreferredSize());                
        }
    });

}

public static void main(String[] args){
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            LayoutTestStart lst = new LayoutTestStart();
            lst.setVisible(true);
            lst.pack();
        }
    });
}
}
0 голосов
/ 17 июля 2009

updateUI(); никогда не подведет!

0 голосов
/ 17 июля 2009

Во-первых, что касается вашего предположения, вы можете вызвать пакет, получив ответчик верхнего уровня (такой компонент есть в компонентах) и разработав пакет вызова. Вы можете создать статический метод и вызывать его везде, где это необходимо. Это будет работать.

Другой вариант (возможно, действительно предпочтительный вариант) заключается в использовании менеджера компоновки, который учитывает это. GridBagLayout, конечно, делает все это, но есть те, кто утверждает, что он не предназначен для использования смертными. MigLayout - менеджер компоновки с открытым исходным кодом, который немного более вменяемый.

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