How to solve misalignment in boxlayout?

╄→尐↘猪︶ㄣ 提交于 2019-12-11 03:27:18

问题


I'm trying to add multiple Jlabels in a Jpanel with Box layout, But i'm facing prolems on setting their setAlignmentX() . I'm reffering to an example from this site of Text bubble border and trying to pull out some examples from it. The jpanel is then added in Jscrollpane.

My code is here !!!

//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 starts here

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);
    }
}

Plus i think i will face problem while wrapping up text in Jlabel, although i used HTML wrapping technique in chatpanel. that will not be effecient with changing sizes of msgboxes!! thanks in advance for help!!


回答1:


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);
    }
}



回答2:


Interchange values of jl.setAlignmentX(0) 0 to 1 and 1 to 0 .in msgbox or ChatPaneMsgBox classes which are given here. Like

      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
              }

even i think now jl.setAlignmentX(); doesn't matter anymore.

Thanks a lot to @mKorbel & @kleopatra for their help & suggestions. :-)




回答3:


The GridbagLayoutManager does a good job of helping to keep rectangular layouts easy to manage in terms of width and auto sizing. The programming mechanisms of GridbagLayout are data intensive and this causes many people to run away from it.

Back in 1996, I created the Packer class that is on Java.net under the Packer project. It wraps GridbagLayoutManager in a subclass which creates and uses GridbagLayout data items to make things work.

To create a simple layout like this, you just need to do something like the following.

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);
    }
}

Then, you can create the appropriate MsgObject and just add it to the container and it will appear there. You can add appropriate code for scrolling on add etc.



来源:https://stackoverflow.com/questions/17740694/how-to-solve-misalignment-in-boxlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!