Init
This commit is contained in:
commit
0ece74282d
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
/bin/
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>ExempleJPanelConversation</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.8
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
import packageIHM.MaJFrame;
|
||||||
|
|
||||||
|
public class ClassePrincipale {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
MaJFrame maFen = new MaJFrame();
|
||||||
|
maFen.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
package packageIHM;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
|
|
||||||
|
public class JPanelConversation extends JPanel
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private ArrayList<Message> messages;
|
||||||
|
private TextBubble border;
|
||||||
|
private final int marginLeft = 0;
|
||||||
|
private final int marginTop = 0;
|
||||||
|
private final int thickness = 2;
|
||||||
|
private final int radius = 8;
|
||||||
|
private final int pointerSize = 10;
|
||||||
|
private int offset = 0;
|
||||||
|
private boolean initialized = false;
|
||||||
|
private int maxCharByLine = 50;
|
||||||
|
|
||||||
|
|
||||||
|
JPanelConversation(MaJFrame mjf, ArrayList<Message> messages) {
|
||||||
|
setLayout(null);
|
||||||
|
int posX = marginLeft;
|
||||||
|
int posY;
|
||||||
|
this.messages = messages;
|
||||||
|
JTextArea bubble = null;
|
||||||
|
|
||||||
|
for (Message msg : messages) {
|
||||||
|
if (bubble!=null) {
|
||||||
|
posY = bubble.getLocation().y+bubble.getHeight();
|
||||||
|
} else {
|
||||||
|
posY = marginTop;
|
||||||
|
}
|
||||||
|
bubble = new JTextArea(wrap(msg.getMessage(),maxCharByLine));
|
||||||
|
bubble.setDisabledTextColor(Color.BLACK);
|
||||||
|
bubble.setEnabled(false);
|
||||||
|
border = new TextBubble(msg.getColor(),thickness,radius,pointerSize, msg.getSide());
|
||||||
|
bubble.setBorder(border);
|
||||||
|
bubble.setOpaque(true);
|
||||||
|
bubble .setBackground(Color.WHITE);
|
||||||
|
bubble.setSize(bubble.getPreferredSize());
|
||||||
|
bubble.setLocation(posX, posY);
|
||||||
|
bubble.setLineWrap(true);
|
||||||
|
bubble.addMouseMotionListener(new RedispatchingMouseAdapter() );
|
||||||
|
add(bubble);
|
||||||
|
msg.setBubble(bubble);
|
||||||
|
msg.setPosY(posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void createBubbleIfNecessary() {
|
||||||
|
int currentHeight = 0;
|
||||||
|
for (Message msg : messages) {
|
||||||
|
if (msg.getBubble()==null) {
|
||||||
|
JTextArea bubble = new JTextArea(wrap(msg.getMessage(),maxCharByLine));
|
||||||
|
bubble.setDisabledTextColor(Color.BLACK);
|
||||||
|
bubble.setEnabled(false);
|
||||||
|
border = new TextBubble(msg.getColor(),thickness,radius,pointerSize, msg.getSide());
|
||||||
|
bubble.setBorder(border);
|
||||||
|
bubble.setOpaque(true);
|
||||||
|
bubble.setBackground(Color.WHITE);
|
||||||
|
bubble.setSize(bubble.getPreferredSize());
|
||||||
|
bubble.setLocation(marginLeft, currentHeight);
|
||||||
|
bubble.setLineWrap(true);
|
||||||
|
add(bubble);
|
||||||
|
msg.setBubble(bubble);
|
||||||
|
msg.setPosY(currentHeight);
|
||||||
|
calculateOffsetToShowLastMessage();
|
||||||
|
} else {
|
||||||
|
currentHeight = currentHeight + msg.getBubble().getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int getFullHeightMessage() {
|
||||||
|
int fullHeight = 0;
|
||||||
|
for (Message msg : messages) {
|
||||||
|
fullHeight = fullHeight + msg.getBubble().getHeight();
|
||||||
|
}
|
||||||
|
return fullHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void calculateOffsetToShowLastMessage() {
|
||||||
|
int fullHeight = getFullHeightMessage();
|
||||||
|
if (fullHeight>getHeight()) {
|
||||||
|
offset = fullHeight-getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void up(int x) {
|
||||||
|
offset = offset + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void down(int x) {
|
||||||
|
offset = offset - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
if (!initialized) {
|
||||||
|
calculateOffsetToShowLastMessage();
|
||||||
|
initialized=true;
|
||||||
|
}
|
||||||
|
createBubbleIfNecessary();
|
||||||
|
for (Message msg : messages) {
|
||||||
|
if (msg.getSide()==SwingConstants.RIGHT) {
|
||||||
|
msg.getBubble().setLocation(getWidth()-msg.getBubble().getWidth(), msg.getPosY()-offset);
|
||||||
|
} else {
|
||||||
|
msg.getBubble().setLocation(msg.getBubble().getX(), msg.getPosY()-offset);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final String linebreak = "\n"; // or "\r\n";
|
||||||
|
|
||||||
|
public static String wrap(String string, int lineLength) {
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
for (String line : string.split(Pattern.quote(linebreak))) {
|
||||||
|
b.append(wrapLine(line, lineLength));
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String wrapLine(String line, int lineLength) {
|
||||||
|
if (line.length() == 0) return linebreak;
|
||||||
|
if (line.length() <= lineLength) return line + linebreak;
|
||||||
|
String[] words = line.split(" ");
|
||||||
|
StringBuilder allLines = new StringBuilder();
|
||||||
|
StringBuilder trimmedLine = new StringBuilder();
|
||||||
|
for (String word : words) {
|
||||||
|
if (trimmedLine.length() + 1 + word.length() <= lineLength) {
|
||||||
|
trimmedLine.append(word).append(" ");
|
||||||
|
} else {
|
||||||
|
allLines.append(trimmedLine).append(linebreak);
|
||||||
|
trimmedLine = new StringBuilder();
|
||||||
|
trimmedLine.append(word).append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trimmedLine.length() > 0) {
|
||||||
|
allLines.append(trimmedLine);
|
||||||
|
}
|
||||||
|
allLines.append(linebreak);
|
||||||
|
return allLines.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
package packageIHM;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
public class MaJFrame extends JFrame implements MouseMotionListener{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 7252959164975426293L;
|
||||||
|
private JPanel contentPane;
|
||||||
|
private JPanelConversation conversationPanel;
|
||||||
|
private JPanel panel;
|
||||||
|
private JTextField textFieldMsg;
|
||||||
|
private ArrayList<Message> messages;
|
||||||
|
private int previousY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the frame.
|
||||||
|
*/
|
||||||
|
public MaJFrame() {
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setBounds(100, 100, 450, 300);
|
||||||
|
contentPane = new JPanel();
|
||||||
|
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
contentPane.setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
|
panel = new JPanel();
|
||||||
|
panel.setBorder(new LineBorder(new Color(0, 0, 0)));
|
||||||
|
contentPane.add(panel, BorderLayout.NORTH);
|
||||||
|
panel.setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
|
|
||||||
|
Action action = new AbstractAction() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
addMessage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
JButton buttonAdd = new JButton("Add");
|
||||||
|
panel.add(buttonAdd, BorderLayout.EAST);
|
||||||
|
buttonAdd.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
addMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
textFieldMsg = new JTextField();
|
||||||
|
panel.add(textFieldMsg, BorderLayout.CENTER);
|
||||||
|
textFieldMsg.setColumns(10);
|
||||||
|
textFieldMsg.addActionListener(action);
|
||||||
|
|
||||||
|
messages = new ArrayList<Message>();
|
||||||
|
String msgLeft = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"
|
||||||
|
+ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";
|
||||||
|
String msgRight = "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n"
|
||||||
|
+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
|
||||||
|
|
||||||
|
for (int i=0;i<20;i++) {
|
||||||
|
if (i%2==0) {
|
||||||
|
messages.add(new Message(Color.BLUE, i + " " + msgLeft, SwingConstants.LEFT));
|
||||||
|
} else {
|
||||||
|
messages.add(new Message(Color.RED, i + " " + msgRight, SwingConstants.RIGHT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conversationPanel = new JPanelConversation(this, messages);
|
||||||
|
conversationPanel .setBackground(Color.WHITE);
|
||||||
|
conversationPanel.addMouseMotionListener(this);
|
||||||
|
contentPane.add(conversationPanel, BorderLayout.CENTER);
|
||||||
|
setContentPane(contentPane);
|
||||||
|
|
||||||
|
addComponentListener(new ComponentAdapter() {
|
||||||
|
public void componentResized(ComponentEvent componentEvent) {
|
||||||
|
conversationPanel.calculateOffsetToShowLastMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void addMessage() {
|
||||||
|
//panel.setImage("image1.jpg");
|
||||||
|
//panel_1.setImage("image2.png");
|
||||||
|
if (textFieldMsg.getText().length()>0) {
|
||||||
|
messages.add(new Message(Color.RED,textFieldMsg.getText(),SwingConstants.RIGHT));
|
||||||
|
conversationPanel.repaint();
|
||||||
|
textFieldMsg.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void up(int x) {
|
||||||
|
conversationPanel.up(x);
|
||||||
|
conversationPanel.repaint();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void down(int x) {
|
||||||
|
conversationPanel.down(x);
|
||||||
|
conversationPanel.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
int y = e.getY();
|
||||||
|
if (y < previousY) {
|
||||||
|
if (Math.abs(previousY-y)<60)
|
||||||
|
up(Math.abs(previousY-y));
|
||||||
|
|
||||||
|
} else if (y > previousY) {
|
||||||
|
if (Math.abs(previousY-y)<60)
|
||||||
|
down(Math.abs(previousY-y));
|
||||||
|
}
|
||||||
|
previousY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package packageIHM;
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
|
||||||
|
public class Message {
|
||||||
|
|
||||||
|
private Color color;
|
||||||
|
private String message;
|
||||||
|
private int side;
|
||||||
|
private JTextArea bubble;
|
||||||
|
private int posY;
|
||||||
|
|
||||||
|
public Message(Color color, String message, int side) {
|
||||||
|
super();
|
||||||
|
this.color = color;
|
||||||
|
this.message = message;
|
||||||
|
this.side = side;
|
||||||
|
this.posY = -1;
|
||||||
|
bubble = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSide() {
|
||||||
|
return side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSide(int side) {
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JTextArea getBubble() {
|
||||||
|
return bubble;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBubble(JTextArea graphics) {
|
||||||
|
this.bubble = graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosY() {
|
||||||
|
return posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosY(int posY) {
|
||||||
|
this.posY = posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package packageIHM;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
import java.awt.event.MouseWheelListener;
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{
|
||||||
|
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e){
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseDragged(MouseEvent e){
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
redispatchToParent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void redispatchToParent(MouseEvent e){
|
||||||
|
Component source = (Component) e.getSource();
|
||||||
|
MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent());
|
||||||
|
source.getParent().dispatchEvent(parentEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
package packageIHM;
|
||||||
|
|
||||||
|
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.SwingConstants;
|
||||||
|
import javax.swing.border.AbstractBorder;
|
||||||
|
|
||||||
|
class TextBubble extends AbstractBorder {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private Color color;
|
||||||
|
private int thickness;
|
||||||
|
private int radius;
|
||||||
|
private int pointerSize = 0;
|
||||||
|
private Insets insets = null;
|
||||||
|
private BasicStroke stroke = null;
|
||||||
|
private int strokePad;
|
||||||
|
private double pointerPadPercent = 0.5;
|
||||||
|
int pointerSide = SwingConstants.TOP;
|
||||||
|
private RenderingHints hints;
|
||||||
|
|
||||||
|
|
||||||
|
TextBubble(Color color, int thickness, int radius, int pointerSize, int pointerSide) {
|
||||||
|
this.color = color;
|
||||||
|
this.thickness = thickness;
|
||||||
|
this.radius = radius;
|
||||||
|
this.pointerSize = pointerSize;
|
||||||
|
|
||||||
|
hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
insets = new Insets(0, 0, 0, 0);
|
||||||
|
this.pointerSide = pointerSide;
|
||||||
|
|
||||||
|
setThickness(thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TextBubble setThickness(int n) {
|
||||||
|
thickness = n < 0? 0: n;
|
||||||
|
|
||||||
|
stroke = new BasicStroke(thickness);
|
||||||
|
strokePad = thickness / 2;
|
||||||
|
|
||||||
|
setPointerSize(pointerSize);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextBubble setPointerSize(int size) {
|
||||||
|
int pad = radius/2 + strokePad;
|
||||||
|
|
||||||
|
int pointerSidePad = pad + pointerSize + strokePad;
|
||||||
|
int left, right, bottom, top;
|
||||||
|
left = right = bottom = top = pad;
|
||||||
|
switch (pointerSide) {
|
||||||
|
case SwingConstants.TOP:
|
||||||
|
top = pointerSidePad;
|
||||||
|
break;
|
||||||
|
case SwingConstants.LEFT:
|
||||||
|
left = pointerSidePad;
|
||||||
|
break;
|
||||||
|
case SwingConstants.RIGHT:
|
||||||
|
right = pointerSidePad;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case SwingConstants.BOTTOM:
|
||||||
|
bottom = pointerSidePad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
insets.set(top, left, bottom, right);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Insets getBorderInsets(Component c) {
|
||||||
|
return insets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||||
|
Color bg = new Color(color.getRed(), color.getGreen(), color.getBlue(), 125);
|
||||||
|
g.setColor(bg);
|
||||||
|
g.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
|
g2.setBackground(c.getBackground());
|
||||||
|
|
||||||
|
|
||||||
|
RoundRectangle2D.Double bubble;
|
||||||
|
Polygon pointer = new Polygon();
|
||||||
|
{
|
||||||
|
int rx, ry, rw, rh;
|
||||||
|
rx = ry = strokePad;
|
||||||
|
rw = width - thickness;
|
||||||
|
rh = height - thickness;
|
||||||
|
switch (pointerSide) {
|
||||||
|
case SwingConstants.LEFT:
|
||||||
|
rx += pointerSize;
|
||||||
|
case SwingConstants.RIGHT:
|
||||||
|
rw -= pointerSize;
|
||||||
|
break;
|
||||||
|
case SwingConstants.TOP:
|
||||||
|
ry += pointerSize;
|
||||||
|
case SwingConstants.BOTTOM:
|
||||||
|
default:
|
||||||
|
rh -= pointerSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bubble = new RoundRectangle2D.Double(rx,ry,rw,rh,radius, radius);
|
||||||
|
int pointerPad;
|
||||||
|
if (pointerSide == SwingConstants.LEFT || pointerSide == SwingConstants.RIGHT) {
|
||||||
|
pointerPad = (int) (pointerPadPercent * (height-radius*2-pointerSize));
|
||||||
|
} else {
|
||||||
|
pointerPad = (int) (pointerPadPercent * (width-radius*2-pointerSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
int basePad = strokePad + radius + pointerPad;
|
||||||
|
switch (pointerSide) {
|
||||||
|
case SwingConstants.LEFT:
|
||||||
|
pointer.addPoint(rx, basePad);// top
|
||||||
|
pointer.addPoint(rx, basePad+pointerSize);// bottom
|
||||||
|
pointer.addPoint(strokePad, basePad+pointerSize/2);
|
||||||
|
break;
|
||||||
|
case SwingConstants.RIGHT:
|
||||||
|
pointer.addPoint(rw, basePad);// top
|
||||||
|
pointer.addPoint(rw, basePad+pointerSize);// bottom
|
||||||
|
pointer.addPoint(width-strokePad, basePad+pointerSize/2);
|
||||||
|
break;
|
||||||
|
case SwingConstants.TOP:
|
||||||
|
pointer.addPoint(basePad, ry);// left
|
||||||
|
pointer.addPoint(basePad + pointerSize, ry);// right
|
||||||
|
pointer.addPoint(basePad + (pointerSize / 2), strokePad);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case SwingConstants.BOTTOM:
|
||||||
|
pointer.addPoint(basePad, rh);// left
|
||||||
|
pointer.addPoint(basePad + pointerSize, rh);// right
|
||||||
|
pointer.addPoint(basePad + (pointerSize / 2), height - strokePad);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Area area = new Area(bubble);
|
||||||
|
area.add(new Area(pointer));
|
||||||
|
g2.setRenderingHints(hints);
|
||||||
|
Area spareSpace = new Area(new Rectangle(0, 0, width, height));
|
||||||
|
spareSpace.subtract(area);
|
||||||
|
g2.setClip(spareSpace);
|
||||||
|
g2.clearRect(0, 0, width, height);
|
||||||
|
g2.setClip(null);
|
||||||
|
g2.setColor(color);
|
||||||
|
g2.setStroke(stroke);
|
||||||
|
g2.draw(area);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue