Results 1 to 4 of 4
Like Tree2Likes
  • 1 Post By DarrylBurke
  • 1 Post By javice

Thread: JTable misjustified numbers with alternating row colors

  1. #1
    javice is offline Member
    Join Date
    Mar 2012
    Posts
    4
    Rep Power
    0

    Default JTable misjustified numbers with alternating row colors

    Hi everybody,

    1) i wanted every second row of my JTable to be in an alternating color. I found examples in the www and it basically works. But then i noticed, that without alternating colors numbers are right justified (as expected):
    Unbenannt2.bmp

    WITH alternating colors, they are left justified:
    Unbenannt.bmp


    Could not find a solution. Nor could a coworkers. Any ideas how to fix that?

    I created a stripped down version of my problem, which has everything in it. So you can cut and paste the code from here to eclipse for further examination, if you like to.



    2) There is another problem, but i put in a second post.




    Java Code:
    package LudoPackage;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JLabel;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableModel;
    import java.awt.*;  
    import java.awt.event.*;  
    import java.sql.Types;
    
    import javax.swing.event.*;  
    
    
    
    
    import javax.swing.RowSorter;
    //import javax.swing.table.DefaultTableModel;
    //import javax.swing.table.TableModel;
    import javax.swing.table.TableRowSorter;
    
    
    
    
    public class strippedDown {
    
    	class simpleData extends AbstractTableModel {	
    		int				maxCols;
    		int				maxRows;
    		
    	    String[] columns = { "Item", "Quantity", "Price" };
    	
    	    Object[][] cache = { { "Potatoes", 1, 10.98 }, { "Magazine", 2, 7.99 },
    	        { "Can of soup", 10, 0.89 }, { "DVD movie", 11, 39.99 } };
    	
    		
    		//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
    		public simpleData(
    		) {
    			this.maxCols		= 3;
    			this.maxRows		= 4;
    		}
    	
    		
    		//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    		@Override public String getColumnName(
    			int	col
    		) {
    			String	tmpStr;
    	
    			tmpStr	= columns[col];
    			return( tmpStr );
    		} // Ende getColumnName
    	
    		
    		//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    		@Override public int getRowCount() 		{ return(this.maxRows); }
    		@Override public int getColumnCount() 	{ return(this.maxCols); }
    	
    		
    		//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    		@Override public Class getColumnClass(
    			int	col
    		) {
    			Class	x;
    			
    			switch( col ) {
    				case 0:	x = Object.class;break;
    				case 1:	x = Number.class;break;
    				case 2: x = Number.class;break;
    				default:System.exit(-99);
    				x = Object.class;
    				
    			}
    			return(x);
    		} // Ende getColumnClass
    		
    		
    		//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    		@Override public Object getValueAt(
    			int row,
    			int col
    		) {
    			Object	tmp;
    			
    			tmp	= this.cache[row][col];
    			return(tmp);
    		}
    	}
    	
    	
    	//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    	private class myRenderer implements TableCellRenderer {
    		public final DefaultTableCellRenderer	dr	= new DefaultTableCellRenderer();
    		
    		//----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    		public Component getTableCellRendererComponent(
    			JTable	table,
    			Object	value,
    			boolean isSelected, 
    		    boolean hasFocus,
    		    int 	row,
    		    int 	column
    		) {
    			Component	renderer	= dr.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
    			Color	fg;
    			Color	bg;
    
    			if( isSelected ) {				
    				fg	= Color.YELLOW;
    				bg	= Color.GREEN;
    			} else {
    				if( row % 2  == 0 ){
    					fg	= Color.BLUE;
    					bg	= Color.WHITE;
    				} else {
    					fg	= Color.WHITE;
    					bg	= Color.BLUE;
    					
    				}
    			}
    			renderer.setForeground(fg);
    			renderer.setBackground(bg);
    			return( renderer );
    		}
    	}
    	
    	
    	//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    	public strippedDown(
    	) {
    		JFrame 	f;
    		JTable	tbl;
    		simpleData data;
    		
    		data	= new simpleData();
    		
    		f		= new JFrame();
    		tbl		= new JTable( data );
    		
    		
    		
    	    tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    	    
    	    tbl.setPreferredScrollableViewportSize(new Dimension(800, 500));
    
    	    //code for numerical sorting
    //	    tbl.setAutoCreateRowSorter(true);    
    	    RowSorter<simpleData> sorter = new TableRowSorter<simpleData>(data);
    	    tbl.setRowSorter(sorter);
    
    	    //now, this here creates the alternating colors in every second row
    	    tbl.setDefaultRenderer(Object.class, new myRenderer());
    	    tbl.setDefaultRenderer(Number.class, new myRenderer());
    	    
    	    //when using these 2 lines of code instead of the 2 lines above, the problem of
                     //wrong justified numbers occurs as well
               	    //tbl.setDefaultRenderer(Object.class, new DefaultTableCellRenderer());
    	    //tbl.setDefaultRenderer(Number.class, new DefaultTableCellRenderer());
    	    
    	    
    	    f.getContentPane().add( new JScrollPane( tbl ) );
    	    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    	    f.pack();
    	    f.setVisible( true );
    	} // Ende simpleJTableGUI
    	
    	
    	//---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8	
    	public static void main(String[] args) {
    			new strippedDown();
    	}
    	
    }

  2. #2
    javice is offline Member
    Join Date
    Mar 2012
    Posts
    4
    Rep Power
    0

    Default Re: JTable misjustified numbers with alternating row colors

    2) Ok, here is number 2: When enabling sorting, i noticed, that columns with numbers will be sorted alphabetically (e.g. 1, 10, 2, 3, 31, 4). I found a cure for that as well in the www, but could not apply it to my code. I include the working code from the www and i put a comment into my code in the first post to mark it.

    package LudoTest;

    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.RowSorter;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    import javax.swing.table.TableRowSorter;

    public class TableRowSorterWithHeader extends JFrame {
    public TableRowSorterWithHeader() {
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    String[] columns = { "Item", "Quantity", "Price" };

    Object[][] rows = { { "Potatoes", 1, 10.98 }, { "Magazine", 2, 7.99 },
    { "Can of soup", 10, 0.89 }, { "DVD movie", 11, 39.99 } };

    TableModel model = new DefaultTableModel(rows, columns){
    public Class getColumnClass(int column) {
    if (column >= 0 && column <= getColumnCount())
    return getValueAt(0, column).getClass();
    else
    return Object.class;
    }
    };
    JTable table = new JTable(model);
    RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
    table.setRowSorter(sorter);
    getContentPane().add(new JScrollPane(table));

    setSize(200, 150);
    setVisible(true);
    }

    public static void main(String[] args) {
    new TableRowSorterWithHeader();
    }
    }

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is online now Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,409
    Rep Power
    20

    Default Re: JTable misjustified numbers with alternating row colors

    A lot of plus points for a clear problem description and posting a SSCCE

    Minus points for:
    • Silly comment lines that resemble a graph axis
    • Silly end-of-method inline comments
    • One unused and two commented imports
    • Multiple blank lines aka vertical whitespace
    • Variable declaration and assignment on consecutive lines
    • Parentheses around return values
    • Class names that strt with a lowercase letter
    • Swing components constructed and manipulated on the main Thread instead of the EDT.


    Your expectations, that DefaultTableCellRenderer should right-align a number, are wrong. By default, JTable uses its own internal static class JTable.NumberRenderer and extending class DoubleRenderer (and corresponding editors). Read the source of JTable around lines 5336 to 5354 (actual numbers may vary depending on your JDK version).

    The sorting problem is because Number doesn't implement the Comparable interface. Its subclasses Integer and Double do. If you return Integer.class and Double.class from getColumnClass(...), the alignment will still be left-justified, but sorting will work correctly.

    For minor customizations in rendering, I usually find it easier to wrap the table's own default renderer, thus leaving the heavy lifting work to the Swing classes. One way to do this is to obtain a reference to the renderer and save the reference to an instance field of the custom renderer. This is illustrated in the code, which takes care of most of the bullet points I raised, has some variable names changed to make it easier for me to read, and a couple of other changes.
    Java Code:
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class StripeRenderingTableExample {
    
      class SimpleData extends AbstractTableModel {
    
        int maxCols = 3;
        int maxRows = 4;
        String[] columns = {"Item", "Quantity", "Price"};
        Object[][] data = {
          {"Potatoes", 1, 10.98},
          {"Magazine", 2, 7.99},
          {"Can of soup", 10, 0.89},
          {"DVD movie", 11, 39.99}
        };
    
        @Override
        public String getColumnName(int col) {
          return columns[col];
        }
    
        @Override
        public int getRowCount() {
          return maxRows;
        }
    
        @Override
        public int getColumnCount() {
          return maxCols;
        }
    
        @Override
        public Class getColumnClass(int col) {
          switch (col) {
            case 0:
              return Object.class;
            case 1:
              return Integer.class;
            case 2:
              return Double.class;
            default:
              throw new IllegalArgumentException("Column cannot be greater than 2");
          }
        }
    
        @Override
        public Object getValueAt(int row, int col) {
          return data[row][col];
        }
      }
    
      private class MyRenderer implements TableCellRenderer {
    
        public final DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        private final TableCellRenderer defaultRenderer;
    
        public MyRenderer(TableCellRenderer defaultRenderer) {
          this.defaultRenderer = defaultRenderer;
        }
    
        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row, int column) {
          Component component = defaultRenderer.getTableCellRendererComponent(table,
                  value, isSelected, hasFocus, row, column);
    
          Color foreground;
          Color background;
          if (isSelected) {
            foreground = Color.YELLOW;
            background = Color.GREEN;
          } else {
            if (row % 2 == 0) {
              foreground = Color.BLUE;
              background = Color.WHITE;
            } else {
              foreground = Color.WHITE;
              background = Color.BLUE;
            }
          }
          component.setForeground(foreground);
          component.setBackground(background);
    
          return component;
        }
      }
    
      public StripeRenderingTableExample() {
        SimpleData data = new SimpleData();
        JTable table = new JTable(data);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setPreferredScrollableViewportSize(new Dimension(800, 500));
        RowSorter<SimpleData> sorter = new TableRowSorter<SimpleData>(data);
        table.setRowSorter(sorter);
    
        //now, this here creates the alternating colors in every second row
        table.setDefaultRenderer(Object.class,
            new MyRenderer(table.getDefaultRenderer(Object.class)));
        table.setDefaultRenderer(Integer.class,
            new MyRenderer(table.getDefaultRenderer(Integer.class)));
        table.setDefaultRenderer(Double.class,
            new MyRenderer(table.getDefaultRenderer(Double.class)));
    
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
      }
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    
          @Override
          public void run() {
            new StripeRenderingTableExample();
          }
        });
      }
    }
    db
    Last edited by DarrylBurke; 03-21-2012 at 11:39 PM.
    Fubarable likes this.
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  4. #4
    javice is offline Member
    Join Date
    Mar 2012
    Posts
    4
    Rep Power
    0

    Default Re: JTable misjustified numbers with alternating row colors

    I always wanted to come here to say thanks for your help to DarrylBurke.

    Now i have to apologize that it took me 2 months to do that. The reply was very good. Many thanks again.
    Fubarable likes this.

Similar Threads

  1. Replies: 5
    Last Post: 01-07-2012, 09:33 AM
  2. alternating series sum java help
    By java157 in forum New To Java
    Replies: 18
    Last Post: 03-20-2011, 03:41 AM
  3. Replies: 1
    Last Post: 10-18-2010, 06:48 AM
  4. JTable format numbers in column
    By mine0926 in forum NetBeans
    Replies: 7
    Last Post: 06-07-2010, 05:10 AM
  5. Alternating Sum
    By ScaryJello in forum New To Java
    Replies: 6
    Last Post: 10-13-2009, 09:18 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •