使用BorderLayout Swing GUI问题

时间:2015-05-17 17:07:48

标签: java swing border-layout

我目前正在尝试与Layouts相处,考虑到我从未真正理解它们而只是做了nullLayout,而是绝对定位所有元素。

但是,我目前有一个合适的小项目,我正在努力学习它,这是一些小型的聊天服务。

现在是一张图片:enter image description here

这是一张图片,我想象它是如何完成的(请注意,这只是一些概念,但它应该给你正确的想法。我不是图形艺术家):{{0 }}

这是我目前的代码:

public class Gui {

JFrame frame;
JTextArea textfield;
JTextField enterMessage;

    public Gui(){

        frame = new JFrame();
        frame.setSize(600, 400);


        textfield = new JTextArea();
        textfield.setText("Textfield");
        textfield.setSize(400, 300);

        JPanel messagePanel = new JPanel();

        JTextField chatMessage = new JTextField();
        chatMessage.setText("Send me");

        JButton send = new JButton();
        send.setText("Send");


        messagePanel.add(chatMessage, BorderLayout.WEST);
        messagePanel.add(send, BorderLayout.EAST);

        frame.add(textfield, BorderLayout.WEST);
        frame.add(messagePanel, BorderLayout.SOUTH);
        frame.setVisible(true);
    }
}

我的想法,连同对BorderLayouts的理解,到目前为止,将文本字段放在框架内,在WEST侧,聊天对话框将在稍后结束。

要发送的按钮和输入某些文本的字段将位于面板内,具有自己的borderlayout,而按钮右侧有一些较小的部分,宽度的其余部分正在填充文本字段。

整个面板然后在框架的南侧结束。

但是,现在我遇到的问题是,这些元素会逐渐缩小到最小尺寸。

我尝试用setSize()修复此问题; ,但这根本没有影响,只是被完全忽略了。

有任何帮助指出我正确的方向吗?

5 个答案:

答案 0 :(得分:4)

最初,您有一个简单的问题:

//          should be new JPanel(new BorderLayout())
JPanel messagePanel = new JPanel();

然后,在此之后,通常BorderLayout喜欢在BorderLayout.CENTER中拉伸组件。因此,您希望将textfieldchatMessage置于中心位置。

public Gui(){
    frame = new JFrame();
    frame.setSize(600, 400);

    textfield = new JTextArea();
    textfield.setText("Textfield");
//    textfield.setSize(400, 300);

    JPanel messagePanel = new JPanel(new BorderLayout());

    JTextField chatMessage = new JTextField("Send me");
    JButton send = new JButton("Send");

    messagePanel.add(chatMessage, BorderLayout.CENTER);
    messagePanel.add(send, BorderLayout.EAST);

    frame.add(textfield, BorderLayout.CENTER);
    frame.add(messagePanel, BorderLayout.SOUTH);
    frame.setVisible(true);
}

一旦你这样做,你应该得到这样的东西:

yay

但是,正如一些建议:

  • 不要依赖JFrame的setSize。相反,您应该在单个组件上使用setPreferredSize,整个UI应该自行调整大小。 (可能是主要文本区域。)JFrame的大小包括,例如,标题栏。
  • 您应该考虑将JTextArea打包在滚动窗格中。然后,您可以setPreferredSize on the viewport
  • 在您拥有首选尺寸的组件后,请在调用pack()之前在JFrame上调用setVisible(true)。这将自动调整大小。

类似的东西:

frame = new JFrame();
// frame.setSize(600, 400);

...

JScrollPane pane = new JScrollPane(
    textfield,
    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
    JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// specifying initial size for the
// visible portion of the scroll pane
pane.getViewport().setPreferredSize(new Dimension(320, 200));

frame.add(pane, BorderLayout.CENTER);
frame.add(messagePanel, BorderLayout.SOUTH);
// entire UI sizes around the scroll pane view
frame.pack();
frame.setVisible(true);

答案 1 :(得分:2)

BoxLayout中试试BorderLayout messagePanel

messagePanel.setLayout(new BoxLayout(messagePanel,BoxLayout.LINE_AXIS));
messagePanel.add(chatMessage);
messagePanel.add(send);

对于textField

frame.add(textfield, BorderLayout.CENTER);

答案 2 :(得分:2)

尝试设置元素的首选大小尺寸。

textfield.setText("Textfield");
textfield.setPreferredSize(new Dimension(600, 300));
//some other code


JTextField chatMessage = new JTextField();
chatMessage.setPreferredSize(new Dimension(500, 25));
//some other code

答案 3 :(得分:2)

正如Sridhar所指出的,BorderLayout并不总是尊重子面板的尺寸。要解决此问题,您应该使用textfield而非messagePanel初始化子面板(在本例中为setPreferedSize()setSize())。

答案 4 :(得分:2)

将构造函数更改为

public Gui() {

    frame = new JFrame();
    frame.setSize(600, 400);


    textfield = new JTextArea();
    textfield.setText("Textfield");
    textfield.setSize(400, 300);
    // set border layout to JPanel
    JPanel messagePanel = new JPanel(new BorderLayout());

    JTextField chatMessage = new JTextField();
    chatMessage.setText("Send me");

    JButton send = new JButton();
    send.setText("Send");

    // add JTextField to CENTER and button to EAST
    messagePanel.add(chatMessage, BorderLayout.CENTER);
    messagePanel.add(send, BorderLayout.EAST);

    // add textArea to CENTER of JFrame
    frame.add(textfield, BorderLayout.CENTER);
    frame.add(messagePanel, BorderLayout.SOUTH);
    frame.setVisible(true);
}

它会起作用..