2011-12-11 7 views
6

私の最終的な目標は、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); 

    } 
} 
+0

はchat1ための画像である。 https://lh4.googleusercontent.com/-uhDR71VGYfA /TuRNiM2DfOI/AAAAAAAAADU/DqOuEi8c3lg/s334/chat1.jpg – user1091968

+1

1) 'JTextArea'(なぜなら' JLabel'や他のsyledコンポーネントとは対照的です)ですか? 2)これは、**カスタム**ボーダーである「CommentBubbleBorder」でもっともうまくいくと思います。 3)Swingコンポーネントは 'paint(Graphics)'ではなく 'paintComponent(Graphics)'をオーバーライドする必要があります。 –

+0

あなたの[以前の質問](http://stackoverflow.com/users/1091968/user1091968?tab=questions)の回答を選択する時間はありませんか? –

答えて

1

To post code、4つのスペースですべての行をインデントが。

JTextAreaの場合はpaintComponent() *を上書きしているものとします。あなたがいる場合は、*それは

setOpaque(false); 

を追加することにより、透明であることを確認してくださいあなたはpaint()を上書きする場合にも動作しますが、trashgodは正しくpaintBorder()を妨害すること、を述べて。

+0

"Swingプログラムは' paint() 'をオーバーライドするのではなく' paintComponent() 'をオーバーライドする必要があります。" - [AWTとSwingのペイント:ペイントメソッド](http://java.sun.com/products/jfc/tsc/ articles/painting/index.html#コールバック)。 – trashgod

+1

@trashgodありがとう、私はそれを知らなかった。編集されました。 –

6

あなたはより多くのspecifictlyあなたがBorderFactory.createEmptyBorder(int top, int left, int bottom, int right)を使用する必要があり、そのためのBorderを使用する必要があります。

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

ます。またpaintComponent代わりのpaintをオーバーライドする必要があります。また、setRows()setColumns()を使用してtextAreaのサイズを設定すると、setSize(400,400)ではなくpack()を使用できますが、これはお勧めできません。この例を参照してください:

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

良い例ですが、私はまだ[カスタム境界](http://stackoverflow.com/a/8463742/418556)がこれに進む方法だと思います。 ;) –

+0

@AndrewThompson:そうです。彼はどのくらいの変更をしたいのかによって異なります。この1行の修正は役に立ちますが、最適な解決策にはなりません。あなたの解決策は+1です。 – Jonas

+0

+1。グラフィックスに挑戦している人のための最も簡単な解決策:) – camickr

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

+1、クールボーダー。 – camickr

+0

ありがとう!いくつかの質問: 少し "私"のバブルは残っていますか? このコードのどの部分を編集して、テキスト領域を引き伸ばす代わりに単語が折り返されるようにすることができますか? 私の全体的な目標は、チャットの会話画面をシミュレートすることです。 – user1091968

+0

さらに詳しい情報を参照してください(繰り返し質問)ので、回答を編集してください。 –