Reputation: 6469
I'm implementing a simple chat application, using Java. I want my chat application to have the "bubble" message style like modern message apps, so I've built 2 classes LeftArrowBubble
and RightArrowBubble
which extend JPanel to illustrate sender & receiver bubbles, like this:
This is the code for my LeftArrowBubble
class (quite alike for 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);
}
}
Now I have a JFrame window with a JScrollPane
on it, which looks like this:
What I want to do now is when I click on that CreateNewBubble
button, a new Left(or Right)ArrowBubble
JPanel will be created & displayed inside that JScrollPane
(and this JScrollPane
will be vertical scrollable if there're more bubbles inside of it). I've already tried this way:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
BubbleTest.LeftArrowBubble leftArrowBubble = new BubbleTest.LeftArrowBubble();
jScrollPane1.add(leftArrowBubble);
}
But it didn't work as I expected: nothing shows up in the JScrollPane
after clicking the button!
I've been stuck at this problem for hours, really appreciate if you guys can help!
Upvotes: 0
Views: 1336
Reputation: 50041
You can't use .add
that way on a JScrollPane. A JScrollPane can only scroll a single component, which is set by either passing it to its constructor, or by calling .setViewportView
.
Instead, create a separate container for the bubbles, such as a vertical Box, and set that as the single component scrolled by the scroll pane:
Box box = new Box(BoxLayout.Y_AXIS);
JScrollPane jScrollPane1 = new JScrollPane(box);
When you add a bubble, add it to the box (and call .revalidate()
to lay it out):
box.add(leftArrowBubble);
box.revalidate();
Edit: Also, your bubbles will not, by default, have any size, unless you give them a size such as by calling setPreferredSize
or by overriding getPreferredSize
or by putting components inside them.
Upvotes: 3
Reputation: 3165
With JScrollPane you should always add components to the scroll pane's JViewPort. Look at the documentation here, it explains the concept behind the class rather well.
Short summary: A JScrollPane holds the scroll bars and a view port. The view port is a component that displays only a portion of its content - in this case the part that is visible on screen. The scroll bars tell the view port which portion to show.
Upvotes: 2