Internal padding for JTextArea with background Image

前端 未结 4 1843
既然无缘
既然无缘 2020-11-27 20:37

My ultimate goal is to have a JTextArea with a background image. I found code online that showed me how to do this, but now I\'m having an issue with the text b

相关标签:
4条回答
  • 2020-11-27 21:01

    You should use an Border for that, more specifictly you should use BorderFactory.createEmptyBorder(int top, int left, int bottom, int right):

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

    You should also override paintComponent instead of paint. Also, use setRows() and setColumns() to set the size of the textArea, then you can use pack() instead of setSize(400,400) which is not recommended. See this example:

    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();
        }
    
    }
    
    0 讨论(0)
  • 2020-11-27 21:15

    Use a custom border that extends AbstractBorder. Something like this:

    Text Bubble Border

    Getting the exact shape & color is left as an exercise for the reader. :)

    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);
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-11-27 21:17

    A better version of TextBubbleBorder.

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

    • pointer padding control
    • pointer side control
    • dynamic change
    0 讨论(0)
  • 2020-11-27 21:22

    To post code, indent every line by four spaces.

    I assume you are overriding paintComponent()* for your JTextArea. If you are, make sure that it is transparent by adding

    setOpaque(false);
    

    *This also works if you override paint(), but as trashgod correctly states, that would interfere with paintBorder().

    0 讨论(0)
提交回复
热议问题