如何解决boxlayout中的错位?

时间:2013-07-19 07:44:05

标签: java swing jpanel alignment boxlayout

我正在尝试使用Box布局在Jpanel中添加多个Jlabel,但我在设置setAlignmentX()时遇到了问题。我正在从这个文本泡泡边框的网站上做一个例子,试图从中提取一些例子。然后在Jscrollpane中添加jpanel。

我的代码在这里!!!

//Source :Andrew Thompson

 class TextBubbleBorder extends AbstractBorder {
 private Color color;
 private int thickness = 4;
 private int radii = 8;
private int pointerSize = 7;
private Insets insets = null;
private BasicStroke stroke = null;
private int strokePad;
private int pointerPad = 4;
private boolean left = true;
RenderingHints hints;

TextBubbleBorder(
        Color color) {
    new TextBubbleBorder(color, 4, 8, 7);
}

TextBubbleBorder(
        Color color, int thickness, int radii, int pointerSize) {
    this.thickness = thickness;
    this.radii = radii;
    this.pointerSize = pointerSize;
    this.color = color;

    stroke = new BasicStroke(thickness);
    strokePad = thickness / 2;

    hints = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    int pad = radii + strokePad;
    int bottomPad = pad + pointerSize + strokePad;
    insets = new Insets(pad, pad, bottomPad, pad);
}

TextBubbleBorder(
        Color color, int thickness, int radii, int pointerSize, boolean left) {
    this(color, thickness, radii, pointerSize);
    this.left = left;
}

@Override
public Insets getBorderInsets(Component c) {
    return insets;
}

@Override
public Insets getBorderInsets(Component c, Insets insets) {
    return getBorderInsets(c);
}

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

    Graphics2D g2 = (Graphics2D) g;

    int bottomLineY = height - thickness - pointerSize;

    RoundRectangle2D.Double bubble = new RoundRectangle2D.Double(
            0 + strokePad,
            0 + strokePad,
            width - thickness,
            bottomLineY,
            radii,
            radii);

    Polygon pointer = new Polygon();

    if (left) {
        // left point
        pointer.addPoint(
                strokePad + radii + pointerPad,
                bottomLineY);
        // right point
        pointer.addPoint(
                strokePad + radii + pointerPad + pointerSize,
                bottomLineY);
        // bottom point
        pointer.addPoint(
                strokePad + radii + pointerPad + (pointerSize / 2),
                height - strokePad);
    } else {
        // left point
        pointer.addPoint(
                width - (strokePad + radii + pointerPad),
                bottomLineY);
        // right point
        pointer.addPoint(
                width - (strokePad + radii + pointerPad + pointerSize),
                bottomLineY);
        // bottom point
        pointer.addPoint(
                width - (strokePad + radii + pointerPad + (pointerSize / 2)),
                height - strokePad);
    }

    Area area = new Area(bubble);
    area.add(new Area(pointer));

    g2.setRenderingHints(hints);

    // Paint the BG color of the parent, everywhere outside the clip
    // of the text bubble.
    Component parent  = c.getParent();
    if (parent!=null) {
        Color bg = parent.getBackground();
        Rectangle rect = new Rectangle(0,0,width, height);
        Area borderRegion = new Area(rect);
        borderRegion.subtract(area);
        g2.setClip(borderRegion);
        g2.setColor(bg);
        g2.fillRect(0, 0, width, height);
        g2.setClip(null);
    }

    g2.setColor(color);
    g2.setStroke(stroke);
    g2.draw(area);
}}

 //TextBubbleBorder ends here

Msgbox从这里开始

class msgbox extends JPanel {

    boolean ij = true;
    String msg = "";
    JLabel jl;

    msgbox() {
        //  msgpnl();
    }

    msgbox(String str, boolean bj) {
        ij = bj;
        msg = str;
        msgpnl();
    }
    /* public void setText(String str, boolean  bj){
     ij=bj;
     msg=str;
     msgpnl();
     }
     */

    public void msgpnl() {
        //setLayout(new GridLayout(0, 1));
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        if (ij) {
            jl = new JLabel(msg);

            jl.setOpaque(true);
            jl.setBorder(new TextBubbleBorder(Color.LIGHT_GRAY, 1, 10, 7, ij));

            jl.setBackground(new Color(123, 104, 238));
            jl.setAlignmentX(0);
        } else {
            jl = new JLabel(msg, SwingConstants.RIGHT);

            jl.setOpaque(true);
            jl.setBorder(new TextBubbleBorder(Color.LIGHT_GRAY, 1, 10, 7, ij));

            jl.setBackground(new Color(224, 102, 255));
            jl.setAlignmentX(1);
        }
        this.add(jl);
        System.out.print("\nThis executed");
    }
}

chatpanel

class chatpanel extends JScrollPane {

    static JPanel jp;

    chatpanel() {
        this.setVisible(true);
        //this.setLayout(null);
        this.jp = new JPanel();
        this.jp.setLayout(new BoxLayout(this.jp, BoxLayout.Y_AXIS));
        //jp= new JPanel( new GridLayout(0, 1,0,5));
        //this.setLayout(new GridLayout(1,1));
        this.getViewport().add(jp);
        jp.setVisible(true);
        setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    }

    public void addmsg(Component co) {
        //msgscp.add(co);
        //co.setSize(100, 30);
        jp.add(co);
    }

    public static void main(String args[]) {
        JFrame jf = new JFrame("Testing msgpanel");
        jf.setLayout(new GridLayout(0, 1, 0, 0));
        chatpanel cp = new chatpanel();
        JButton jb = new JButton("new");
        msgbox mb;
        mb = new msgbox("<html><body style='width: 200px; padding: 5px;'>"
                + "<h1>Do U C Me?</h1>"
                + "Here is a long string that will wrap.  "
                + "The effect we want is a multi-line label.", true);
        // mb.setText();
        cp.addmsg(mb);
        msgbox mb2 = new msgbox("Hello 2", false);
        cp.addmsg(mb2);
        jb.setSize(100, 30);
        jf.add(cp);
        //jf.add(jb);
        jf.setSize(400, 400);
        //jf.pack();
        jf.setVisible(true);
    }
}

另外我认为我在Jlabel中包装文本时会遇到问题,尽管我在聊天面板中使用了HTML包装技术。改变msgboxes的大小不会有效!!在此先感谢您的帮助!!

3 个答案:

答案 0 :(得分:2)

enter image description here enter image description here

only in due all my respect to @Andrew Thompson :-) and my curiosity

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

public class ChatPanel {

    private JFrame jf = new JFrame("Testing msgpanel");
    private JScrollPane scroll = new JScrollPane();
    private JPanel jp;
    private ChatPaneMsgBox mb;
    private ChatPaneMsgBox mb2;
    private JPanel cp = new JPanel();
    private JButton jb = new JButton("  ME !!! ");
    private JButton jb1 = new JButton("  YOU !!! ");

    public ChatPanel() {
        jp = new JPanel();
        jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
        mb = new ChatPaneMsgBox("<html><body style='width: 200px; padding: 5px;'>"
                + "<h1>Do U C Me?</h1>"
                + "Here is a long string that will wrap.  "
                + "The effect we want is a multi-line label.", true);
        addmsg(mb);
        mb2 = new ChatPaneMsgBox("Hello 2", false);
        addmsg(mb2);
        scroll.setViewportView(jp);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mb = new ChatPaneMsgBox("<html><body style='width: 200px; padding: 5px;'>"
                        + "<h1>Do U C Me?</h1>"
                        + "Here is a long string that will wrap.  "
                        + "The effect we want is a multi-line label.", true);
                addmsg(mb);
                Rectangle rect = jp.getBounds();
                Rectangle r2 = scroll.getViewport().getVisibleRect();
                jp.scrollRectToVisible(new Rectangle((int) rect.getWidth(), 
                        (int) rect.getHeight(), (int) r2.getWidth(), (int) r2.getHeight()));
            }
        });
        jb1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mb2 = new ChatPaneMsgBox("Hello 2", false);
                addmsg(mb2);
                Rectangle rect = jp.getBounds();
                Rectangle r2 = scroll.getViewport().getVisibleRect();
                jp.scrollRectToVisible(new Rectangle((int) rect.getWidth(), 
                        (int) rect.getHeight(), (int) r2.getWidth(), (int) r2.getHeight()));
            }
        });
        cp.add(jb);
        cp.add(jb1);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(scroll);
        jf.add(cp, BorderLayout.SOUTH);
        jf.setSize(400, 400);
        jf.setVisible(true);
    }

    private void addmsg(Component co) {
        jp.add(co);
        jp.revalidate();
        jp.repaint();
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ChatPanel();
            }
        });
    }
}

import java.awt.Color;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

class ChatPaneMsgBox extends JPanel {

    boolean ij = true;
    private String msg = "";
    private JLabel jl;

    public ChatPaneMsgBox() {
    }

    public ChatPaneMsgBox(String str, boolean bj) {
        ij = bj;
        msg = str;
        msgpnl();
    }

    private void msgpnl() {
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        if (ij) {
            jl = new JLabel(msg);

            jl.setOpaque(true);
            jl.setBorder(new TextBubbleBorder(Color.LIGHT_GRAY, 1, 10, 7, ij));

            jl.setBackground(new Color(123, 104, 238));
            jl.setAlignmentX(0);
        } else {
            jl = new JLabel(msg, SwingConstants.RIGHT);

            jl.setOpaque(true);
            jl.setBorder(new TextBubbleBorder(Color.LIGHT_GRAY, 1, 10, 7, ij));

            jl.setBackground(new Color(224, 102, 255));
            jl.setAlignmentX(1);
        }
        this.add(jl);
        System.out.print("\nThis executed");
    }
}

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.border.AbstractBorder;

class TextBubbleBorder extends AbstractBorder {

    private Color color;
    private int thickness = 4;
    private int radii = 8;
    private int pointerSize = 7;
    private Insets insets = null;
    private BasicStroke stroke = null;
    private int strokePad;
    private int pointerPad = 4;
    private boolean left = true;
    RenderingHints hints;

    TextBubbleBorder(Color color) {
        new TextBubbleBorder(color, 4, 8, 7);
    }

    TextBubbleBorder(Color color, int thickness, int radii, int pointerSize) {
        this.thickness = thickness;
        this.radii = radii;
        this.pointerSize = pointerSize;
        this.color = color;
        stroke = new BasicStroke(thickness);
        strokePad = thickness / 2;
        hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);
        int pad = radii + strokePad;
        int bottomPad = pad + pointerSize + strokePad;
        insets = new Insets(pad, pad, bottomPad, pad);
    }

    TextBubbleBorder(Color color, int thickness, int radii, int pointerSize, boolean left) {
        this(color, thickness, radii, pointerSize);
        this.left = left;
    }

    @Override
    public Insets getBorderInsets(Component c) {
        return insets;
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        return getBorderInsets(c);
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2 = (Graphics2D) g;
        int bottomLineY = height - thickness - pointerSize;
        RoundRectangle2D.Double bubble = new RoundRectangle2D.Double(
                0 + strokePad,
                0 + strokePad,
                width - thickness,
                bottomLineY,
                radii,
                radii);
        Polygon pointer = new Polygon();
        if (left) {
            // left point
            pointer.addPoint(
                    strokePad + radii + pointerPad,
                    bottomLineY);
            // right point
            pointer.addPoint(
                    strokePad + radii + pointerPad + pointerSize,
                    bottomLineY);
            // bottom point
            pointer.addPoint(
                    strokePad + radii + pointerPad + (pointerSize / 2),
                    height - strokePad);
        } else {
            // left point
            pointer.addPoint(
                    width - (strokePad + radii + pointerPad),
                    bottomLineY);
            // right point
            pointer.addPoint(
                    width - (strokePad + radii + pointerPad + pointerSize),
                    bottomLineY);
            // bottom point
            pointer.addPoint(
                    width - (strokePad + radii + pointerPad + (pointerSize / 2)),
                    height - strokePad);
        }
        Area area = new Area(bubble);
        area.add(new Area(pointer));
        g2.setRenderingHints(hints);
        // Paint the BG color of the parent, everywhere outside the clip
        // of the text bubble.
        Component parent = c.getParent();
        if (parent != null) {
            Color bg = parent.getBackground();
            Rectangle rect = new Rectangle(0, 0, width, height);
            Area borderRegion = new Area(rect);
            borderRegion.subtract(area);
            g2.setClip(borderRegion);
            g2.setColor(bg);
            g2.fillRect(0, 0, width, height);
            g2.setClip(null);
        }
        g2.setColor(color);
        g2.setStroke(stroke);
        g2.draw(area);
    }
}

答案 1 :(得分:1)

此处给出的msgbox或ChatPaneMsgBox类中的 jl.setAlignmentX(0)0到1和1到0 。的交换值。像

      if (ij) {
              this.setLayout(new FlowLayout(FlowLayout.LEFT));
              //rest code
              jl.setAlignmentX(1); 
              //rest code here
              }
       else   {
               this.setLayout(new FlowLayout(FlowLayout.Right));
              //rest code
              jl.setAlignmentX(0); 
              //rest code here
              }

即使我认为现在jl.setAlignmentX();没关系了。

非常感谢@mKorbel&amp; @kleopatra的帮助和帮助建议。 : - )

答案 2 :(得分:0)

GridbagLayoutManager在帮助保持矩形布局在宽度和自动调整大小方面易于管理方面做得很好。 GridbagLayout的编程机制是数据密集型的,这导致许多人逃避它。

早在1996年,我在Packer项目下创建了Java.net上的Packer类。它将GridbagLayoutManager包装在一个子类中,该子类创建并使用GridbagLayout数据项来使事情有效。

要创建这样的简单布局,您只需要执行以下操作。

class MsgObject extends JPanel {
    public MsgObject(String text) {
        Packer pk = new Packer( this );
        pk.pack( new JLabel("<html><body>"+text+"</body></html>") ).fillBoth();
    }
}
class TheirMsgObject extends MsgObject {
    public TheirMsgObject( string text ) {
        super(text);
        setBackground( new Color( 255, 220, 230 ) );
    }
}
class MyMsgObject extends MsgObject {
    public MyMsgObject( string text ) {
        super(text);
        setBackground( new Color( 220, 230, 255 ) );
    }
}
class MsgPane extends JPanel {
    int items = -1;
    Packer mpk;
    BlankSpace = blank;
    class BlankSpace extends JPanel {
        public Dimension PreferredSize() {
            return new Dimension( 100, 2 );
        }
    }
    public void MsgPane() {
        mpk = new Packer( this);
        blank = new BlankSpace();
    }

    private void addMessage( MsgObject msg, int col ) {
        mpk.pack( msg ).gridx(0).gridy(++items).gridw(col).fillx(1);
    }
    public void addMessage( TheirMsgObject msg ) {
        addMessage( msg, 0 );
    }

    public void addMessage( MyMsgObject msg ) {
        addMessage( msg, 1 );
        mpk.pack( blank ).gridx(0).gridy(items);
    }
}

然后,您可以创建相应的MsgObject并将其添加到容器中,它将显示在那里。您可以添加适当的代码以便在添加等时滚动。