【问题标题】:BorderLayout delay issuesBorderLayout 延迟问题
【发布时间】:2011-01-01 04:32:50
【问题描述】:

经过很长的几天后,我确定如果文本区域处于边框布局中,则在文本区域中非常快速地显示文本时会出现延迟。我的问题是,为什么使用边框布局执行以下代码的时间比不使用边框布局要长 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);       
    }
}

【问题讨论】:

    标签: java user-interface swing


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    我在 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);
    

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

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

    【讨论】:

    • 我在 macbook pro 上运行 java.vm.version=17.1-b03-307。使用边框布局,最后三个运行时间是: 60.92516447368421 62.32072368421053 63.99259868421053 没有: 4.652960526315789 4.579769736842105 4.451480263157895 IFrame 并获得了相同的布局管理器结果。
    猜你喜欢
    • 2011-01-14
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 2018-07-19
    相关资源
    最近更新 更多