2011-12-11 31 views
6

Mục tiêu cuối cùng của tôi là có một hình ảnh nền JTextArea. Tôi tìm thấy mã trực tuyến cho thấy tôi làm thế nào để làm điều này, nhưng bây giờ tôi đang có một vấn đề với văn bản được trên đầu trang của hình ảnh.Đệm nội bộ cho JTextArea với nền Hình ảnh

này phải là những gì tôi muốn nói:

Text overlapping image

Có cách nào tôi có thể thêm một loại thụt vào bên trong để các văn bản không chồng lấn lên các cạnh của hình ảnh?


Đây là hình ảnh bong bóng nhận xét thô.

Comment bubble


Đây là mã:

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

    } 
} 
+0

Dưới đây là hình ảnh cho chat1: https://lh4.googleusercontent.com/-uhDR71VGYfA /TuRNiM2DfOI/AAAAAAAAADU/DqOuEi8c3lg/s334/chat1.jpg – user1091968

+1

1) Tại sao một 'JTextArea' (trái ngược với một' JLabel' hoặc thành phần syled khác)? 2) Tôi nghĩ rằng điều này tốt nhất nên được thực hiện với một ** tùy chỉnh biên giới **, một 'CommentBubbleBorder'. 3) Các thành phần Swing nên ghi đè 'paintComponent (Graphics)', thay vì 'paint (Graphics)'. –

+0

Không phải là lúc bạn chọn câu trả lời cho một số câu hỏi trước đó của bạn (http://stackoverflow.com/users/1091968/user1091968?tab=questions)? –

Trả lời

1

To post code, indent mỗi dòng bốn chỗ.

Tôi giả sử bạn đang ghi đè paintComponent() * cho số JTextArea của mình. Nếu bạn đang có, chắc chắn rằng nó là minh bạch bằng cách thêm

setOpaque(false); 

* Đây cũng hoạt động nếu bạn ghi đè paint(), nhưng như trashgod khẳng định một cách chính xác, điều đó sẽ gây trở ngại cho paintBorder().

+0

"Chương trình Swing nên ghi đè' paintComponent() 'thay vì ghi đè' paint() '." - [Vẽ trong AWT và Swing: Phương pháp vẽ] (http://java.sun.com/products/jfc/tsc/ bài viết/painting/index.html # callbacks). – trashgod

+1

@trashgod Cảm ơn, tôi không biết điều đó. Đã chỉnh sửa. –

6

Bạn nên sử dụng một Border cho rằng, specifictly hơn bạn nên sử dụng BorderFactory.createEmptyBorder(int top, int left, int bottom, int right):

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

Bạn cũng nên ghi đè paintComponent thay vì paint. Ngoài ra, hãy sử dụng setRows()setColumns() để đặt kích thước của văn bảnArea, sau đó bạn có thể sử dụng pack() thay vì setSize(400,400) không được khuyến nghị. Xem ví dụ sau:

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

} 
+1

Ví dụ điển hình, nhưng tôi vẫn nghĩ rằng [biên giới tùy chỉnh] (http://stackoverflow.com/a/8463742/418556) là cách để thực hiện điều này. ;) –

+0

@AndrewThompson: Bạn nói đúng. Nó phụ thuộc vào bao nhiêu thay đổi mà anh ta muốn làm. Điều này sửa chữa dòng duy nhất có thể giúp đỡ, nhưng không phải là giải pháp tốt nhất. 1 cho giải pháp của bạn. – Jonas

+0

+1. giải pháp dễ dàng nhất cho những người sử dụng được Graphics thách thức :) – camickr

12

Sử dụng một tuỳ chỉnh biên giới kéo dài AbstractBorder. Một cái gì đó như thế này:

Text Bubble Border

Lấy chính xác hình dạng & màu là trái như một bài tập cho người đọc. :)

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

+1, đường viền mát mẻ. – camickr

+0

Cảm ơn bạn! Một vài câu hỏi: Bong bóng "i" nhỏ để lại là gì? Phần nào của mã này có thể được chỉnh sửa để các từ sẽ quấn quanh thay vì kéo dài vùng văn bản? "để bong bóng trò chuyện bắt nguồn từ bên phải? Mục tiêu tổng thể của tôi là mô phỏng chế độ xem cuộc trò chuyện để trò chuyện. – user1091968

+0

Xem thêm thông tin. (Và câu hỏi lặp lại) trong chỉnh sửa để trả lời. –

Các vấn đề liên quan