2

現在、BorderLayoutを持つPanel内にネストされたJScrollPaneがあります。さらに重要なことに、JScrollPane内で、JScrollPaneの幅を超えない幅で、必要なだけの高さで(スクロールペインには垂直スクロールバーしかない)、複数のテキスト領域を垂直にリストするつもりです。

私の問題は、テキスト領域が最大のテキスト領域に対してJScrollPaneの中央に配置されているように見え、それらがすべて1行であるということです。

誰かが私のコードを見て、スクロールペインの右側の前にテキスト領域を折り返す方法と、それらを左揃えにする方法を教えてもらえますか?

private JPanel generateStateView(State state) {
        //Create a new panel, and the info label.
        JPanel container = new JPanel(new BorderLayout());
        JLabel infoLabel = new JLabel("The state of " + state.getName() + 
                ", with " + state.getElectoralVotes() + " Electoral Votes.");
        container.add(infoLabel, BorderLayout.NORTH); //Put the label on top.
        //Will scroll through polls.
        JScrollPane pollViewer = new JScrollPane();
        //This will be the scroll pane's "viewport".
        JViewport pollViewport = new JViewport();
        //And finally, this will actually hold the individual polls.
        JPanel pollPanel = new JPanel(new GridLayout(
                state.getPolls().size(), 1));
        pollPanel.setAlignmentX(LEFT_ALIGNMENT);
        //Iteratively add the polls to the container
        for (Poll poll : state.getPolls()) {
            //Holds individual polls
            Box pollBox = Box.createHorizontalBox();
            //Create the poll's panel and add it to the poll container.
            pollBox.add(generatePollPanel(poll));
            pollBox.add(Box.createHorizontalGlue()); //Fill to the right
            pollBox.setAlignmentX(LEFT_ALIGNMENT);
            pollPanel.add(pollBox); //Put the box into the pollPanel.
        }
        //Put the panel into the viewport.
        pollViewport.add(pollPanel);
        //Put the viewport "into" the scroll pane
        pollViewer.setViewport(pollViewport);
        //Put the pane into the state view.
        container.add(pollViewer, BorderLayout.CENTER);
        return container; //And give back the container.
    }

    /**
     * Method: generatePollPanel
     * Purpose: Generates a panel containing information on a particular poll.
     * @param poll The poll to have information generated from.
     * @return The JPanel.
     */
    private JPanel generatePollPanel(Poll poll) {
        //Create a new panel, then a text area to fill with the info.
        JPanel pollPanel = new JPanel();
        JTextArea pollInfo = new JTextArea("Conducted by " + poll.getAgency() + 
                " on day " + poll.getDate() + " for " + poll.getNumDays() + 
                " days, " + poll.getPercentVoteDem() +
                "% voted Democrat, and " + poll.getPercentVoteRep() +
                "% voted Republican.");
        pollInfo.setEditable(false); //We don't want the user editing this.
        pollPanel.add(pollInfo); //Throw the area in, and return the panel.
        pollPanel.setAlignmentX(LEFT_ALIGNMENT);
        return pollPanel;
    }

    /**
     * Method: valueChanged
     * Purpose: Handle the event of a different list item being selected.
     * @param event The object containing information about this event.
     */
    public void valueChanged(ListSelectionEvent event) {
        //Instantiating JList with a type of ? seems to solve the issue of
        //eclipse complaining about an unchecked cast (originally to
        //JList<String>, so I should be able to cast child values directly
        //to string later on anyways.
        JList<?> stateList = (JList<?>) event.getSource();
        //Account for keyboard and mouse actions
        if (!event.getValueIsAdjusting()) {
            State chosenState; //Keep track of the picked state.
            try {
                //Try to get the currently selected state
                chosenState = db.findState((String) stateList.getSelectedValue());
            }
            catch (NoSuchElementException exception) {
                //Somehow the picked state was not found, notify the user.
                reportError("The selected state is not available.");
                return;
            }
            //Find the container for the gui window.
            Container container = getContentPane();
            //Remove the empty state view container by generating a new one.
            container.remove(currentStateView);
            //Generate the state view and add that to the container.
            currentStateView = generateStateView(chosenState);
            container.add(currentStateView, BorderLayout.CENTER);
            //Redraw everything.
            revalidate();
        }
    }
4

2 に答える 2

4

入れ子を失った深刻なケースのように見えます:-)

ネストはレイアウト要件を達成するための手段ですが、意図した出力が得られない場合、正確に何が問題になるのかを見つけるのは難しい場合があります。また、ネスティングに基本的に問題があるという一般的な警告信号があります

  • 非常に多様なマネージャーを持つ深いレベルのコンテナー
  • 子が1つしかないコンテナ

あなたの場合、トップレベルのborderlayoutを除くすべてに、レベルを持つ単一の「netto」(つまり、レイアウトの問題をハックすることを意図していない)の子があります。

BorderLayout (the state view)
   GridLayout (the panel that's the scrollPane's view)
      BoxLayout (the panel that contains a single pollBox)
         FlowLayout (the panel that contains the textArea)

経験した問題:

  • テキスト領域は折り返されることなく1行です
  • テキスト領域は中央に配置されます

どちらも、部分的に(最初)または完全に(2番目)のレイアウトマネージャーの特性によるものです。

  • マネージャが原因ではない部分は、textAreaがデフォルトでラップされないことです。これを行うように、明示的に構成する必要があります。manager(== FlowLayout)が原因の部分は、常に子をprefSizeに従ってレイアウトすることであり、それ以外は何もありません。つまり、親が使用できるスペースの量に関係なく、子のサイズは固定されます。したがって、textAreaが折り返されるように構成されている場合でも、親がどれだけ広くできるかに関係なく、その初期サイズに固執します。
  • 内側のFlowLayoutは、その子を...中央に配置します。したがって、BoxLayoutのレベルで設定した配置は、効果がありません。接着剤ではありません:他の子/子がその次元で最大サイズを持っている場合にのみ余分なスペースをすべて取ります(単純なLayoutManagerには次の概念がないため、FlowLayoutのパネルにはありません)最大、タイプLayoutManager2のマネージャーのみが持っています)

一歩下がって、最初の要件を確認する時間です。

垂直方向にリストされた複数のテキスト領域。幅はJScrollPaneを超えず、高さは必要なだけです。

ゼロ次の解決策は

  • 必要に応じてtextAreaを構成します
  • すべてのレイアウトのネストを破棄します(scrollPane内)

コード内:

JComponent overview = new JPanel(new BorderLayout());
overview.add(new JLabel("All polls for state XY"), BorderLayout.NORTH);

JComponent pollPanel = new JPanel(); 
pollPanel.setLayout(new BoxLayout(pollPanel, BoxLayout.PAGE_AXIS));
for (int i = 0; i < 10; i++) {
    pollPanel.add(generatePollTextArea(i)); //Put the box into the pollPanel.
}
pollPanel.add(Box.createVerticalGlue());
JScrollPane pollViewer = new JScrollPane(pollPanel);
overview.add(pollViewer);
showInFrame(overview, "layout text only");

protected JComponent generatePollTextArea(int i) {
    String agency = "agency ";
    // simulates different size text
    for (int j = 0; j < i; j++) {
        agency += i;
    }
    String text = "Conducted by " + agency + 
            " on day " + "today" + " for " + 20 + 
            " days, " + 99 +
            "% voted Democrat, and " + 0.2 +
            "% voted Republican.";
    JTextArea pollInfo = new JTextArea(text); 
    // give it some reasonable initial width
    // in terms of content
    pollInfo.setColumns(20);
    pollInfo.setLineWrap(true);
    pollInfo.setWrapStyleWord(true);
    pollInfo.setEditable(false); //We don't want the user editing this.
    return pollInfo;
}

「DasWortzumDienstag」:ネストされたレイアウトは、ネストされたレイアウトの個々のレベルで使用されるLayoutManagerの特性を学習することを回避する手段ではありません。

于 2012-09-18T09:28:24.863 に答える
3

Box第一に、それ以外のものと一緒に使用されることはないと思いますBoxLayout(私は間違っている可能性がありますが、それは私がそれを読む方法です)

個人的には、 SwingLabsのいずれかを使用GridBagLayoutします。VerticalLayout

水平方向の制限を容易にするために、特にスクロール可能なインターフェイスも確認する必要がありますgetScrollableTracksViewportWidth

于 2012-09-17T19:56:41.023 に答える