noch ne Frage zu JTable.

Flex IV

Mitglied
Hallo,
ich hab da eine Tabelle mit vier Spalten, in der letzten Spalte brauche ich (beim rendern der Zelle) den wert aus der 3. Spalte (derselben Zeile).
ich krieg einfach nicht raus, wie ich (listing Zeile 108) den float wert der vorherigen Zelle bekommen kann (und an x2 zuzuweisen).

Java:
import java.awt.*;
import java.util.Random;
 
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Component;
import java.awt.Point;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class JTableDemo extends JFrame
{	
	static Color LiteBlue = new Color(238, 244, 255);
	
    public static void main( String[] args ){
    	
    	JTableDemo jtDemo = new JTableDemo ();
    }
    	
    public JTableDemo()
    {
    	
    //	Ein TableModel mit zufälligen Werten füllen
        TableModel model = randomModel();
 
    //	Die JTable initialisieren
        JTable table = new JTable( model );
        table.setDefaultRenderer( Object.class, new ColorRenderer());
        table.setDefaultRenderer( Integer.class, new ColorRenderer());
        table.setDefaultRenderer( Float.class, new ColorRenderer());
    //	table.setDefaultRenderer( Point.class, new PointRender());
        
        JFrame frame = new JFrame( "Demo" );
        frame.getContentPane().add( new JScrollPane( table ) );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
    }
 
    // Diese Methode generiert ein TableModel mit zufälligen Werten
    private static TableModel randomModel(){
        Object[] names = { "String", "Integer", "Float", "Point" };
 
        DefaultTableModel dtmodel = new DefaultTableModel( names, 0 ) {
            @Override
            public Class<?> getColumnClass( int column ) {
                switch( column ){
                    case 0: return String.class;
                    case 1: return Integer.class;
                    case 2: return Float.class;
                    case 3: return Point.class;
                    default: return Object.class;
                }
            }
        };
 
        Random random = new Random();
 
        for( int i = 0; i < 22; i++ ){
            Object[] row = {
                    randomString( random ),
                    randomInt( random ),
                    (float) (1+ i + i/24.0F), 
                    new Point( randomInt( random ), randomInt( random ))
            };
 
            dtmodel.addRow( row );
        }
 
        return dtmodel;
    }
 
 // Generiert einen zufälligen String
    private static String randomString( Random random ){
        int length = random.nextInt( 4 ) + 4;
        StringBuilder result = new StringBuilder( length );
        for( int i = 0; i < length; i++ )
            result.append( (char)('a' + random.nextInt( 'z' - 'a' + 1 )));
        return result.toString();
    }
 
 // Generiert einen zufälligen int
    private static int randomInt( Random random ){
        return random.nextInt( 1000 ) + 1;
    }
    
    class ColorRenderer extends DefaultTableCellRenderer {
    	public Component getTableCellRendererComponent 
    		(JTable table, Object value,
    		 boolean isSelected,
    		 boolean hasFocus,
    		 int row, int column) {

    		super.getTableCellRendererComponent(table, value, isSelected,
    				hasFocus, row, column);

    	System.out.println(column+": "+value);
    		if (column == 0)
    			setHorizontalAlignment(CENTER);
    		
    		if (row % 2 == 1) 
    			setBackground(LiteBlue);
    		else
    			setBackground(Color.WHITE);
    		
    		if (column == 3) {
    			float x2 = (float) table.getModel().getValueAt(row, 2);
    			
    		}

   			return this;
    	}
    }
    
//	-----------------------------------------------------------------------------
    
  //Ein Renderer für java.awt.Point
    public class PointRender extends DefaultTableCellRenderer{
	private static final long serialVersionUID = 1L;

		@Override
        public Component getTableCellRendererComponent( JTable table, Object value, 
                boolean isSelected, boolean hasFocus, int row, int column ) {
            Point point = (Point)value;
            String text = point.x + " / " + point.y;
            return super.getTableCellRendererComponent( table, text, isSelected,
                hasFocus,  row, column );
        }
    }

}

Geht das? Wie?

Danke und Gruss,
der Flex
 
Hallo,

du missbrauchst einen TableCellRenderer als TableModel. Du solltest dir ein eigenes Model schreiben, welches dir in der 4.Spalte den Wert der 2. Spalte *2 zurückgibt.

Der Renderer ist nur zuständig für das Aussehen der Zelle. Der DefaultCellRenderer ist ein JLabel, das heißt du kannst dort einfach setText aufrufen. Aber wie gesagt, du nutzt den Renderer falsch.

Gruß

Sascha
 
Danke Sasha,
ich dachte eigentlich ich hätte ein eigenes Modell definiert?! In Zeile 25.
Wie muss ich das denn machen, dass ich den Wert (Inhalt) einer Zelle im Modell ermittel kann?
Danke und Gruss,
Flex
 
Danke nochmal,
in dem Beispiel wird aber ein AbstractTableModel verwendet. ich arbeite (s.o) aber mit dem DefaultTableModel - hilft mir also nicht wirklich weiter.

Jetzt hab ich also versucht das DefaultTableModel für meine Zwecke zu erweitern:
Java:
 package jtable;

import java.awt.*;
import java.util.Random;
 
import javax.swing.*;
import javax.swing.table.*;

import java.awt.Component;
import java.awt.Point;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class JTableDemo2 extends JFrame
{	
	static Color LiteBlue = new Color(238, 244, 255);
	
    public static void main( String[] args ){
    	
    	JTableDemo jtDemo = new JTableDemo ();
    }
    	
    public JTableDemo2()
    {
    	
    //	Ein TableModel mit zufälligen Werten füllen
    //	TableModel model = randomModel();
    	TableModel model = new MyTableModel ();
    	fillModel (model);
        
 
    //	Die JTable initialisieren
        JTable table = new JTable( model );
        table.setDefaultRenderer( Object.class, new ColorRenderer());
        table.setDefaultRenderer( Integer.class, new ColorRenderer());
        table.setDefaultRenderer( Float.class, new ColorRenderer());
    //	table.setDefaultRenderer( Point.class, new PointRender());
        
    //	Der TableRowSorter wird die Daten des Models sortieren
        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>();
 
    //	Der Sorter muss dem JTable bekannt sein
        table.setRowSorter( sorter );
 
    //	... und der Sorter muss wissen, welche Daten er sortieren muss
        sorter.setModel( model );
 
        JFrame frame = new JFrame( "Demo" );
        frame.getContentPane().add( new JScrollPane( table ) );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
    }
 
    
    private void fillModel (TableModel model) {
    Random random = new Random();
    
    	for( int i = 0; i < 22; i++ ){
    		Object[] row = {
                randomString( random ),
                randomInt( random ),
                (float) (1+ i + i/24.0F), 
                new Point( randomInt( random ), randomInt( random ))
    			};
            ((MyTableModel) model).addRow( row );
    	}
    }
 
 // Generiert einen zufälligen String
    private static String randomString( Random random ){
        int length = random.nextInt( 4 ) + 4;
        StringBuilder result = new StringBuilder( length );
        for( int i = 0; i < length; i++ )
            result.append( (char)('a' + random.nextInt( 'z' - 'a' + 1 )));
        return result.toString();
    }
 
 // Generiert einen zufälligen int
    private static int randomInt( Random random ){
        return random.nextInt( 1000 ) + 1;
    }
    
    class ColorRenderer extends DefaultTableCellRenderer {
    	public Component getTableCellRendererComponent 
    		(JTable table, Object value,
    		 boolean isSelected,
    		 boolean hasFocus,
    		 int row, int column) {

    		super.getTableCellRendererComponent(table, value, isSelected,
    				hasFocus, row, column);

    	//	System.out.println(column+": "+value);
    		if (column == 0)
    			setHorizontalAlignment(CENTER);
    		
    		if (row % 2 == 1) 
    			setBackground(LiteBlue);
    		else
    			setBackground(Color.WHITE);
    		
    	//	if (column == 3)  
    		//	float x2 = table.getModel().getValueAt(row, 2);
    		
   			return this;
    	}
    }
    
   static class MyTableModel extends DefaultTableModel {
    	
        static Object[] columnNames = { "String", "Integer", "Float", "Point" };
        private Object[][] data;
        
        public MyTableModel () {
        	super(columnNames, 0 );	
        }
        
        public void addRow (Object[] rowData) {
        	this.addRow(rowData);
        }

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return (String) columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
                return false;
        }

        /* Don't need to implement this method unless your table's
         * data can change.
         */
        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }

Pustekuchen, jetzt gibt es eine nullpointer-exception wenn ich die ein Object der Klasse MyTableModel kreiere...
Schöne Shice
 
So,
jetzt hab ich es geschafft, mit einem eigenen - vom DefaultModel abgeleiteten Model MyTableModel.
Bleibt allerdings die Eingangsfrage: Wie kann ich jetzt in Zeile 101 den Float-Wert einer Zelle auslesen?

Java:
package jtable;

import java.awt.*;
import java.util.Random;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Component;
import java.awt.Point;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class JTableDemo2 extends JFrame
{	
	static Color LiteBlue = new Color(238, 244, 255);
	
    public static void main( String[] args ){
    	
    	JTableDemo jtDemo = new JTableDemo ();
    }
    	
    public JTableDemo2()
    {
    	
    //	Ein TableModel mit zufälligen Werten füllen
    //	TableModel model = randomModel();
    	MyTableModel model = new MyTableModel ();
    	fillModel (model);
 
    //	Die JTable initialisieren
        JTable table = new JTable( model );
        table.setDefaultRenderer( Object.class, new ColorRenderer());
        table.setDefaultRenderer( Integer.class, new ColorRenderer());
        table.setDefaultRenderer( Float.class, new ColorRenderer());
    //	table.setDefaultRenderer( Point.class, new PointRender());
        
    //	Der TableRowSorter wird die Daten des Models sortieren
        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>();
 
    //	Der Sorter muss dem JTable bekannt sein
        table.setRowSorter( sorter );
 
    //	... und der Sorter muss wissen, welche Daten er sortieren muss
        sorter.setModel( model );
 
        JFrame frame = new JFrame( "Demo" );
        frame.getContentPane().add( new JScrollPane( table ) );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
    }
 
   
    private void fillModel (MyTableModel model) {
    Random random = new Random();
    
    	for( int i = 0; i < 22; i++ ){
    		Object[] row = {
                randomString( random ),
                randomInt( random ),
                (float) (1+ i + i/24.0F), 
                new Point( randomInt( random ), randomInt( random ))
    			};
             model.addRow( row );
    	}
    }

 // Generiert einen zufälligen String
    private static String randomString( Random random ){
        int length = random.nextInt( 4 ) + 4;
        StringBuilder result = new StringBuilder( length );
        for( int i = 0; i < length; i++ )
            result.append( (char)('a' + random.nextInt( 'z' - 'a' + 1 )));
        return result.toString();
    }
 
 // Generiert einen zufälligen int
    private static int randomInt( Random random ){
        return random.nextInt( 1000 ) + 1;
    }
    
    class ColorRenderer extends DefaultTableCellRenderer {
    	public Component getTableCellRendererComponent 
    		(JTable table, Object value,
    		 boolean isSelected,
    		 boolean hasFocus,
    		 int row, int column) {

    		super.getTableCellRendererComponent(table, value, isSelected,
    				hasFocus, row, column);

    	//	System.out.println(column+": "+value);
    		if (column == 0)
    			setHorizontalAlignment(CENTER);
    		
    		if (row % 2 == 1) 
    			setBackground(LiteBlue);
    		else
    			setBackground(Color.WHITE);
    		
    		if (column == 3) {  
    		//	float x2 = (float) table.getModel().getValueAt(row, 2);
    		}
    		
   			return this;
    	}
    }
    
    static class MyTableModel extends DefaultTableModel {
    	
        private String[] colNames = { "String", "Integer", "Float", "Point" };
        private Object[][] data = new Object[100][4];
        private int rows = 0;
        
        public MyTableModel () {
        //	super(columnNames, 0 );	
        }
        
        public void addRow (Object[] rowData) {
        //	super.addRow(rowData);
        	data [rows++] = rowData;
        }

        public int getColumnCount() {
            return colNames.length;
        }

    	public int getRowCount() {
        //	return data == null ? 0 : data.length;
    		return rows;
        } 

        public String getColumnName(int col) {
            return colNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
                return false;
        }

        /* Don't need to implement this method unless your table's
         * data can change.
         */
        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }

}

Kann mir das BITTE jemand sagen?
 
in dem Beispiel wird aber ein AbstractTableModel verwendet. ich arbeite (s.o) aber mit dem DefaultTableModel - hilft mir also nicht wirklich weiter.

Das stimmt nicht. Du überschreibst viele Methoden des DefaultTableModel, so werden jetzt im DefaultTableModel einiges angelegt was du gar nicht brauchst. Du könntest einfach hingehen und änderst das DefaultTableModel zu AbstractTableModel und du wirst sehen, dass es immer noch funktioniert. Das DefaultTableModel ist halt die DefaultImplementierung des AbstractTableModel. Es stellt dir einiges mehr zur Verfügung, was jetzt alles nicht mehr funktioniert, da du nur manche Methoden überschrieben hast. Zudem werden intern jetzt auch einige Variablen angelegt die du nicht brauchst.

Ich glaube du hast das TableModel nicht richtig verstanden. ;-)

Die Methode getValueAt(row, column) gibt den Wert zurück, der in der Zelle stehen soll. Dort kannst du ja leicht abfragen, ob du dich in der 4. Spalte befindest und dann den entsprechenden Wert zurückgeben.

Zur Info (falls du es brauchst)
Die Methode setValueAt wird aufgerufen, wenn du eine Zelle editierst.

Gruß

Sascha
 
Mag sein das ich es noch nicht richtig verstanden habe.
Mit dem geigneten cast: float x2 = (Float) table.getModel().getValueAt(row, 2);
in Zeile 101 (ursprüngliches Listing 108) funktioniert es jetzt bestens.
Danke trotzem.
Flex
 

Neue Beiträge

Zurück