# JTextArea background Transparent geht nicht



## Samuel (27. Jun 2006)

Wir haben ein JTextArea mit ner JScrollPane, es klappt auch wunderbar, Scrollbalken sind da, wenn sie gebraucht werden.
Aber wir würden gerne den Background des Textfelds transparent machen.

textfeld.setOpqaue(false); geht seit dem wir ScrollPane dabei haben, nicht mehr, ebenfalls geht es nicht, wenn textfeld und scrollpane.setOpaque(false); haben.

Wir kommen beim besten willen nicht dahiner, wie man es transparent kriegt, der Hintergrund ist eine Grafik, daher kann man nicht einfach irgendeine Farbe als Background definieren.

Hier der Code

```
nachricht = new JTextArea("tetetet"); 
           nachricht.setOpaque(false); 
           nachricht.setWrapStyleWord(true); 
           nachricht.setLineWrap(true); 
           nachricht.setForeground(Color.red); 
           
            
           JScrollPane p= new JScrollPane(nachricht); 
           p.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
           p.setBounds(70, 479, 278, 111); 
           p.setOpaque(false); 
           add(p,0);
```


----------



## Gast (27. Jun 2006)

Hallo,

man muss den Viewport ders ScrollPane transparent setzen.


----------



## Samuel (27. Jun 2006)

Die JTextArea ist doch der Viewport oder nicht? Und der ist doch da oben opaque false


----------



## André Uhres (27. Jun 2006)

Ich bin nicht sicher ob es dir hilft. Ich stell's einfach mal hier rein:

```
//package text;
/*
 * TransparentTextarea2.java
 */
import java.awt.*;
import java.net.*;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.JTextComponent;
public class TransparentTextarea2 extends JFrame {
    public TransparentTextarea2() {
        super("Transparent Textarea");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400,300);
        setLocationRelativeTo(null);
        nachricht = new JTextArea("tetetet"){
            ImageIcon image = null;{
                try {image = new ImageIcon(new URL(
                        "http://www.feebleminds-gifs.com/emerald-butterfly.jpg" ));
                } catch (MalformedURLException e) {e.printStackTrace();}
            }
            public void paint( Graphics g ) {
                // Zuerst die Hintergrundgrafik zeichnen - tiled:
                Dimension d = getSize();
                for( int x = 0; x < d.width; x += image.getIconWidth() )
                    for( int y = 0; y < d.height; y += image.getIconHeight() )
                        g.drawImage( image.getImage(), x, y, null, null );
                // Nun lassen wir den regulären Code arbeiten:
                super.paint(g);
            }
        };
        nachricht.setOpaque(false);
        nachricht.setWrapStyleWord(true);
        nachricht.setLineWrap(true);
        nachricht.setForeground(Color.red);
        nachricht.setCaret(new FancyCaret());
        JScrollPane p= new JScrollPane(nachricht);
        p.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        p.setBounds(70, 479, 278, 111);
        add(p,0);
    }
    public static void main(String args[]) {new TransparentTextarea2().setVisible(true);}
    private JTextArea nachricht;
}
class FancyCaret extends DefaultCaret {
    protected synchronized void damage(Rectangle r) {
        if (r == null) return;
        x = r.x;
        y = r.y;
        height = r.height;
        if (width <= 0)  width = getComponent().getWidth();
        repaint();
    }
    public void paint(Graphics g) {
        JTextComponent comp = getComponent();
        if (comp == null) return;
        int dot = getDot();
        Rectangle r = null;
        char dotChar;
        try {
            r = comp.modelToView(dot);
            if (r == null) return;
            dotChar = comp.getText(dot, 1).charAt(0);
        } catch (BadLocationException e) { return;}
        if ((x != r.x) || (y != r.y)) {
            repaint();
            y = r.y;
            height = r.height;
        }
        g.setColor(comp.getCaretColor());
        g.setXORMode(comp.getBackground());
        if (dotChar == '\n') {
            int diam = r.height;
            if (isVisible()) g.fillArc(r.x - diam / 2, r.y, diam, diam, 270, 180);
            width = diam / 2 + 2;
            return;
        }
        if (dotChar == '\t')
            try {
                Rectangle nextr = comp.modelToView(dot + 1);
                if ((r.y == nextr.y) && (r.x < nextr.x)) {
                    width = nextr.x - r.x;
                    if (isVisible()) g.fillRoundRect(r.x, r.y, width, r.height, 12, 12);
                    return;
                } else dotChar = ' ';
            } catch (BadLocationException e) {dotChar = ' ';}
        width = g.getFontMetrics().charWidth(dotChar);
        if (isVisible()) g.fillRect(r.x, r.y, width, r.height);
    }
}
```


----------



## Samuel (27. Jun 2006)

Hm, in der Tat scheint es mir nicht zu helfen.
Was tust du da? Malst du ein Bild auf den Hintergrund von einem Textffeld (i.A. ) würde ich gerne darauf verzichten 

Ist das Problem denn bekannt? Und gibt es Lösungen dafür?

Danke für die Mühe 

Edit: Simulierst du ein Textfeld?


----------



## André Uhres (27. Jun 2006)

Samuel hat gesagt.:
			
		

> ..Simulierst du ein Textfeld?


Das Beispiel überschreibt lediglich die paint Methode der JTextArea um zuerst die Grafik als
Hintergrund zu zeichnen bevor dann mit super.paint() der Standard Code aufgerufen wird.
Durch nachricht.setOpaque(false) kann man dann einfach über die Grafik schreiben.
Die Klasse FancyCaret gehört eigentlich nicht direkt dazu. Sie dient nur dazu den Caret 
vor einem besonderen Hintergrund besser sichtbar zu machen.
Es geht aber auch so:

```
//package tabledemo;
import java.awt.*;
import java.net.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class TextBackground_Demo extends JFrame {
    public TextBackground_Demo() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        try{
            URL url = new URL("http://www.feebleminds-gifs.com/emerald-butterfly.jpg");
            image = ImageIO.read(url);
        }catch(Exception ex){
            ex.printStackTrace();
        }
        scrollpane = new JScrollPane();
        scrollpane.setViewportBorder( new CentredBackgroundBorder() );
        scrollpane.getViewport().setOpaque(false);
        textarea = new JTextArea();
        textarea.setOpaque(false);
        textarea.setForeground(Color.red);
        scrollpane.setViewportView(textarea);
        getContentPane().add(scrollpane, BorderLayout.CENTER);
        setSize(600,400);
        setLocationRelativeTo(null);
    }
    public static void main(String args[]) { new TextBackground_Demo().setVisible(true); }
    private Image image ;
    private JScrollPane scrollpane;
    private JTextArea textarea;
    class CentredBackgroundBorder extends javax.swing.border.AbstractBorder {
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            x += (width-image.getWidth(null))/2;
            y += (height-image.getHeight(null))/2;
            ((Graphics2D) g).drawRenderedImage((java.awt.image.RenderedImage)image,
                    java.awt.geom.AffineTransform.getTranslateInstance(x,y));
        }
    }
}
```


----------



## Samuel (27. Jun 2006)

Danke 
Damit willst du mir also sagen, dass man Textfelder mit Scrollboxen nicht so einfach transparent setzen kann, richtig?
Gibt es einen Grund, warum opaque nicht geht?


----------



## André Uhres (28. Jun 2006)

Samuel hat gesagt.:
			
		

> Damit willst du mir also sagen, dass man Textfelder mit Scrollboxen nicht so einfach transparent setzen kann, richtig?..


Achso, ich glaube ich hab da was falsch verstanden. Das geht natürlich auch.
Wie Gast schon sagte, einfach p.getViewport().setOpaque(false):

```
//package paint;
/*
 * TextHintergrund.java
 */
import java.awt.*; 
import java.awt.image.*;
import java.net.*; 
import javax.imageio.*; 
import javax.swing.*; 
public class TextHintergrund extends JFrame { 
    public TextHintergrund() { 
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
        imagePanel = new ImagePanel();
        try{
            image = javax.imageio.ImageIO.read( new java.net.URL(IMAGE_URL) );
            imagePanel.setPreferredSize( new Dimension(image.getWidth(),image.getHeight()) );
            System.out.println("image.getHeight(): "+image.getHeight());
        }catch(java.io.IOException ex){
            setTitle("Image Error: "+ex.getMessage());
        }
        imagePanel.setLayout(null);
        JTextArea nachricht = new JTextArea("tetetet");
        nachricht.setOpaque(false);
        nachricht.setWrapStyleWord(true);
        nachricht.setLineWrap(true);
        nachricht.setForeground(Color.red);
        JScrollPane p= new JScrollPane(nachricht);
        p.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        p.setBounds(70, 40, 278, 111);
        p.setOpaque(false);
        p.getViewport().setOpaque(false);
        imagePanel.add(p);
        getContentPane().add(imagePanel, BorderLayout.CENTER); 
        setSize(600,400); 
        setLocationRelativeTo(null); 
    } 
    public static void main(String args[]) { new TextHintergrund().setVisible(true); } 
    private ImagePanel imagePanel;
    private BufferedImage image;
    private final String IMAGE_URL = "http://www.feebleminds-gifs.com/emerald-butterfly.jpg";
    class ImagePanel extends JPanel{
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image,0,0,null);
        }
    }
}
```


----------



## Samuel (28. Jun 2006)

Seltsam, das war genau das, was ich gemacht habe, werde es morgen testen und hier bescheid geben, aber wie gesagt, ich meine, es ging nicht.

Danke und bis naja "morgen"


----------



## Samuel (28. Jun 2006)

Hallo,
so sieht der code davon aus:


```
JLabel label = new JLabel();
		label.setBounds(0, 0, 800, 600);
		label.setIcon(new ImageIcon("bilder\\Interface_JAVA.png"));
		// label.setComponentZOrder(this,10);
		add(label);

		nachricht = new JTextArea("Nachricht");
		// nachricht.setBounds(70, 479, 278, 111);
		// nachricht.setOpaque(false);
		nachricht.setWrapStyleWord(true);
		nachricht.setLineWrap(true);
		nachricht.setForeground(Color.red);
		// add(nachricht,0);

		JScrollPane p = new JScrollPane(nachricht);
		p.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		p.setBounds(70, 479, 278, 111);
		p.setOpaque(false);
		p.getViewport().setOpaque(false);
		add(p, 0);
```

Also letzte Zeile ist das ViewPort Teil und es wird leider nicht transparent


----------



## André Uhres (28. Jun 2006)

nachricht.setOpaque(false); muss auch sein


----------



## Samuel (28. Jun 2006)

Aah, geht.

Danke


----------



## Samuel (29. Jun 2006)

Weiter gehts, wie krieg ich das Border vom ScrollText weg?
setBorder(null) geht nicht, oder muss ich das von Scroller und vom Text machen?


----------



## André Uhres (30. Jun 2006)

Samuel hat gesagt.:
			
		

> Weiter gehts, wie krieg ich das Border vom ScrollText weg?
> setBorder(null) geht nicht, oder muss ich das von Scroller und vom Text machen?


Vom JScrollPane.


----------



## Samuel (30. Jun 2006)

Ach mensch, warum funktioniert es erst dann, nachdem man mir es nochmal im Forum sagt.
Ich hab genau das gleiche getan, die IDee mit Scrollpane kam sogar vor dem Textfeld, aber war nicht.
Nun geht es.
Zum Haare raufen.

Danke!


----------



## Samuel (1. Jul 2006)

Naja, tour de force geht weiter.
Bei einer JTextAre kann man ja mit setForeground die Farbe ändern, aber kann man selektiv für Stellen im Text die Farbe ändern?


----------



## André Uhres (1. Jul 2006)

Samuel hat gesagt.:
			
		

> ..Bei einer JTextAre kann man ja mit setForeground die Farbe ändern, aber kann man selektiv für Stellen im Text die Farbe ändern?


http://javaalmanac.com/egs/javax.swing.text/style_HiliteWords.html   (eigentlich nur Background !)
http://javaalmanac.com/egs/javax.swing.text/style_HiliteWords2.html  (nur für JTextPane/JEditorPane)


----------



## Samuel (1. Jul 2006)

Ah, es geht darum einen Text zu selektieren und ihm einen style zu verpassen, richtig?

Es geht also nicht, dass man sagt "so ab jetzt nur rot" , append text der auch rot wird und dann sagt man "so wieder schwarz"

Man muss also text einfügen, selektieren und "stylen"


----------



## André Uhres (1. Jul 2006)

Mit JTextArea kannst du eh nicht stylen, da kannst du nur mit einem Highlighter den Background hervorheben.

Mit JEditorPane kannst du aber richtig stylen.
Es geht auch so wie du willst, dass man sagt "so ab jetzt nur rot" , append text der auch rot wird 
und dann sagt man "so wieder schwarz":

```
//package text;
/*
 * ColorText2.java
 */
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class ColorText2 extends JFrame {
    private JEditorPane editorPane;
    private Document doc;
    private MutableAttributeSet black;
    private MutableAttributeSet red;
    private AttributeSet attribute;
    public ColorText2() {
        super("Color Text");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);
        editorPane = new JEditorPane();
        getContentPane().add(new JScrollPane(editorPane), BorderLayout.CENTER);
        black = new SimpleAttributeSet();
        StyleConstants.setForeground(black, Color.black);
        red = new SimpleAttributeSet();
        StyleConstants.setForeground(red, Color.red);
        editorPane.setEditorKit(new StyledEditorKit());
        doc = editorPane.getDocument();
        append("This ");
        //ab jetzt nur rot:
        attribute = red;
        append("method");
        append(" is called");
        //wieder schwarz:
        attribute = black;
        append(" from within the constructor");
        append(" to\n initialize the form.");
    }
    private void append(String text){
        try {
            doc.insertString(doc.getLength(), text, attribute);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }
    public static void main(String args[]) {new ColorText2().setVisible(true);}
}
```


----------



## André Uhres (1. Jul 2006)

Upps, wollte eigentlich neuen Beitrag machen, statt dessen hab ich den vorigen editiert: siehe dort


----------



## keman (12. Dez 2006)

Ich hatte irgendwie ein ähnliches Problem, ich will eine JTextPane mit Hintergrundsbild. Dies funktioniert jedoch nicht (das Hintergrundsbild wird nicht angezeigt):


```
JLabel label = new JLabel();
        label.setIcon(new ImageIcon("images/background1.jpg"));
        label.setOpaque(false);
//scroller ist eine JScrollPane, die die JTextPane pane enthält
        pane.setOpaque(false);
        scroller.setOpaque(false);
        scroller.getViewport().setOpaque(false);
        // c ist ein Container mit BorderLayout
        c.add(label);
        c.add(scroller);
```

Kann mir da jemand helfen?


----------



## Wildcard (12. Dez 2006)

Borderlayout kann nur eine Komponente pro Bereich verwalten. Kann also nicht gehen.


----------



## keman (12. Dez 2006)

Ok, aber dies funktioniert auch nicht wirklich:


```
JPanel medium = new JPanel();
		medium.setLayout(null);
		
        JLabel label = new JLabel();
        label.setIcon(new ImageIcon("images/background1.jpg"));
        label.setOpaque(false);
        pane.setOpaque(false);
        scroller.setOpaque(false);
        scroller.getViewport().setOpaque(false);
        
        label.setBounds(0,0,1000,1000);
        scroller.setBounds(0,0,1000,1000);
        
        medium.add(label);
        medium.add(scroller);
        
        c.add(medium);
```


----------



## André Uhres (13. Dez 2006)

keman hat gesagt.:
			
		

> Ok, aber dies funktioniert auch nicht wirklich..


Vesuch mal das Bild mit drawImage/drawRenderedImage zu zeichnen (Beispiele oben).


----------

