hintergrundbild für jtable als jscrollpane

Flaming_Ace

Mitglied
Hi,
habe folgendes Problem:
ich hab eine jtable die auf einem jscrollpane liegt. jetzt wollte ich ein hintergrundbild einfügen.
Da die Tabellenzeilen das bild nach und nach (je nachdem wieviel zeilen es gibt) verdecken soll, habe
ich das bild durch die methode paint der klasse jscrollpane eingefügt:
Java:
public class TableScrollPaneBackground extends JScrollPane{
	// The Image to store the background image in.
    Image img;
    Frm_Main main;
    public TableScrollPaneBackground(Frm_Main main)
    {
        // Loads the background image and stores in img object.
        img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("/grafiken/Logo.png"));
        this.main = main;
    }

    public void paint(Graphics g)
    {
        // Draws the img to the BackgroundPanel.
    	Dimension d = getSize();
		for( int x = 0; x < d.width; x += img.getWidth(null))
			for( int y = 0; y < d.height; y += img.getHeight(null) )
				g.drawImage( img, x, y, null, null );
//        super.paint(g);//dann geht nichts mehr
//        this.main.validate();//bringt nix
    }
}

die jtable füge ich dann auf das jscrollpane hinzu:
Java:
scrollPane = new TableScrollPaneBackground(this);
scrollPane.setViewportView(getTableMain());//getTableMain() erstellt eine neue Tabelle

Das Bild wird gezeichnet, aber die Tabelle wird zu beginn nicht angezeigt. erst wenn man auf ihr herumklickt.:autsch:
und dabei auch nur die entsprechenden zeilen..
die Scrollbalken werden auch nicht korrekt angezeigt.

hat jemand ne lösung :rtfm: oder eine alternative? danke im vorraus..
 

Michael...

Top Contributor
Mal abgesehen davon, dass man bei Swingkomponenten paintComponent anstelle von paint überschreibt, würde ich mich hüten sowas bei JScrollPane zu machen. JScrollPane ist doch eine relativ komplexe Komponente.
Ich würde ein Überschreiben des Viewports (denn da soll schliesslich das Bild erscheinen) bevorzugen.
Wobei ich mir sicher bin, ob folgendes Bsp nicht doch irgendwie Probleme verursachen kann.
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;

public class ScrollBackgroundDemo extends JFrame {
	private BufferedImage image;
	public ScrollBackgroundDemo() {	
		JTable table = new JTable(new Object[][] {{"Test"}, {"Test"}}, new String[] {"Titel"});
		image = ScrollBackgroundDemo.createImage();
		JScrollPane scroll = new JScrollPane();
		JViewport view = new JViewport() {
			public void paintComponent(Graphics g) {
				g.drawImage(image, 0, 0, this);
			}
		};
		view.add(table);
		scroll.setViewport(view);
		this.getContentPane().add(scroll);
	}
	
	public static BufferedImage createImage() {
		BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = image.createGraphics();
		g.setColor(Color.RED);
		g.fillRect(20, 20, 160, 160);
		g.dispose();
		return image;
	}

	public static void main(String[] args) {
		JFrame frame = new ScrollBackgroundDemo();
		frame.setBounds(0, 0, 250, 150);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 

Flaming_Ace

Mitglied
viewport oder scrollpane ergeben keine änderung.
jedoch weiß ich jetzt warum das scrollpane das bild nicht angezeigt hat. viewport ist default opaque:
deswegen habe ich folgende änderungen gemacht:
Java:
public class TableScrollPaneBackground extends JScrollPane{
    private Image img;
    private Dimension d;
    
    public TableScrollPaneBackground()
    {
    	img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("/grafiken/HintergrundTabelle.png"));//Bild laden

        getViewport().setOpaque(false);//den Viewport auf durchsichtig stellen

        Dimension dim = new Dimension(img.getHeight(null), img.getWidth(null));//Dimension des bildes holen
        setSize(dim);//panel an bild anpassen
    }

    @Override
    public void paintComponent(Graphics g)
    {
    		//Bildzeichnen
        	d = getSize();
    		for( int x = 0; x < d.width; x += img.getWidth(null))
    			for( int y = 0; y < d.height; y += img.getHeight(null) )//Kachel-Modus.. so dass kein leerer raum entsteht
    				g.drawImage( img, x, y, null );

		//Componenten über das Bildzeichnen
		super.paintComponents(g);
    }
}
die einbindung habe ich nicht geändert.
allerdings wird das bild beim ersten anzeigen des fensters nicht gezeigt, erst sobald man die fenstergröße ändert oder ein anderes fenster über das programm gezogen hat.
setze ich den ImageObserver auf "this".. wird das bild beim ersten laden zwar angezeigt, aber nicht korrekt, die komponenten "überlappen"..soll heißen man sieht die oberen komponenten (buttons, menü) nach unten gespiegelt.. ;(
 

Anhänge

  • Aufzeichnen.jpg
    Aufzeichnen.jpg
    48,3 KB · Aufrufe: 52
Zuletzt bearbeitet:

Michael...

Top Contributor
Mein Bsp. funktioniert doch. Warum orientierst Du Dich nicht daran?
Mit einer überschrieben paintComponent in der JScrollPane wirst Du vermutlich nie glücklich werden.
 

Flaming_Ace

Mitglied
ich habs auch mit einem viewport versucht, so wie in deinem beispiel.
dies hat allerdings keine änderungen ergeben, genau die gleichen effekte:
Java:
public class TableViewPort extends JViewport{
    
	private Image img;
    private Dimension d;
    
    public TableViewPort()
    {
    	img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("/grafiken/HintergrundTabelle.png"));//Bild laden
        Dimension dim = new Dimension(img.getHeight(null), img.getWidth(null));//Dimension des bildes holen
        setSize(dim);//viewport an bild anpassen
    }

    @Override
    public void paintComponent(Graphics g)
    {
    		//Bildzeichnen
        	d = getSize();
    		for( int x = 0; x < d.width; x += img.getWidth(this))
    			for( int y = 0; y < d.height; y += img.getHeight(this) )//Kachel-Modus.. so dass kein leerer raum entsteht
    				g.drawImage( img, x, y, this );
		//Componenten über das Bildzeichnen
		super.paintComponents(g);
    }
}
Die einbindung hab ich so gemacht:
Java:
TableViewPort view = new TableViewPort();//
view.add(getTableMain());//liefert die tabelle
scrollPane.setViewportView(view);//
wie gesagt: auch mit dieser variante habe ich die gleichen probleme.
außerdem wird dann der tabellenkopf nichtmehr angezeigt.

*update*
wenn ich das bild im viewport zeichne, entsteht der überlappen effekt "nur" bei ungefähr 50% aller programmstarts???:L:shock:
 
Zuletzt bearbeitet:

Michael...

Top Contributor
wieso rufst Du eigentlich paintComponents(g) auf? Das wird doch eh von der paint() der Komponente aufgerufen.

Hier mal ein Bsp. mit "gekacheltem" Hintergrund, bei mir wird alles - auch der Tabellenkopf - gezeichnet.
Poste vielleicht mal ein KSKB, damit man erkennen kann woran es liegen könnte.
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;

public class ScrollBackgroundDemo extends JFrame {
	private BufferedImage image;
	public ScrollBackgroundDemo() {	
		JTable table = new JTable(new Object[][] {{"Test"}, {"Test"}}, new String[] {"Titel"});
		image = ScrollBackgroundDemo.createImage();
		JScrollPane scroll = new JScrollPane();
		JViewport view = new JViewport() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				int w = image.getWidth(), h = image.getHeight();
				for (int x=0; x<this.getWidth(); x += w)
					for (int y=0; y<this.getHeight(); y += h)
						g.drawImage(image, x, y, this);
			}
		};
		view.add(table);
		scroll.setViewport(view);
		this.getContentPane().add(scroll);
	}
	
	public static BufferedImage createImage() {
		BufferedImage image = new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = image.createGraphics();
		g.setColor(Color.RED);
		g.fillRect(5, 5, 10, 10);
		g.dispose();
		return image;
	}

	public static void main(String[] args) {
		JFrame frame = new ScrollBackgroundDemo();
		frame.setBounds(0, 0, 250, 150);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 

Flaming_Ace

Mitglied
In Zeile 19 von ScrollBackgroundDemo rufst du doch auch super.paintComponents() auf..
allerdings am anfang der methode..
wenn ich diesen aufruf rausnehme hat es keine auswirkungen... ;(

ich habe gerade versucht ein JPanel mit einem hintergrundbild zu erstellen.
auf dieses panel habe ich dann das scrollPane und darauf dann durch viewport die tabelle.
das scrollpane und viewport habe ich auf opaque(false) gesetzt.

die anzeige funktioniert auch, jedoch habe ich wieder den überlappungseffekt. der hängt irgendwie mit ImageObserver zusammen.. wenn ich statt "this" "null" verwende habe ich den überlappungseffekt nicht, aber er zeichnete das bild in diesem fall auch ab und zu nicht.
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Ich rufe
Code:
super.paintComponent(g);
auf (ohne s), das ist ein kleiner aber feiner Unterschied ;-)
Läuft den mein Bsp. bei Dir? Ansonsten wie gesagt, wäre ein KSKB nicht schlecht.
 

Flaming_Ace

Mitglied
dein beispiel läuft einwandfrei!

und jetzt hab ich auch den fehler.. Ich habe paintComponent mit paintComponents verwechselt
:lol:

:applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus:

jetzt funktionieren alle 3 varianten (hintergrundbild im panel/viewport/scrollpane)

für alle, die nicht wissen, wo der unterschied zwischen den zeichenmethoden sind.
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 17 Grafikprogrammierung

Grundsätzlich ließe sich auch von JFrame eine Unterklasse bilden und paint() überschreiben, doch ist das nicht der übliche Weg.
Stattdessen wählen wir einen anderen Ansatz, der sogar unter AWT eine gute Lösung ist.
Wir bilden eine eigene Komponente, eine Unterklasse von JPanel (unter AWT Panel, was wir aber nicht mehr weiter verfolgen wollen),
und setzen diese auf das Fenster.
Wird das Fenster neu gezeichnet, gibt das Grafiksystem den Zeichenauftrag an die Kinder weiter,
also auf unser spezielles JPanel, und ruft die überschriebene paint()-Methode auf.
Allerdings überschreiben eigene Unterklassen von Swing-Komponenten im Regelfall nicht paint(), sondern paintComponent().
Das liegt daran, dass Swing in paint() zum Beispiel noch Rahmen zeichnet und sich um eine Pufferung des Bildschirminhalts zur Optimierung kümmert.
So ruft paint() die drei Methoden paintComponent(), paintBorder() und paintChildren() auf, und bei einer Neudarstellung kümmert sich ein RepaintManager
um eine zügige Darstellung mit Hilfe der gepufferten Inhalte, was bei normalen Swing-Interaktionskomponenten wie Schaltflächen wichtig ist.

Damit ist die Darstellung von Inhalten in einem JFrame einfach. Wir importieren drei Klassen, JPanel und JFrame aus javax.swing sowie Graphics aus java.awt. Dann bilden wir eine Unterklasse von JPanel und überschreiben paintComponent().

Die Methode paintComponent() besitzt in der Oberklasse die Sichtbarkeit protected, was wir beibehalten sollten;
die Methode wird nicht von uns von anderer Stelle aufgerufen, daher muss eine Unterklasse die Sichtbarkeit nicht zu public erweitern.
Der Aufruf von super.paintComponent() ist immer dann angebracht, wenn die Oberklasse ihre Inhalte zeichnen soll.
Bei vollständig eigenem Inhalt ist das nicht notwendig.


aus javadoc für paintComponents():
Paints each of the components in this container.

hier noch der korrekte code für das hintergrundBildPanel:
Java:
 public class TablePanelHintergrundbild extends JPanel{
    
	private Image img;
    private Dimension d;
    
    public TablePanelHintergrundbild()
    {
    	img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("/grafiken/HintergrundTabelle.png"));//Bild laden
        Dimension dim = new Dimension(img.getHeight(null), img.getWidth(null));//Dimension des bildes holen
        setSize(dim);//panel an bild anpassen
    }

    @Override
    protected void paintComponent(Graphics g)
    {
    	super.paintComponent(g);
    	//Bildzeichnen
        d = getSize();
    	for( int x = 0; x < d.width; x += img.getWidth(this))
    		for( int y = 0; y < d.height; y += img.getHeight(this) )//Kachel-Modus.. so dass kein leerer raum entsteht
    			g.drawImage( img, x, y, this );
    }
}
wie gesagt alle Elemente die darüber liegen auf opaque(false) stellen (das wären bei mir scrollPane und ViewPort)

Vielen vielen Dank an: Michael... !!!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Hintergrundbild für JFrame AWT, Swing, JavaFX & SWT 6
R 2D-Grafik Hintergrundbild für JFrame AWT, Swing, JavaFX & SWT 4
G Hintergrundbild für JPanel AWT, Swing, JavaFX & SWT 4
T Hintergrundbild einfügen AWT, Swing, JavaFX & SWT 1
L Hintergrundbild im Fenster darstellen AWT, Swing, JavaFX & SWT 9
R Java, GUI, Hintergrundbild, Image, AWT, Swing, JavaFX & SWT 4
H Hintergrundbild in einem Programm AWT, Swing, JavaFX & SWT 4
snipesss Hintergrundbild in JOptionPane.showInputDialog? AWT, Swing, JavaFX & SWT 4
M Hintergrundbild wird nicht angezeigt AWT, Swing, JavaFX & SWT 1
L [Slick2d] Sidescroller/Hintergrundbild sehr langsam AWT, Swing, JavaFX & SWT 3
O Vollbildmodus mit Hintergrundbild AWT, Swing, JavaFX & SWT 8
A jpanel mit gridbaglayout auf hintergrundbild AWT, Swing, JavaFX & SWT 7
Mr. Pink AWT Anzeigeproblem JPanel/Hintergrundbild AWT, Swing, JavaFX & SWT 1
H Swing Hintergrundbild in einen JFrame einfügen AWT, Swing, JavaFX & SWT 7
T Hintergrundbild in JTextPane fixieren AWT, Swing, JavaFX & SWT 2
M Auf einem Hintergrundbild zeichnen AWT, Swing, JavaFX & SWT 2
SexyPenny90 Hintergrundbild mit Swing AWT, Swing, JavaFX & SWT 3
C Eigenes Hintergrundbild einfügen AWT, Swing, JavaFX & SWT 6
P AWT Hintergrundbild in Hauptframe AWT, Swing, JavaFX & SWT 3
T 2D-Grafik Statisches Hintergrundbild, dynamische Bilder drüber AWT, Swing, JavaFX & SWT 2
F Hintergrundbild im Frame AWT, Swing, JavaFX & SWT 11
H Hintergrundbild in jTextArea AWT, Swing, JavaFX & SWT 4
N AWT Hintergrundbild AWT, Swing, JavaFX & SWT 2
E JButton mit hintergrundbild AWT, Swing, JavaFX & SWT 4
J Swing Hintergrundbild auf einem JFrame AWT, Swing, JavaFX & SWT 7
G Swing Komponenten dem Hintergrundbild des JPanels anpassen? AWT, Swing, JavaFX & SWT 6
B Wie ein Hintergrundbild einfügen??? AWT, Swing, JavaFX & SWT 18
I JPanel mit Hintergrundbild, setOpaque AWT, Swing, JavaFX & SWT 10
C Label Hintergrundbild mit Text AWT, Swing, JavaFX & SWT 6
S Applet - Aerger mit dem Hintergrundbild - JLabel und JTextfield AWT, Swing, JavaFX & SWT 7
J Hintergrundbild des JFrames lässt Textboxen verschwinden? AWT, Swing, JavaFX & SWT 4
H hintergrundbild fixieren AWT, Swing, JavaFX & SWT 3
N Swing Hintergrundbild in einer JScrollpane AWT, Swing, JavaFX & SWT 2
dl85hej Hintergrundbild AWT, Swing, JavaFX & SWT 2
C JPanel mit Hintergrundbild AWT, Swing, JavaFX & SWT 30
U JList mit Hintergrundbild hinterlegen und noch ne Frage AWT, Swing, JavaFX & SWT 4
C Hintergrundbild ohne Repaint AWT, Swing, JavaFX & SWT 9
G Jpanel mit Hintergrundbild füllen? AWT, Swing, JavaFX & SWT 6
G 2x JPanel im JScrollPane (Hintergrundbild in JScrollPane) AWT, Swing, JavaFX & SWT 9
E JPanel mit Hintergrundbild AWT, Swing, JavaFX & SWT 10
hdi panel hintergrundbild falsch implementiert ? AWT, Swing, JavaFX & SWT 9
Kidao Das Hintergrundbild überdeckt die Swing-Komponente AWT, Swing, JavaFX & SWT 5
C JdesktopPane Hintergrundbild AWT, Swing, JavaFX & SWT 6
N Hintergrundbild setzen AWT, Swing, JavaFX & SWT 4
L Frame mit Hintergrundbild? AWT, Swing, JavaFX & SWT 4
S JTextPane mit Hintergrundbild AWT, Swing, JavaFX & SWT 9
K Hintergrundbild an JFrame anpassen AWT, Swing, JavaFX & SWT 9
U bewegtes Hintergrundbild AWT, Swing, JavaFX & SWT 2
G Hintergrundbild auf JFrame oder JPanel AWT, Swing, JavaFX & SWT 3
F Text besser lesbar über Hintergrundbild AWT, Swing, JavaFX & SWT 6
S Hintergrundbild an Größe des JFrames anpassen AWT, Swing, JavaFX & SWT 4
G Problem mit Menü/Button auf Hintergrundbild AWT, Swing, JavaFX & SWT 10
D JTable - Hintergrundbild in Cell AWT, Swing, JavaFX & SWT 6
M Hintergrundbild und grafischer Button (Transparenz Probleme) AWT, Swing, JavaFX & SWT 3
H Hintergrundbild im Panel verschwindet sofort AWT, Swing, JavaFX & SWT 6
B Problem mit Hintergrundbild AWT, Swing, JavaFX & SWT 12
I Hintergrundbild bei awt container AWT, Swing, JavaFX & SWT 9
E hintergrundbild einfügen!! AWT, Swing, JavaFX & SWT 2
Juelin setzen background color für selected Row im Tableview AWT, Swing, JavaFX & SWT 20
Juelin Für Java-Spezialisten AWT, Swing, JavaFX & SWT 4
H JTabel - RowFilter Daten für Berechnung filtern AWT, Swing, JavaFX & SWT 6
I JavaFX JavaFx-Anwendung für die Erstellung einer Windows-Anwendung? AWT, Swing, JavaFX & SWT 6
M Eigene Java Klasse für allgemeine Grafikelemente AWT, Swing, JavaFX & SWT 8
M Vokabelprogram - Schleife für Liste soll schrittweise durchlaufen werden AWT, Swing, JavaFX & SWT 3
tommybalbor JavaFx Anwendung klappt nicht für macOs Nutzern, wenn ich zwei dependecies bei maven hinzufüge AWT, Swing, JavaFX & SWT 6
I Libraries für AWT für andere Grafik-Frameworks tauglich machen AWT, Swing, JavaFX & SWT 6
R auto. Importanweisungen für javafx funktioniert in Eclipse nicht mehr AWT, Swing, JavaFX & SWT 4
komplettlost Vollbildmodus für MacOs Nutzer geht nicht AWT, Swing, JavaFX & SWT 13
D JavaFX Schadensberechnung für Kartenspiel AWT, Swing, JavaFX & SWT 1
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
Jose05 JavaFX: eigene FXML-Datei für einen Button AWT, Swing, JavaFX & SWT 3
L actionListener für Button AWT, Swing, JavaFX & SWT 97
izoards Textfeld für Zeit AWT, Swing, JavaFX & SWT 4
CptK Wie funktioniert contains() für Path2D.Double AWT, Swing, JavaFX & SWT 10
T Getter und Setter für eine Stage AWT, Swing, JavaFX & SWT 6
P Swing Programm hängt sich bei Buttondruck auf? (GUI für "Chatbot" erstellen) AWT, Swing, JavaFX & SWT 15
T Button für GUI programmieren AWT, Swing, JavaFX & SWT 1
Z Switch Case für Buttons AWT, Swing, JavaFX & SWT 8
M Hough-Transformation für Kreise und andere Formen AWT, Swing, JavaFX & SWT 3
kodela HTML-tags für JLabel AWT, Swing, JavaFX & SWT 9
E Keystroke für Ausschneiden läßt sich nicht ändern AWT, Swing, JavaFX & SWT 2
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
MiMa Package Struktur für GUI Programmierung AWT, Swing, JavaFX & SWT 26
N JavaFX 1 Listener für mehrere ChoiceBoxen AWT, Swing, JavaFX & SWT 3
B eclipse für JavaFx setuppen AWT, Swing, JavaFX & SWT 4
K Swing Struktur für TreeTable rekursiv aufbauen AWT, Swing, JavaFX & SWT 17
A Swing JTextField an Button übergeben für Popup-Fenster funktioniert nicht AWT, Swing, JavaFX & SWT 3
H Ein Patten für das Gluon Mobile Framework AWT, Swing, JavaFX & SWT 7
J Gibt es einen Grund für 16x16 anstatt z.B. 15x15 Tiles ? AWT, Swing, JavaFX & SWT 10
F JFormattedTextField für kg und Währung AWT, Swing, JavaFX & SWT 6
V Swing für jedes Kästchen eine eigene Farbe AWT, Swing, JavaFX & SWT 2
F Wie bekomme ich den Wert der ComboBox in eine Variable gespeichert welche ich für meinen ActionListener nutzen kann? AWT, Swing, JavaFX & SWT 3
Soloeco JavaFX Dreifachklick für MenuButton erforderlich AWT, Swing, JavaFX & SWT 2
L JavaFX Lösungsvorschläge für dieses coole Control AWT, Swing, JavaFX & SWT 8
looparda Suche Lib für Visualisierung von Graphen AWT, Swing, JavaFX & SWT 12
G LayoutManager Beliebige Anzahl von Panels für LayoutManager AWT, Swing, JavaFX & SWT 3
L Ein Actionlistener für ein Textfeld, anstatt viele Actionlistener für ein Textfeld AWT, Swing, JavaFX & SWT 7
S Swing Finde Grund für NullPointerExeption nicht. AWT, Swing, JavaFX & SWT 2
W JavaFX (j)Unittests für GUI AWT, Swing, JavaFX & SWT 0
B JavaFX JavaFX TableView PropertyValueFactory für Werte aus HashMap AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben