graphics in JTable, Darstellung fehlerhaft

cr3m4

Mitglied
Hallo,

ich sitze nun schon eine weile an einem Problem, welches auch diverse Foreneinträge nicht beseitigen konnten.

Ich habe eine JTable mit einen CustomHeaderRenderer und CustomCellrenderer der jeweils ein JPanel übergibt. In dem JPanel ist eine Linie per Graphics gezeichnet.
Im Header und in den Zellen werden die Grafiken jedoch erst korrekt dargestellt, nachdem die Fenstergröße geändert, oder in der Tabelle rumgeklickt wurde.
Ein repaint hat bei mir nicht funktioniert.

Wie kann ich die JTable nach Programmstart anders neu zeichnen oder gibt es andere Möglichkeiten mein Problem zu beseitigen?

Hier die Tabelle:
Code:
private JTable getConSecGrafx_jTable1() 
{
  if(conSecGrafx_jTable1 == null) 
	{
	Object vehposHeader[] = new JPanel[1];
       Object vehpos[][] = new JPanel[1][1];
					
		vehpos[0][0]= new DrawWidePanel(); 
				
		TableModel conSecGrafx_jTable1Model = 
		new DefaultTableModel
				(
					vehpos, vehposHeader
				);
					
				conSecGrafx_jTable1 = new JTable();
				conSecGrafx_jTable1.setModel(conSecGrafx_jTable1Model);
		
				conSecGrafx_jTable1.getTableHeader().setPreferredSize(new java.awt.Dimension(300,32));
					 TableColumn col = conSecGrafx_jTable1.getColumnModel().getColumn(0);
					 col.setHeaderRenderer(new grafxHeaderCellRenderer());
					 conSecGrafx_jTable1.getTableHeader().setResizingAllowed(false);
					 conSecGrafx_jTable1.getTableHeader().setReorderingAllowed(false); 
					 
grafxCellRenderer conSecGrafxCellRenderer = new grafxCellRenderer();
conSecGrafx_jTable1.setDefaultRenderer(Object.class,  conSecGrafxCellRenderer);
					 conSecGrafx_jTable1.getColumnModel().getColumn(0).setCellRenderer(conSecGrafxCellRenderer);
					   				
				}
				return conSecGrafx_jTable1;
		}

Hier der HeaderRenderer:
Code:
	class grafxHeaderCellRenderer extends JPanel implements TableCellRenderer
	{	
		
	public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column) 
		{	
		add(new DrawWideHeaderPanel());
				
		return this;
		}
	}

Hier der Cellrenderer:
Code:
public class grafxCellRenderer extends JPanel implements TableCellRenderer 
	{ 
	private static final long serialVersionUID = 1L;
		
	public Component getTableCellRendererComponent(JTable table, Object value, 
		 boolean isSelected, boolean hasFocus, int row, int column)
	  { 	
		this.setBackground(Color.white);
		add((JComponent)value);	
		return this; 
	  } 
	}

Hier die Grafiken:
Code:
class DrawPanel extends JPanel 
	{ 
	private static final long	serialVersionUID	= 1L;
	protected void paintComponent( Graphics g ) 
		{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(120, 20));
			this.setSize(120,20);

			for(int i=0;i<=1;i++)
			{
				g.drawLine( 0, i, 120, i ); 	
			}
					
		} 
	}
		
class DrawWidePanel extends JPanel 
	{ 
	private static final long	serialVersionUID	= 1L;
	@Override
	protected void paintComponent( Graphics g ) 
		{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(300, 20));
			this.setSize(300,20);
			this.setBackground(Color.white);

			for(int i=0;i<=1;i++)
			{
				g.drawLine( 0, i, 300, i ); 			
			}	
		} 
	}
		
class DrawDottedPanel extends JPanel 
	{ 
		private static final long	serialVersionUID	= 1L;
		protected void paintComponent( Graphics g ) 
		{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(120, 20));
			this.setSize(120,20);
					
			for(int y=0;y<=1;y++)
			{
				for (int x=0;x<=120;x=x+10)
				{
					g.drawLine( x, y, x+5, y );
				}
			}
					
		} 
	}
		
class DrawWideDottedPanel extends JPanel 
	{ 
	private static final long	serialVersionUID	= 1L;
	@Override
	protected void paintComponent( Graphics g ) 
		{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(300, 20));
			this.setSize(300,20);
			this.setBackground(Color.white);

			for(int y=0;y<=1;y++)
			{
				for (int x=0;x<=300;x=x+10)
				{
					g.drawLine( x, y, x+5, y );
				}
			}		
		} 
	}
	
class DrawLineDottedPanel extends JPanel 
	{ 
		private static final long	serialVersionUID	= 1L;
		protected void paintComponent( Graphics g ) 
			{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(120, 20));
			this.setSize(120,20);

				for(int y=0;y<=1;y++)
				{
				for (int x=1;x<=120;x=x+20)
				{
					g.drawLine( x, y, x+1, y );
				}
			}		
			for(int y=0;y<=1;y++)
				{
				for (int x=10;x<=120;x=x+20)
				{
				g.drawLine( x, y, x+5, y );
				}
			}
		}		
	}
		
class DrawWideLineDottedPanel extends JPanel 
	{ 
	private static final long	serialVersionUID	= 1L;
	@Override
	protected void paintComponent( Graphics g ) 
		{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(300, 20));
			this.setSize(300,20);
			this.setBackground(Color.white);
					
			for(int y=0;y<=1;y++)
			{
				for (int x=1;x<=300;x=x+20)
				{
					g.drawLine( x, y, x+1, y );
				}
			}
					
			for(int y=0;y<=1;y++)
			{
				for (int x=10;x<=300;x=x+20)
				{
					g.drawLine( x, y, x+5, y );
				}		
			}
		}		
	}		
		
public class DrawWideHeaderPanel extends JPanel 
	{ 
	private static final long	serialVersionUID	= 1L;
	@Override
	protected void paintComponent( Graphics g ) 
		{ 
			super.paintComponent( g );
			this.setPreferredSize(new java.awt.Dimension(310, 32));
			this.setSize(310,32);
			
			g.drawString("15",   0, 9);
			g.drawString("10", 100, 9);
			g.drawString( "5", 202, 9);
			g.drawString( "0", 302, 9);
				
			for(int y=12;y<=17;y++)
			{
				for (int x=5;x<=305;x=x+20)
				{
				g.drawLine( x, y, x+1, y );	//Vertikale kurze Linien im 20px-Abstand
				}
			}			
	               for(int y=10;y<=20;y++)
			{
				for (int x=5;x<=305;x=x+100)
				{
					g.drawLine( x, y, x+1, y );	//Vertikale lange Linien im 100px-Abstand					}
				}
					
			for (int x=5;x<=305;x=x+1)
			{
				g.drawLine( x, 14, x+1, 15 );		//Horizontale durchgehende Linie
			}				
		}
	}

Solltet ihr weitere Infos brauchen, einfach melden.

vielen Dank im Vorraus
 
Ohne mich jetzt in deinen Quellcode stürzen zu wollen - dein Problem hört sich für mich zumindest bekannt an. Hierfür habe ich immer folgende Lösung verwendet, vielleicht ist es ja tatsächlich das gleiche Problem:

Java:
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        fenster.updateUI();
    }
})

Hiermit forderst du das "fenster" auf, sich und seine Komponenten zu erneuern.
 
Ein repaint hat bei mir nicht funktioniert.

Wie kann ich die JTable nach Programmstart anders neu zeichnen oder gibt es andere Möglichkeiten mein Problem zu beseitigen?

Ich muss gestehen, ich hab mir deine Tabellen nicht angeschaut, aber anstelle eines repaint oder paint versuch doch einfach mal paintImmediately(int x, int y, int width, int high). Mit den Parametern sagst du welcher Bereich neu gezeichnet werden soll.
 
hmm, die beiden Funktionen stehen bei mir nicht zu Verfügung. Kann es sein dass die erst ab Java 1.6 implementiert sind?
Leider muss ich Das Programm unter java 1.5 realisieren. Habe ich wohl vergessen zu erwähnen.
 
ok war ja nur ne schnelle Vermutung :)
Ich arbeite momentan unter Eclipse, der regelt ja die Imports automatisch, daran sollte es also nicht liegen.

ich habe mal in der main ein repaint versucht ( inst.repaint(); ). Nun ist die Darstellung fast wie gewünscht, es scheint aber, als wären nur Teile neu gezeichnet worden oder sie müssten öfter neu gezeichnet werden.
Leider bringt ein wiederholtes repaint oder mit delay nichts.

so siehts momentan aus:

ohne repaint
ohnerepaint.JPG


mit einmaligem repaint
besser.JPG


so soll es shcon bei Programmstart aussehen:
perfekt.JPG
 
Hallo,

füge mal bitte vor dieser Zeile
Code:
add((JComponent)value);
noch ein
Code:
removeAll();
ein.

Dann müsste es eigentlich ohne Probleme funktionieren.
Du solltest dir aber eine andere Möglichkeit überlegen.


Mal zur Erklärung. Der Renderer ist ja bei dir ein JPanel. Aber in jeder Zelle in der er verwendet wird, wird immer das gleiche JPanel dargestellt. Also es ist nicht eine andere Instance oder so, sondern immer die selbe.
Zum Beispiel, wenn du nur beim ersten mal den Background auf Blau setzt, bleibt der Background für alle Zellen blau.
Hier hast du immer das Value hinzugefügt. Das sind bei 3 Zeilen, drei Elemente die direkt übereinander liegen.

MFG

Sascha
 
Schonmal ganz gut der Tipp. Die Zellinhalte werden korrekt dargestellt. Im HeaderRenderer funktioniert der Trick leider nicht :).
Trotzdem vielen dank
 
Das ist kein Trick, hab es oben nochmal erklärt.

Beim Header machst du das
Code:
add(new DrawWideHeaderPanel());
einfach im Contructor.

Also sieht die Methoden nachher so aus
Code:
public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column) 
		{	
			
		return this;
		}

MFG

Sascha
 
Zurück