简体   繁体   中英

Set minimum width in side panel of Swing BorderLayout

I understand some parts of BorderLayout -- eg, the EAST/WEST (or BEGINNING_OF_LINE/END_OF_LINE) panel component stays one width and its length is stretched with the length of the window.

I want to put a panel on the WEST side that itself has multiple components - a panel of buttons and a JList of things the buttons control, in this case. I would like to allocate a minimum width for the strings in that JList, but something (probably BorderLayout) prevents me from setting a minimum or preferred width.

When I run the code below, the list in the left panel is wide enough for "LongNameGame 3", but only because I added the string before rendering the list. I would like to set the width of that JList to accommodate strings of the width of my choice. Later I'll put it in a ScrollPane for strings wider than that, but that's a different problem.

My question is not answered by referring me to other layout managers -- I want to know how to do this with BorderLayout, if possible.

package comm;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;

public class BLPlay
{
  public static void main(String ... arguments)
  {
    JFrame frame = buildLoungeFrame();
    frame.setVisible(true);
  }
  private static JFrame buildLoungeFrame()
  {
    JFrame loungeFrame = new JFrame("BLPlay");
    loungeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    loungeFrame.setLayout(new BorderLayout(10,10));

    // left panel is another BorderLayout panel with buttons and a list of games
    JPanel gameListControlPanel = new JPanel(new BorderLayout());

    Border innerBorder = BorderFactory.createLineBorder(Color.BLACK, 2);
    Border outerBorder = BorderFactory.createEmptyBorder(3,3,3,3);
    gameListControlPanel.setBorder(BorderFactory.createCompoundBorder(outerBorder, innerBorder));

    String[] gamePanelButtonLabels = { "New", "Join", "Leave", "End" };
    JPanel gamePanelButtons = new JPanel(new GridLayout(gamePanelButtonLabels.length,1));
    addButtons(gamePanelButtons, gamePanelButtonLabels);
    JPanel gamePanelButtonsContainerPanel = new JPanel();
    gamePanelButtonsContainerPanel.add(gamePanelButtons);
    gameListControlPanel.add(gamePanelButtonsContainerPanel, BorderLayout.WEST);

    Vector<String> gameList = new Vector<>();
    gameList.add("Game 1");
    gameList.add("Game 2");
    gameList.add("LongNameGame 3");

    JList<String> gameJList = new JList<>(gameList);
    JPanel gameListPanel = new JPanel(new FlowLayout());
    gameListPanel.setMinimumSize(new Dimension(600,600));   // <-- has no effect
    gameListPanel.add(gameJList);
    gameListControlPanel.add(gameListPanel, BorderLayout.EAST);

    loungeFrame.add(gameListControlPanel, BorderLayout.WEST);

    // center panel in the lounge is for chat messages; it has a separate border layout,
    // center for accumulated messages, bottom for entering messages
    JPanel chatMessagePanel = new JPanel(new BorderLayout());
//    Border chatMessagePanelBorder = BorderFactory.createEmptyBorder(7,7,7,7);
//    chatMessagePanel.setBorder(chatMessagePanelBorder);

    JTextArea chatMessages = new JTextArea();
    chatMessagePanel.add(chatMessages, BorderLayout.CENTER);
    // debug
    chatMessages.append("message one\n");
    chatMessages.append("message two\n");
    chatMessages.append("message three\n");

    // and lower panel is for entering one's own chat messages
    JPanel chatMessageEntryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    JTextField chatMessageEntryField = new JTextField(35);
    JButton chatMessageEntryButton = new JButton("Enter");
    chatMessageEntryPanel.add(chatMessageEntryField);
    chatMessageEntryPanel.add(chatMessageEntryButton);
    chatMessagePanel.add(chatMessageEntryPanel, BorderLayout.SOUTH);

    loungeFrame.add(chatMessagePanel, BorderLayout.CENTER);

    loungeFrame.pack();    

    return loungeFrame;
  }

  private static void addButtons(JPanel panel, String ... labels)
  {
    for (String label : labels)
    {
      JButton button = new JButton(label);
      panel.add(button);
    }
  }

}

Give the JList a prototype cell value that is wide enough to display what you need. eg,

gameJList.setPrototypeCellValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

The prototype value (here a String because the list has been declared as a JList<String> ) is used to set the list's preferred size, but is not displayed in the JList. You can use as large or small a list as you need. Also be sure to set visible row count for the same purpose in the horizontal dimension:

gameJList.setVisibleRowCount(20);  // for example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM