使用带有lanterna的GridLayout的ArrayIndexOutOfBoundsException

时间:2018-01-14 20:46:08

标签: java grid lanterna

我正在体验lanterna's 4th tutorial。当我创建一个包含2列的GridLayout并添加2个标签时,每个标签跨越2列,程序运行时没有错误。但是当我创建一个包含4列的GridLayout并添加2个跨越4列的标签时,我得到以下ArrayIndexOutOfBoundsException运行时错误。

[rmcgregor@cs lanterna]$ make 4
java -cp .:lanterna-3.0.0.jar GUIApp

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at com.googlecode.lanterna.gui2.GridLayout.getPreferredColumnWidths(GridLayout.java:542)
    at com.googlecode.lanterna.gui2.GridLayout.getPreferredSize(GridLayout.java:387)
    at com.googlecode.lanterna.gui2.Panel$1.getPreferredSize(Panel.java:187)
    at com.googlecode.lanterna.gui2.Panel$1.getPreferredSize(Panel.java:182)
    at com.googlecode.lanterna.gui2.AbstractComponent.calculatePreferredSize(AbstractComponent.java:194)
    at com.googlecode.lanterna.gui2.Panel.calculatePreferredSize(Panel.java:217)
    at com.googlecode.lanterna.gui2.AbstractComponent.getPreferredSize(AbstractComponent.java:178)
    at com.googlecode.lanterna.gui2.AbstractBasePane$ContentHolder$1.getPreferredSize(AbstractBasePane.java:331)
    at com.googlecode.lanterna.gui2.AbstractBasePane$ContentHolder$1.getPreferredSize(AbstractBasePane.java:324)
    at com.googlecode.lanterna.gui2.AbstractComponent.calculatePreferredSize(AbstractComponent.java:194)
    at com.googlecode.lanterna.gui2.AbstractComponent.getPreferredSize(AbstractComponent.java:178)
    at com.googlecode.lanterna.gui2.AbstractWindow.getPreferredSize(AbstractWindow.java:161)
    at com.googlecode.lanterna.gui2.DefaultWindowManager.onAdded(DefaultWindowManager.java:103)
    at com.googlecode.lanterna.gui2.MultiWindowTextGUI.addWindow(MultiWindowTextGUI.java:356)
    at com.googlecode.lanterna.gui2.MultiWindowTextGUI.addWindowAndWait(MultiWindowTextGUI.java:369)
    at GUIApp.main(GUIApp.java:50)

这是源代码。

import java.io.IOException;

import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
import com.googlecode.lanterna.screen.Screen;
import com.googlecode.lanterna.gui2.*;

class GUIApp {
    public static void main(String[] args) {

        DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory();
        Screen screen = null;

        try {
            screen = terminalFactory.createScreen();
            screen.startScreen();

            final WindowBasedTextGUI textGUI = new MultiWindowTextGUI(screen);
            final Window window = new BasicWindow();

            Panel contentPanel = new Panel(new GridLayout(4));

            GridLayout gridLayout = (GridLayout)contentPanel.getLayoutManager();
            gridLayout.setHorizontalSpacing(3);

            Label title = new Label("This is a label that spans two columns");
            title.setLayoutData(GridLayout.createLayoutData(
                GridLayout.Alignment.BEGINNING,
                GridLayout.Alignment.BEGINNING,
                true,
                false,
                4,
                1));
            contentPanel.addComponent(title);

            Label alignedText = new Label("Text Box (aligned)");
            alignedText.setLayoutData(GridLayout.createLayoutData(
                GridLayout.Alignment.BEGINNING,
                GridLayout.Alignment.BEGINNING,
                true,
                false,
                4,
                1));
            contentPanel.addComponent(alignedText);

            //Label moreText = new Label("more text");
            //contentPanel.addComponent(moreText);

            window.setComponent(contentPanel);
            textGUI.addWindowAndWait(window);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if(screen != null) {
                try {
                    screen.stopScreen();
                }
                catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

任何帮助解释我在概念上的误解都会很棒!

1 个答案:

答案 0 :(得分:0)

我一直在做一些测试,并认为我在GridLayout中发现了一个错误。我在reportedlanterna google groups forum了。

您似乎无法向第一行添加跨越多个列的Button或Label。它们可以包含在第一行之后的任何行中。有趣的是,您可以添加到跨越多列的第一行EmptySpace。

以下是我的测试用例。希望他们帮助理解这个问题。

    private static class GUIAppWindow extends BasicWindow {
            GUIAppWindow() { 

                    Panel contentPanel = new Panel(new GridLayout(4)); 
                    GridLayout gridLayout = (GridLayout)contentPanel.getLayoutManager(); 
                    gridLayout.setHorizontalSpacing(3);

                    // Valid First Row ***************************************************** 
                    contentPanel.addComponent(new Label("AAAAA")); 
                    contentPanel.addComponent(new Label("BBBBB")); 
                    contentPanel.addComponent(new Label("DDDDD")); 
                    contentPanel.addComponent(new Label("EEEEE")); 

                    // Valid First Row ***************************************************** 
                    contentPanel.addComponent( 
                            new EmptySpace() 
                                    .setLayoutData( 
                                            GridLayout.createHorizontallyFilledLayoutData(3))); 
                    contentPanel.addComponent(new Label("HHHHH")); 

                    // Valid First Row ***************************************************** 
                    contentPanel.addComponent(new Label("HHHHH")); 
                    contentPanel.addComponent( 
                            new EmptySpace() 
                                    .setLayoutData( 
                                            GridLayout.createHorizontallyFilledLayoutData(2))); 
                    contentPanel.addComponent(new Label("IIIII")); 

                    // Valid First Row ***************************************************** 
                    contentPanel.addComponent(new Label("BBBBB")); 
                    contentPanel.addComponent(new Label("DDDDD")); 
                    contentPanel.addComponent(new Label("EEEEE")); 
                    contentPanel.addComponent(new Button("Exit", new Runnable() { 
                            @Override 
                            public void run() { 
                                    GUIAppWindow.this.close(); 
                            } 
                    })); 

                    // Invalid First Row ***************************************************** 
                    contentPanel.addComponent(new Label("KKKKK")); 
                    contentPanel.addComponent(new Label("LLLLL")); 
                    contentPanel.addComponent( 
                            new Button("Close", new Runnable() { 
                                    @Override 
                                    public void run() { 
                                            GUIAppWindow.this.close(); 
                                    } 
                    }), GridLayout.createHorizontallyEndAlignedLayoutData(2)); 

                    // Invalid First Row ***************************************************** 
                    contentPanel.addComponent( 
                            new EmptySpace() 
                                    .setLayoutData( 
                                            GridLayout.createHorizontallyFilledLayoutData(2))); 
                    contentPanel.addComponent(new Label("CCCCC"), GridLayout.createLayoutData( 
                            GridLayout.Alignment.CENTER, 
                            GridLayout.Alignment.BEGINNING, 
                            false, 
                            false, 
                            2, 
                            1)); 

                    // Invalid First Row ***************************************************** 
                    contentPanel.addComponent(new Label("FFFFF"), GridLayout.createLayoutData( 
                            GridLayout.Alignment.CENTER, 
                            GridLayout.Alignment.BEGINNING, 
                            true, 
                            false, 
                            4, 
                            1)); 

                    // Invalid First Row ***************************************************** 
                    contentPanel.addComponent(new Label("DDDDD")); 
                    contentPanel.addComponent(new Label("EEEEE")); 
                    contentPanel.addComponent(new Label("FFFFF"), GridLayout.createLayoutData( 
                            GridLayout.Alignment.CENTER, 
                            GridLayout.Alignment.BEGINNING, 
                            true, 
                            false, 
                            2, 
                            1)); 

                    this.setComponent(contentPanel); 
            } 
    }