带有背景图像的JTextArea的内部填充

时间:2011-12-11 06:48:06

标签: java swing border jtextarea

我的最终目标是拥有一张带有背景图片的JTextArea。我发现在线代码向我展示了如何做到这一点,但现在我遇到了问题,文本位于图像之上。

这就是我的意思:

Text overlapping image

有什么方法可以添加一种向内缩进,以便文本不会与图像的边缘重叠?


这是原始评论气泡图片。

Comment bubble


以下是代码:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.GrayFilter;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class myBackgroundSample {

    String file;

    public myBackgroundSample(String i) {
        file = i;
        setItUp();
    }

    public void setItUp() {
        final ImageIcon imageIcon = new ImageIcon(file);
        JTextArea textArea = new JTextArea() {
            Image image = imageIcon.getImage();

            public void paint(Graphics g) {
                setOpaque(false);
                g.drawImage(image, 0, 0, this);
                super.paint(g);
            }
        };
        JFrame frame = new JFrame("Background Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane scrollPane = new JScrollPane(textArea);
        Container content = frame.getContentPane();
        content.add(scrollPane, BorderLayout.CENTER);
        frame.setSize(400, 400);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String right = "chat1.jpg";
        myBackgroundSample temp = new myBackgroundSample(right);

    }
}

4 个答案:

答案 0 :(得分:12)

使用扩展AbstractBorder的自定义边框。像这样:

Text Bubble Border

获得确切的形状&颜色留给读者练习。 :)

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
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;
    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);
    }

    @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();

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

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JLabel l = new JLabel(
                    "The quick brown fox jumped over the lazy dog!");

                l.setBorder(new TextBubbleBorder(Color.MAGENTA.darker(),2,4,0));
                l.setOpaque(true);
                l.setBackground(Color.BLACK);
                JOptionPane.showMessageDialog(null, l);
            }
        });
    }
}

答案 1 :(得分:6)

您应该使用Border,更具体地说,您应该使用BorderFactory.createEmptyBorder(int top, int left, int bottom, int right)

textArea.setBorder(BorderFactory.createEmptyBorder(10,10,15,10));

您还应该覆盖paintComponent而不是paint。此外,使用setRows()setColumns()设置textArea的大小,然后您可以使用pack()而不是setSize(400,400),这是不推荐的。见这个例子:

enter image description here

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;


public class Test extends JFrame {

    class MyTextArea extends JTextArea {

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setColor(Color.PINK);
            g2.setStroke(new BasicStroke(4));
            g2.drawRoundRect(3, 3, getWidth()-7, getHeight()-7, 5, 5);
        }

    }

    public Test() {
        JPanel panel = new JPanel(new BorderLayout());
        JTextArea textArea = new MyTextArea();
        textArea.setRows(3);
        textArea.setColumns(25);
        textArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        panel.add(textArea, BorderLayout.NORTH);

        add(panel);
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Test();
    }

}

答案 2 :(得分:1)

To post code,每行缩进四个空格。

我认为你的paintComponent()覆盖了JTextArea *。如果是,请通过添加

确保它是透明的
setOpaque(false);

*如果您覆盖paint(),这也有效,但正如垃圾邮件正确说明那样会干扰paintBorder()

答案 3 :(得分:0)

TextBubbleBorder的更好版本。

https://gist.github.com/wenerme/6940534

  • 指针填充控件
  • 指针侧控制
  • 动态变化