Проблемы с задержкой BorderLayout - PullRequest
1 голос
/ 31 декабря 2010

Через очень долгую пару дней я определил, что при быстром отображении текста в текстовой области возникает задержка, если эта текстовая область находится в макете границы. Мой вопрос заключается в том, почему следующий код выполняется в 10-20 раз дольше при использовании макета границы, чем без него (закомментируйте один из двух методов addWithBorderLayout или addWithoutBorderLayout) И есть ли способ использовать макет границы без этой задержки? (Проблема существует с методом invokeLater () SwingUtilities или без него.)

import java.awt.BorderLayout;
import java.awt.Label;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JDesktopPane;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;


public class Driver
{
    public static void main(String args[])
    {
        System.out.println("JEditPane Test");

        //window to display the plyed back text
        JFrame mainFrame = new JFrame("Main Frame");

        //holds some text to be played back
        final JEditorPane editPane1 = new JEditorPane(); 
        final JEditorPane editPane2 = new JEditorPane(); 

        //desktop pane to hold docs
        JDesktopPane desktopPane = new JDesktopPane();

        //create an internal frame
        JInternalFrame internalFrame1 = new JInternalFrame("Test Doc 1", true, true, true, true);
        internalFrame1.setContentPane(new JScrollPane(editPane1));
        internalFrame1.setSize(400, 400);
        internalFrame1.setVisible(true);
        internalFrame1.setLocation(0, 0);

        JInternalFrame internalFrame2 = new JInternalFrame("Test Doc 2", true, true, true, true);
        internalFrame2.setContentPane(new JScrollPane(editPane2));
        internalFrame2.setSize(400, 400);
        internalFrame2.setVisible(true);
        internalFrame2.setLocation(400, 0);

        //add it to the desktop
        desktopPane.add(internalFrame1);
        desktopPane.add(internalFrame2);

        //map of editor panes
        final Map < String, JEditorPane > mapOfPanes = new HashMap < String, JEditorPane >();
        mapOfPanes.put("1", editPane1);
        mapOfPanes.put("2", editPane2);

        //COMMENT ONE OF THESE TWO OUT!!!
        addWithBorderLayout(mainFrame, desktopPane);
        //addWithoutBorderLayout(mainFrame, desktopPane);

        //for closing
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //set the size and location of the window
        mainFrame.setSize(800,500);
        mainFrame.setLocation(100, 100);

        //make the window visible
        mainFrame.setVisible(true);


        //create some text to display
        StringBuilder builder = new StringBuilder();
        builder.append("This is a rather long string of text. ");

        //build up a good amount of text
        for(int i = 0;i < 5;i++)
        {
            //copy it a few times
            builder.append(builder.toString());
        }

        //get the string
        final String longStringOfText = builder.toString();

        //create a thread to call setText on the editor pane
        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                //for gathering stats
                int sum = 0;
                int numberOfCharsToPrintFromString = 0;
                Date prev = new Date();
                Date current = new Date();

                System.out.println("Num Panes: " + mapOfPanes.size());

                //for each pane
                for(JEditorPane pane : mapOfPanes.values())
                {
                    //to help in printing subsections of the big string
                    numberOfCharsToPrintFromString = 0;

                    while(numberOfCharsToPrintFromString < longStringOfText.length())
                    {
                        //wait a short amount of time
                        try{Thread.sleep(1);}catch(Exception e){}

                        //grab sections of the long string
                        String text = longStringOfText.substring(0, numberOfCharsToPrintFromString);

                        //set the text of the pane
                        pane.setText(text);

                        //stats
                        numberOfCharsToPrintFromString++;
                        long diff = current.getTime() - prev.getTime();
                        sum = sum + (int)diff;
                        prev = current;
                        current = new Date();
                    }               
                }

                System.out.println("Average time in between events: " + ((double)sum/(double)numberOfCharsToPrintFromString));                  
            }
        });

        thread.start();
    }

    private static void addWithoutBorderLayout(JFrame mainFrame, JDesktopPane desktopPane)
    {
        mainFrame.add(desktopPane);
    }

    private static void addWithBorderLayout(JFrame mainFrame, JDesktopPane desktopPane)
    {
        mainFrame.setLayout(new BorderLayout());
        mainFrame.add(new Label("Top Panel"), BorderLayout.NORTH);
        mainFrame.add(desktopPane, BorderLayout.CENTER);
        mainFrame.add(new Label("Bottom Panel"), BorderLayout.SOUTH);       
    }
}

Ответы [ 2 ]

1 голос
/ 31 декабря 2010

В Mac OS X 10.5.8, использующей Java версии 1.6, я вижу сопоставимое несоответствие, если я не установлю apple.awt.graphics.UseQuartz в начале main().Вот связанный пример , который влияет на качество рендеринга шрифта, а не на время выполнения.

if (System.getProperty("os.name").startsWith("Mac OS X")) {
    System.setProperty("apple.awt.graphics.UseQuartz", "true");
}
0 голосов
/ 31 декабря 2010

Я использую JDK6_17 в XP со старым компьютером и не замечаю разницу, которую вы испытываете. Мои сроки между 20-22 в обоих случаях.

Затем я изменил время сна на 10 мс, и время было поразительно похожим.

Для макета по умолчанию:

Среднее время между событиями: 31.236842105263158
Среднее время между событиями: 31.236842105263158
Среднее время между событиями: 31.236842105263158

Для макета границы:

Среднее время между событиями: 31.236842105263158
Среднее время между событиями: 31.23766447368421
Среднее время между событиями: 31.236842105263158

На самом деле я не могу поверить, что они идентичны в 5 из 6 случаев.

По умолчанию панель содержимого JFrame использует BorderLayout. Поэтому, когда вы добавляете компоненты к фрейму, все, что вам нужно сделать, это:

frame.add(topComponent, BorderLayout.NORTH);
frame.add(centerComponent);
frame.add(bottomComponent, BorderLayout.SOUTH);

и рамка добавит компоненты в панель содержимого в нужном месте.

Почему вы изменяете макет фрейма вместо панели содержимого. Обычно вы бы изменили только макет панели содержимого. Корневая панель фрейма используется для хранения строки меню и панели содержимого. Так, может быть, вы измените менеджер макета по умолчанию для всего кадра, который вызывает некоторые проблемы?

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