1

这个问题Java Swing: Vertical Layout with fixed width and variable height让我有机会尝试 Apache Pivot。我对 Pivot 有一天的经验。

这是我能够创建的 GUI。

段图形用户界面

我的问题是:

  1. 如何调整, 和TextArea, 的一部分的大小Expander,以使Expander,ScrollPaneTextArea填充窗口的宽度,并且TextArea足够高以容纳任意数量的文本?

  2. 如何调整 s 的高度ScrollPaneExpander以便在所有文本区域都展开时, 3 Expanders 适合窗口的高度?

这是创建 GUI 的源代码。我正在使用 2.0.2 版的 Apache Pivot。

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.pivot.collections.Map;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.BoxPane;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.Expander;
import org.apache.pivot.wtk.Orientation;
import org.apache.pivot.wtk.ScrollPane;
import org.apache.pivot.wtk.TextArea;
import org.apache.pivot.wtk.Window;

public class Segments implements Application {

    protected SectionCollection collection;

    protected Window window;

    @Override
    public void startup(Display display, Map<String, String> properties) {
        collection = new SectionCollection();
        new SectionCollectionCreator(collection);

        window = new Window();
        window.setTitle("Segments");
        window.setMaximized(true);

        BoxPane boxPane = new BoxPane();
        boxPane.setOrientation(Orientation.VERTICAL);

        for (int i = 0; i < collection.size(); i++) {
            SectionText sectionText = collection.get(i);

            TextArea textArea = new TextArea();
            textArea.setEditable(false);
            textArea.setPreferredSize(400, 220);
            try {
                textArea.setText(sectionText.getTopic());
            } catch (IOException e) {
                e.printStackTrace();
            }

            ScrollPane textScrollPane = new ScrollPane();
            textScrollPane.setPreferredSize(420, 100);
            textScrollPane.setVerticalScrollBarPolicy(
                    ScrollPane.ScrollBarPolicy.AUTO);
            textScrollPane.setView(textArea);

            Expander expander = new Expander();
            expander.setTitle(sectionText.getTitle());
            expander.setContent(textScrollPane);
            expander.setExpanded(false);

            boxPane.add(expander);  
        }

        ScrollPane expanderScrollPane = new ScrollPane();
        expanderScrollPane.setHorizontalScrollBarPolicy(
                ScrollPane.ScrollBarPolicy.AUTO);
        expanderScrollPane.setVerticalScrollBarPolicy(
                ScrollPane.ScrollBarPolicy.AUTO);
        expanderScrollPane.setView(boxPane);

        window.setContent(expanderScrollPane);
        window.open(display);
    }

    @Override
    public boolean shutdown(boolean optional) {
        if (window != null) {
            window.close();
        }
        return false;
    }

    @Override
    public void suspend() {
    }

    @Override
    public void resume() {
    }

    public static void main(String[] args) {
        DesktopApplicationContext.main(Segments.class, args);
    }

    public class SectionText {
        protected String title;
        protected Reader topic;

        public SectionText(String title, Reader topic) {
            this.title = title;
            this.topic = topic;
        }

        public String getTitle() {
            return title;
        }

        public Reader getTopic() {
            return topic;
        }
    }

    public class SectionCollection {
        protected List<SectionText> collection;

        public SectionCollection() {
            this.collection = new ArrayList<SectionText>();
        }

        public void add(SectionText sectionText) {
            collection.add(sectionText);
        }

        public int size() {
            return collection.size();
        }

        public SectionText get(int index) {
            return collection.get(index);
        }
    }   

    public class SectionCollectionCreator {
        protected SectionCollection collection;

        protected static final String text = "Attributes, Styles and Style Contexts\n\n"
                + "The simple PlainDocument class that you saw in the previous "
                + "chapter is only capable of holding text. The more complex text "
                + "components use a more sophisticated model that implements the "
                + "StyledDocument interface. StyledDocument is a sub-interface of "
                + "Document that contains methods for manipulating attributes that "
                + "control the way in which the text in the document is displayed. "
                + "The Swing text package contains a concrete implementation of "
                + "StyledDocument called DefaultStyledDocument that is used as the "
                + "default model for JTextPane and is also the base class from which "
                + "more specific models, such as the HTMLDocument class that handles "
                + "input in HTML format, can be created. In order to make use of "
                + "DefaultStyledDocument and JTextPane, you need to understand how "
                + "Swing represents and uses attributes.";

        public SectionCollectionCreator(SectionCollection collection) {
            this.collection = collection;

            String title = "Title ";

            for (int i = 1; i <= 3; i++) {
                SectionText sectionText = new SectionText(title + i, 
                        new StringReader(text));
                collection.add(sectionText);
            }
        }   
    }

}
4

2 回答 2

0

我终于解决了这个难题。

通过设置文本区域的宽度,计算出适合文本的高度。

通过设置文本区域滚动窗格的高度,我可以使文本区域滚动窗格出现,并将扩展器的大小减小到标题栏加上文本区域滚动窗格。

所以现在,我所要做的就是根据窗口的宽度和高度计算出文本区域的宽度和文本区域滚动窗格的高度。

这就是组件侦听器发挥作用的地方。侦听器调整了文本区域的宽度和文本区域滚动窗格的高度。我作弊并使用魔法常数来解释滚动条和边距。如果我能在创建组件时获得这些值,那就太好了。

无论如何,这里的代码将 GUI 组件的大小调整为窗口。

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.pivot.collections.Map;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.Bounds;
import org.apache.pivot.wtk.BoxPane;
import org.apache.pivot.wtk.Component;
import org.apache.pivot.wtk.Component.StyleDictionary;
import org.apache.pivot.wtk.ComponentListener;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.Expander;
import org.apache.pivot.wtk.Orientation;
import org.apache.pivot.wtk.ScrollPane;
import org.apache.pivot.wtk.TextArea;
import org.apache.pivot.wtk.Window;

public class Segments implements Application {

    protected List<SectionComponent> expanderComponents;

    protected SectionCollection collection;

    protected Window window;

    @Override
    public void startup(Display display, Map<String, String> properties) 
            throws IOException {
        getStyles(display);

        collection = new SectionCollection();
        new SectionCollectionCreator(collection);
        expanderComponents = new ArrayList<SectionComponent>();

        window = new Window();
        window.setTitle("Segments");
        window.setMaximized(true);

        ComponentSizeListener listener = new ComponentSizeListener();   
        window.getComponentListeners().add(listener.getListener());

        BoxPane boxPane = new BoxPane();
        boxPane.setOrientation(Orientation.VERTICAL);

        for (int i = 0; i < collection.size(); i++) {
            SectionComponent sectionComponent =
                    new SectionComponent(collection.get(i), 400, 100); 
            expanderComponents.add(sectionComponent);
            boxPane.add(sectionComponent.getExpander());
        }

        listener.setComponents(expanderComponents);

        ScrollPane expanderScrollPane = new ScrollPane();
        expanderScrollPane.setHorizontalScrollBarPolicy(
                ScrollPane.ScrollBarPolicy.AUTO);
        expanderScrollPane.setVerticalScrollBarPolicy(
                ScrollPane.ScrollBarPolicy.AUTO);
        expanderScrollPane.setView(boxPane);

        window.setContent(expanderScrollPane);
        window.open(display);
    }

    protected void getStyles(Component component) {
        StyleDictionary dictionary = component.getStyles();
        System.out.println(component);
        Iterator<String> iter = dictionary.iterator();
        List<String> list = new ArrayList<String>();
        while (iter.hasNext()) {
            list.add(iter.next());
        }
        Collections.sort(list);
        for (String style : list) {
            System.out.println("    " + style);
        }
    }

    @Override
    public boolean shutdown(boolean optional) {
        if (window != null) {
            window.close();
        }
        return false;
    }

    @Override
    public void suspend() {
        Bounds bounds = window.getClientArea();
        System.out.println(bounds);
    }

    @Override
    public void resume() {
    }

    public static void main(String[] args) {
        DesktopApplicationContext.main(Segments.class, args);
    }

    public class ComponentSizeListener {
        protected int newWidth;
        protected int newHeight;

        protected ComponentListener listener;

        protected List<SectionComponent> components;

        public ComponentSizeListener() {
            this.newWidth = 425;
            this.newHeight = 131;

            this.listener = new ComponentListener.Adapter() {
                @Override
                public void sizeChanged(Component component, 
                        int previousWidth, int previousHeight) {
                    newWidth = component.getWidth();
                    newHeight = component.getHeight();
                    for (SectionComponent sectionComponent : components) {
                        sectionComponent.setTextAreaWidth(newWidth - 25);
                        int paneHeight = (newHeight / components.size()) - 34;
                        sectionComponent.setTextScrollPaneHeight(paneHeight);
                    }
                }
            };
        }

        public void setComponents(List<SectionComponent> components) {
            this.components = components;
        }

        public ComponentListener getListener() {
            return listener;
        }
    }

    public class SectionComponent {
        protected int textAreaWidth;
        protected int textScrollPaneHeight;

        protected Expander expander;
        protected ScrollPane textScrollPane;
        protected SectionText sectionText;
        protected TextArea textArea;

        public SectionComponent(SectionText sectionText, 
                int textAreaWidth, int textScrollPaneHeight) 
                        throws IOException {
            this.sectionText = sectionText;
            this.textAreaWidth = textAreaWidth;
            this.textScrollPaneHeight = textScrollPaneHeight;
            createPartControl();
        }

        protected void createPartControl() throws IOException {
            textArea = new TextArea();
            textArea.setEditable(false);
            textArea.setPreferredWidth(textAreaWidth);
            textArea.setText(sectionText.getTopic());

            textScrollPane = new ScrollPane();
            textScrollPane.setPreferredHeight(textScrollPaneHeight);
            textScrollPane.setVerticalScrollBarPolicy(
                    ScrollPane.ScrollBarPolicy.AUTO);
            textScrollPane.setView(textArea);

            expander = new Expander();
            expander.setTitle(sectionText.getTitle());
            expander.setContent(textScrollPane);
            expander.setExpanded(false);
        }

        public Expander getExpander() {
            return expander;
        }

        public void setTextAreaWidth(int textAreaWidth) {
            this.textAreaWidth = textAreaWidth;
            textArea.setPreferredWidth(textAreaWidth);
        }

        public void setTextScrollPaneHeight(int textScrollPaneHeight) {
            this.textScrollPaneHeight = textScrollPaneHeight;
            textScrollPane.setPreferredHeight(textScrollPaneHeight);
        }

    }

    public class SectionText {
        protected String title;
        protected Reader topic;

        public SectionText(String title, Reader topic) {
            this.title = title;
            this.topic = topic;
        }

        public String getTitle() {
            return title;
        }

        public Reader getTopic() {
            return topic;
        }
    }

    public class SectionCollection {
        protected List<SectionText> collection;

        public SectionCollection() {
            this.collection = new ArrayList<SectionText>();
        }

        public void add(SectionText sectionText) {
            collection.add(sectionText);
        }

        public int size() {
            return collection.size();
        }

        public SectionText get(int index) {
            return collection.get(index);
        }
    }   

    public class SectionCollectionCreator {
        protected SectionCollection collection;

        protected static final String text = "Attributes, Styles and Style Contexts\n\n"
                + "The simple PlainDocument class that you saw in the previous "
                + "chapter is only capable of holding text. The more complex text "
                + "components use a more sophisticated model that implements the "
                + "StyledDocument interface. StyledDocument is a sub-interface of "
                + "Document that contains methods for manipulating attributes that "
                + "control the way in which the text in the document is displayed. "
                + "The Swing text package contains a concrete implementation of "
                + "StyledDocument called DefaultStyledDocument that is used as the "
                + "default model for JTextPane and is also the base class from which "
                + "more specific models, such as the HTMLDocument class that handles "
                + "input in HTML format, can be created. In order to make use of "
                + "DefaultStyledDocument and JTextPane, you need to understand how "
                + "Swing represents and uses attributes.";

        public SectionCollectionCreator(SectionCollection collection) {
            this.collection = collection;

            String title = "Title ";

            for (int i = 1; i <= 3; i++) {
                SectionText sectionText = new SectionText(title + i, 
                        new StringReader(text));
                collection.add(sectionText);
            }
        }   
    }

}
于 2012-11-27T16:04:00.227 回答
0

您可能还需要考虑将组件放在 FillPane 中,这会使它们的大小调整为填充可用区域。这似乎是 Pivot 的做事方式。

于 2013-03-09T21:32:24.607 回答