BorderLayout延迟问题

时间:2010-12-31 17:29:53

标签: java user-interface swing

经过很长一段时间后,我确定如果文本区域位于边框布局中,则在文本区域中快速显示文本会有延迟。我的问题是,为什么下面的代码使用边框布局比没有使用边框布局长10-20倍(注释掉两个方法之一addWithBorderLayout或addWithoutBorderLayout)并且有没有办法在没有这种延迟的情况下使用边框布局? (无论是否使用SwingUtilities invokeLater()方法都存在问题。)

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 个答案:

答案 0 :(得分:1)

在使用Java 1.6版的Mac OS X 10.5.8上,除非我在apple.awt.graphics.UseQuartz的开头设置main(),否则我会看到相似的差异。这是一个相关的example,它影响字体渲染质量而不是执行时间。

if (System.getProperty("os.name").startsWith("Mac OS X")) {
    System.setProperty("apple.awt.graphics.UseQuartz", "true");
}

答案 1 :(得分:0)

我在XP上使用旧版计算机上的JDK6_17,并没有注意到您遇到的差异。我的时间在两种情况下都在20-22之间。

然后我将睡眠时间改为10毫秒,时间非常相似。

对于默认布局:

活动间的平均时间:31.236842105263158
活动期间的平均时间:31.236842105263158
活动期间的平均时间:31.236842105263158

对于边框布局:

活动间的平均时间:31.236842105263158
活动期间的平均时间:31.23766447368421
活动期间的平均时间:31.236842105263158

事实上,我无法相信它们在6个案例中有5个是相同的。

默认情况下,JFrame的内容窗格确实使用BorderLayout。因此,当您向框架添加组件时,您只需要执行以下操作:

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

,框架会将组件添加到适当位置的内容窗格中。

为什么要更改框架的布局,而不是内容窗格。通常,您只需更改内容窗格的布局。框架的根窗格用于保存菜单栏和内容窗格。那么也许您更改整个帧的默认布局管理器会导致一些问题?