2013-07-19 3 views
2

Я пытаюсь добавить несколько Jlabels в Jpanel с компоновкой коробки, но я столкнулся с пролемами при установке setAlignmentX(). Я привожу пример из этого сайта границы текстового пузыря и пытаюсь извлечь из него несколько примеров. Затем jpanel добавляется в Jscrollpane.Как решить несоосность в boxlayout?

Мой код здесь !!!

//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 метод оборачивания в chatpanel. это не будет эффективно с меняющимися размерами msgbox! Заранее спасибо за помощь!

+1

действительно не читал ваш код на какой-либо глубине, так что это может быть не проблема, просто: BoxLayout требует, чтобы все дети имели одинаковое выравнивание в "другом" (см. соответствующую главу в учебнике, упомянутом в викинге wiki). Не связаны: ознакомьтесь с соглашениями об именах java и придерживайтесь их. – kleopatra

+0

Кстати: что это за проблема? – kleopatra

+0

@kleopatra Извинения, я новичок в java. Я сохраню это в своем уме. Проблема была при запуске chatpanel.Оба msgbox были смещены. Теперь снова извиняюсь, что перепроверил мой код. это проблема со значениями. в msgbox. Но все равно, как решить проблему обертывания текста в JLabel. –

ответ

2

enter image description hereenter 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); 
    } 
} 
+0

большое спасибо, я могу многое узнать из этого кода! : D –

+0

Вот эта ссылка на картинку, которую я захватил! если мы используем msgboxes разных размеров в макете коробки, они искажают выравнивание. Я думаю, мне придется изменить свой менеджер макетов. Но если у вас есть какие-либо другие предложения, пожалуйста, дайте мне знать! Спасибо за помощь . https://docs.google.com/file/d/0B2FlsxAUHToXSlJJMFJYY2w5Vmc/edit?usp=sharing –

+0

, пожалуйста, см. мой комментарий под картинками в моем ответе, нужно использовать константы (dymanically manage with alingment) в используемом LayoutManager, если есть aren ' t любой или не работает корректно, затем использовать другой LayoutManager :-) – mKorbel

1

Обменные значения jl.setAlignmentX (0) От 0 до 1 и от 1 до 0. В классах msgbox или ChatPaneMsgBox, которые приведены здесь. Как

 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 & @kleopatra за помощь & предложения. :-)

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 и просто добавить его в контейнер, и он появится там. Вы можете добавить соответствующий код для прокрутки при добавлении и т. Д.

 Смежные вопросы

  • Нет связанных вопросов^_^