如何将JPanels添加到JScrollPane?

时间:2014-10-26 15:12:20

标签: java swing jframe jpanel jscrollpane

我正在使用Java实现一个简单的聊天应用程序。我希望我的聊天应用程序能够拥有" bubble"消息样式就像现代消息应用程序一样,所以我已经构建了2个类LeftArrowBubbleRightArrowBubble,它们扩展了JPanel以说明发送者&接收器气泡,像这样:

enter image description here

这是我的LeftArrowBubble课程的代码(RightArrowBubble非常相似):

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JPanel;
/**
 * @author harsh
 */
public class LeftArrowBubble extends JPanel {
   private static final long serialVersionUID = -5389178141802153305L;
   private int radius = 10;
   private int arrowSize = 12;
   private int strokeThickness = 3;
   private int padding = strokeThickness / 2;
   @Override
   protected void paintComponent(final Graphics g) {
      final Graphics2D g2d = (Graphics2D) g;
      g2d.setColor(new Color(0.5f, 0.8f, 1f));
      int x = padding + strokeThickness + arrowSize;
      int width = getWidth() - arrowSize - (strokeThickness * 2);
      int bottomLineY = getHeight() - strokeThickness;
      g2d.fillRect(x, padding, width, bottomLineY);
      g2d.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
      g2d.setStroke(new BasicStroke(strokeThickness));
      RoundRectangle2D.Double rect = new RoundRectangle2D.Double(x, padding, width, bottomLineY, radius, radius);
      Polygon arrow = new Polygon();
      arrow.addPoint(20, 8);
      arrow.addPoint(0, 10);
      arrow.addPoint(20, 12);
      Area area = new Area(rect);
      area.add(new Area(arrow));
      g2d.draw(area);
   }
}

现在我有一个JFrame窗口,上面有JScrollPane,如下所示:

enter image description here

我现在要做的是当我点击CreateNewBubble按钮时,会创建一个新的Left(or Right)ArrowBubble JPanel&显示在JScrollPane内部(如果其中有更多气泡,则此JScrollPane将是垂直滚动的)。我已经尝试过这种方式了:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    BubbleTest.LeftArrowBubble leftArrowBubble = new BubbleTest.LeftArrowBubble();
    jScrollPane1.add(leftArrowBubble);
}

但它并没有像我预期的那样工作:单击按钮后JScrollPane中没有显示任何内容! 我已经坚持这个问题好几个小时了,如果你们能帮忙的话,真的很感激!

2 个答案:

答案 0 :(得分:3)

您无法在JScrollPane上使用.add。 JScrollPane只能滚动单个组件,该组件通过将其传递给构造函数或通过调用.setViewportView来设置。

相反,为气泡创建一个单独的容器,例如垂直Box,并将其设置为滚动窗格滚动的单个组件:

Box box = new Box(BoxLayout.Y_AXIS);
JScrollPane jScrollPane1 = new JScrollPane(box);

添加气泡时,请将其添加到框中(并调用.revalidate()将其布置出来):

box.add(leftArrowBubble);
box.revalidate();

编辑:此外,默认情况下,您的气泡不会有任何尺寸,除非您通过调用setPreferredSize或覆盖getPreferredSize或将组件放入其中来给它们一个大小。< / p>

答案 1 :(得分:2)

使用JScrollPane,您应该始终将组件添加到滚动窗格的JViewPort中。看一下文档here,它很好地解释了课程背后的概念。

简短摘要:JScrollPane包含滚动条和视图端口。视口是仅显示其内容的一部分的组件 - 在这种情况下是屏幕上可见的部分。滚动条告诉视口哪个部分显示。