1

Basically I have a JTable, and this JTabel will have a product in one cell, and then in the cell directly below it the cost.

The product name should be aligned to the left. The product cost should be aligned to the right.

I don't actually care what the alignment of other cells in each row is.

So I need to set the alignment of either individual cells, or individual rows. I've found ways to set the alignment of the table, and ways to set the alignment of the columns, but never the rows/individual cells.

sscce:

public class Main extends JFrame{
    public static void main(String args[]){
        new Main();
    }
    public Main(){
        super("Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setExtendedState(MAXIMIZED_BOTH);
        setVisible(true);
        setLayout(new BorderLayout());
        TableModel dataModel = new AbstractTableModel() {
             Object rows[] = new Object[50];
             public int getColumnCount(){return 1;}
             public int getRowCount(){return rows.length;}
             public Object getValueAt(int row, int col){ 
                 return rows[row];
             }
             public boolean isCellEditable(int row, int col){
                 return false; 
             }
             public void setValueAt(Object value, int row, int col) {
                 rows[row] = value;
                 fireTableCellUpdated(row,0);
             }
         };

        JTable receipt = new JTable(dataModel);
        receipt.setBorder(BorderFactory.createEtchedBorder());
        receipt.setShowGrid(false);
        add(receipt,BorderLayout.CENTER);
        for(int i = 0; i < 10; i+=2){
            receipt.setValueAt("ProductNameHere",i,0);
            receipt.setValueAt("Cost",i+1,0);
        }
        validate();
        repaint();
    }
}
Nathan
  • 8,093
  • 8
  • 50
  • 76
csga5000
  • 4,062
  • 4
  • 39
  • 52

1 Answers1

4

The default renderer for Number is a right aligned label. In this example, no special renderer is required to right align INT_COL, which is labeled Index and has type Integer.class.

image

If this is not helpful, please edit your question to include an sscce that shows your current approach and your cost data type.

Addendum: Alternatively, override prepareRender(), as shown here.

image

JTable receipt = new JTable(dataModel) {
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
        JLabel c = (JLabel) super.prepareRenderer(renderer, row, col);
        if (row % 2 == 0) {
            c.setHorizontalAlignment(JLabel.LEFT);
        } else {
            c.setHorizontalAlignment(JLabel.RIGHT);

        }
        return c;
    }
};

SSCCE:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

public class Main extends JFrame {

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Main();
            }
        });
    }

    public Main() {
        super("Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TableModel dataModel = new AbstractTableModel() {
            Object rows[] = new Object[10];

            @Override
            public int getColumnCount() {
                return 1;
            }

            @Override
            public int getRowCount() {
                return rows.length;
            }

            @Override
            public Object getValueAt(int row, int col) {
                return rows[row];
            }

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

            @Override
            public void setValueAt(Object value, int row, int col) {
                rows[row] = value;
                fireTableCellUpdated(row, 0);
            }
        };

        JTable receipt = new JTable(dataModel) {
            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
                JLabel c = (JLabel) super.prepareRenderer(renderer, row, col);
                if (row % 2 == 0) {
                    c.setHorizontalAlignment(JLabel.LEFT);
                } else {
                    c.setHorizontalAlignment(JLabel.RIGHT);

                }
                return c;
            }
        };
        receipt.setBorder(BorderFactory.createEtchedBorder());
        receipt.setShowGrid(false);
        add(receipt, BorderLayout.CENTER);
        for (int i = 0; i < 10; i += 2) {
            receipt.setValueAt("ProductNameHere", i, 0);
            receipt.setValueAt(Integer.valueOf(i + 1), i + 1, 0);
        }
        pack();
        setLocationByPlatform(true);
        setVisible(true);
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I added a sscce... As I said, I already know how to implement separate alignments for columns, I need separate alignment for cells or rows. – csga5000 Feb 22 '13 at 04:22
  • +1, for implementing getColumnClass() so the default renderers can be used correctly. – camickr Feb 22 '13 at 04:24
  • *The product name should be aligned to the left. The product cost should be aligned to the right*. Product name is a column and product cost is a second column. Based on your requirement you need column alignment, not cell alignment. Your SSCCE only shows 2 columns so I don't understand your comment about cell alignment. – camickr Feb 22 '13 at 04:26
  • 2
    @csga5000: Alternatively, override `prepareRender()`; I defer to camickr's [article](http://stackoverflow.com/a/6852973/230513) on the topic. – trashgod Feb 22 '13 at 04:28
  • My SSCCE shows 1 column. I never said that name was a column, as it is not, and neither is cost. I said "a product in one cell, and then in the cell directly below it the cost", all in 1 column. – csga5000 Feb 22 '13 at 04:36
  • Sorry, when I see a table with two setValueAt(..) methods in a loop I thought you were populating a row with two columns since you are using a JTable. I generally use a JList for single column components. Either overriding prepareRenderer() or creating a custom renderer can solve your problem. – camickr Feb 22 '13 at 04:49
  • Thanks tons. I actually could use a JList or something, but I decided against it because, I figured I might want to add a second column later, and because I'm less familiar with tables, and I wanted to figure them out. Once you understood what I was doing, you were extremely helpful, thanks tons. – csga5000 Feb 22 '13 at 05:00