【问题标题】:Swing - Trouble with layout managersSwing - 布局管理器的问题
【发布时间】:2016-01-31 03:14:51
【问题描述】:

我正在尝试使用 Java Swing 制作一个聊天应用程序,但我遇到了聊天气泡问题。我设法完成了起泡部分,但我似乎无法正确放置它们。这是我的代码

            package messagebubble;

import java.awt.BorderLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

import messagebubble.RoundedBorder;

public class Main {

public static void main(String[] args) {

    JFrame window = new JFrame();

    JPanel chat = new JPanel();
    chat.setLayout(new BoxLayout(chat, BoxLayout.PAGE_AXIS));

    JPanel painel = new JPanel(new BorderLayout());
    JPanel painel2 = new JPanel(new BorderLayout());

    JTextArea msg = new JTextArea();
    msg.setLineWrap(true);
    msg.setWrapStyleWord(true);

    msg.setText("ola tudo bem meus caros amigos, como estão? há muito que não vos via por estas bandas haha lol");
    msg.setBorder(new RoundedBorder());
    msg.setColumns(msg.getLineCount());

    JTextArea msg2 = new JTextArea();
    msg2.setLineWrap(true);
    msg2.setWrapStyleWord(true);

    msg2.setText("ola tudo bem");
    msg2.setBorder(new RoundedBorder());

    painel.add(msg,BorderLayout.NORTH);

    chat.add(painel);
    painel2.add(msg2,BorderLayout.NORTH);

    chat.add(painel2);

    window.add(chat);

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setSize(400, 500);
    window.setVisible(true);



    }

}

这是圆形边框

package GUI;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;

import javax.swing.border.AbstractBorder;

public class RoundedBorder extends AbstractBorder {



@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width,
        int height) {

    Graphics2D graph = (Graphics2D) g.create();
    RoundRectangle2D round = new RoundRectangle2D.Float(x, y, width - 1,
            height - 1, 30, 30);
    Container parent = c.getParent();

    if (parent != null) {
        graph.setColor(parent.getBackground());
        Area canto = new Area(new Rectangle2D.Float(x,y,width,height));
        canto.subtract(new Area(round));
        graph.fill(canto);
    }

    graph.setColor(Color.GRAY);
    graph.draw(round);
    graph.dispose();

}

@Override
public Insets getBorderInsets(Component c) {
    return new Insets(5, 10, 5, 10);
}

@Override
public Insets getBorderInsets(Component c, Insets insets) {
    insets.left = 10;
    insets.right = insets.left;
    insets.top = 5;
    insets.bottom = insets.top;
    return insets;
}

}

输出看起来像这样Output。我无法摆脱消息之间的空白或底部 JTextArea 中的空白。

我还尝试将面板的最大尺寸设置为他们喜欢的尺寸,它看起来像 Output2 这太窄了。

知道如何解决这个问题吗?我想要实现的是这样的ideal

【问题讨论】:

  • 考虑创建和发布 1) 你的 minimal reproducible example(请阅读链接)和 2) 当前和所需 GUI 的图像。
  • 那么,您想要输出到什么样的外观?顶部的大输出框和底部的小输入线?还是每条消息的全宽条?
  • @tobias_k 我添加了一个理想的输出。基本上我希望它看起来像 android 消息应用程序,但现在我会满足于删除额外的空间。
  • @tobias_k 我相信他希望 FROM 消息在右侧有一个边距,而 TO 消息在左侧有一个边距(这是当今聊天应用程序中的常见约定)
  • @ggpfc 请发布一个可运行的代码示例,如果没有更多上下文,很难提供帮助

标签: java swing user-interface chat layout-manager


【解决方案1】:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class Main {

    public static void main(String[] args) {

    Border left = new CompoundBorder(new EBorder(0, 0, 0, 100), new RoundedBorder());
    Border right = new CompoundBorder(new EBorder(0, 100, 0, 0), new RoundedBorder());

    JFrame window = new JFrame();

    JPanel chat = new JPanel();
    chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));

    JTextArea msg = new Message();
    msg.setLineWrap(true);
    msg.setWrapStyleWord(true);

    msg.setText("ola tudo bem meus caros amigos, como estão? há muito que não vos via por estas bandas haha lol");
    msg.setBorder(left);

    JTextArea msg2 = new Message();
    msg2.setLineWrap(true);
    msg2.setWrapStyleWord(true);

    msg2.setText("ola tudo bem");
    msg2.setBorder(right);

    chat.add(msg);
    chat.add(msg2);

    window.add(chat);

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setSize(400, 500);
    window.setVisible(true);

    }

    static class Message extends JTextArea {
    private static final long serialVersionUID = -2226104809841941057L;

    @Override
    public Dimension getMaximumSize() {
        return new Dimension(super.getMaximumSize().width, getPreferredSize().height);
    }
    }

    static class EBorder extends EmptyBorder {

    private static final long serialVersionUID = 1265703863790826185L;

    public EBorder(int top, int left, int bottom, int right) {
        super(top, left, bottom, right);
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        g.setColor(c.getParent().getBackground());
        g.fillRect(x, y, left, height);
        g.fillRect(x + width - right, y, right, height);
    }
    }
}

【讨论】:

  • 这完美地修复了对齐,但我也希望 JTextArea 适合文本,而不是在添加较短消息时更大。这就是为什么我尝试将最大宽度设置为与首选宽度相同,
  • 您可以调整 EmptyBorder 的宽度。
【解决方案2】:

我会推荐

  • 使用单个 BorderLayout 来容纳所有组件
  • 让它在 BorderLayout.PAGE_START 位置持有另一个使用 BoxLayout PAGE_AXIS 的 JPanel。
  • 将您的聊天添加到 BoxLayout JPanel。
  • 请注意,我们大多数人都没有您的圆角矩形边框实用程序,因此无法对此进行测试。

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;


public class MainPanel extends JPanel {

    private static final int PREF_W = 400;
    private static final int PREF_H = 500;
    private JPanel msgHoldingPanel = new JPanel();


    public MainPanel() {
        JTextArea msg = new JTextArea();
        msg.setLineWrap(true);
        msg.setWrapStyleWord(true);

        msg.setText("ola tudo bem meus caros amigos, como estão? há muito que não vos via por estas bandas haha lol");

        // !! msg.setBorder(new RoundedBorder());
        msg.setBorder(BorderFactory.createLineBorder(Color.blue));

        msg.setColumns(msg.getLineCount());

        JTextArea msg2 = new JTextArea();
        msg2.setLineWrap(true);
        msg2.setWrapStyleWord(true);

        msg2.setText("ola tudo bem");
        msg2.setBorder(BorderFactory.createLineBorder(Color.blue));

        msgHoldingPanel.setLayout(new BoxLayout(msgHoldingPanel, BoxLayout.PAGE_AXIS));
        msgHoldingPanel.add(msg);
        msgHoldingPanel.add(Box.createVerticalStrut(3));
        msgHoldingPanel.add(msg2);

        setLayout(new BorderLayout());
        add(msgHoldingPanel, BorderLayout.PAGE_START);
    }


    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("MainPanel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

【讨论】:

  • 这完美地修复了对齐,但我也希望 JTextArea 适合文本,而不是在添加较短消息时更大。这就是为什么我尝试将最大宽度设置为与首选宽度相同,
【解决方案3】:

在 Chat JPanel 上使用 GridBagLayout 可能会更好,并且会丢失它们不需要的另外 2 个 JPanel。

类似的东西

JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.LINE_START;
JTextArea msg = new JTextArea();
msg.setText("ola tudo bem meus caros amigos, como estão? há muito que não vos via por estas bandas haha lol");
pane.add(msg , c);

// Now change the side of the placement on the layout manager
c.anchor = GridBagConstraints.LINE_END;
JTextArea msg2 = new JTextArea();
msg.setText("AGORA VAI RAPÁ!");
pane.add(msg , c);

【讨论】:

    猜你喜欢
    • 2011-06-11
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 2016-08-26
    相关资源
    最近更新 更多