Заголовок Выравнивания Jtable Справа

в основном, у меня есть JTable, содержащий столбцы с выровненными по правому краю ячейками, но выровненными по левому краю заголовками, которые выглядят очень плохо. Я хотел бы выровнять заголовки этих столбцов по правому краю, не изменяя "внешний вид" заголовков.

спасибо

12 ответов


вот альтернативный подход к изменению TableCellRenderer таблицы JTableHeader. Это не обязательно для этого использования, но это минимизирует влияние на внешний вид делегата пользовательского интерфейса.

типичное использование:

JTable table = new JTable(…);
JTableHeader header = table.getTableHeader();
header.setDefaultRenderer(new HeaderRenderer(table));

пользовательский визуализатор заголовка:

private static class HeaderRenderer implements TableCellRenderer {

    DefaultTableCellRenderer renderer;

    public HeaderRenderer(JTable table) {
        renderer = (DefaultTableCellRenderer)
            table.getTableHeader().getDefaultRenderer();
        renderer.setHorizontalAlignment(JLabel.CENTER);
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected,
        boolean hasFocus, int row, int col) {
        return renderer.getTableCellRendererComponent(
            table, value, isSelected, hasFocus, row, col);
    }
}

попробуйте это:

((DefaultTableCellRenderer)table.getTableHeader().getDefaultRenderer())
    .setHorizontalAlignment(JLabel.RIGHT);

DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) your_jtable.getTableHeader().getDefaultRenderer();
renderer.setHorizontalAlignment(0);

здесь 0 центр.


показанный выше HeaderRenderer (2011 / sep/21 от trashgod) в сочетании с кодом Heisenbug (2011/sep / 21) будет работать правильно , только если у вас все заголовки выровнены одинаково.

если вы хотите выровнять разные заголовки по-разному, вам придется использовать следующий код:

int[] alignments = new int[] { JLabel.LEFT, JLabel.RIGHT, JLabel.RIGHT };
for (int i = 0 ; i < jTable.getColumnCount(); i++){
  jTable.getTableHeader().getColumnModel().getColumn(i)
    .setHeaderRenderer(new HeaderRenderer(jTable, alignments[i]));
}

и

private static class HeaderRenderer implements TableCellRenderer {
  DefaultTableCellRenderer renderer;
  int horAlignment;
  public HeaderRenderer(JTable table, int horizontalAlignment) {
    horAlignment = horizontalAlignment;
    renderer = (DefaultTableCellRenderer)table.getTableHeader()
        .getDefaultRenderer();
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int col) {
    Component c = renderer.getTableCellRendererComponent(table, value,
      isSelected, hasFocus, row, col);
    JLabel label = (JLabel)c;
    label.setHorizontalAlignment(horAlignment);
    return label;
  }
}

что есть:
Установите выравнивание в getTableCellRendererComponent , а не HeaderRenderer конструктор.


for (int i = 0 ; i < table.getColumnCount(); i++){

    DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
    renderer.setHorizontalAlignment(SwingConstants.RIGHT);
    table.getColumn(i).setHeaderRenderer(renderer);

}

DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) 
MSISDNTable.getTableHeader().getDefaultRenderer();
renderer.setHorizontalAlignment(JLabel.RIGHT);

здесь MSISDNTable ваш стол


вещь, которую нужно помнить об обертывании заголовков таблиц по умолчанию: не держите ссылку на них.

если вы (или ваши пользователи) используете классическую тему Windows на Windows 7 и в приложении устанавливает систему по умолчанию LAF, ответ написал @trashgod может вызвать проблемы для вас.

зависит от эта ошибка, написал десять лет назад (серьезно). Если отображается таблица и вы переключаете тему в Windows предпочтения от темы Aero до Windows Classic, будет шквал NPEs. Вы не должны держаться за ссылку визуализатора, поскольку она может стать недействительной в какой-то момент времени. Упаковка должна быть выполнена динамическим способом, как это предлагается в комментариях отчета об ошибке. Я взял код оттуда и создал следующий runnable пример:

import java.awt.*;
import java.lang.ref.WeakReference;
import javax.swing.*;
import javax.swing.table.*;

public class TestFrame extends JFrame {

    private static final boolean I_WANT_THE_BUG_TO_HAPPEN = true;

    public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedLookAndFeelException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                int res = JOptionPane.showConfirmDialog(null, "Do you want to use the XP L&F?", "laffo", JOptionPane.YES_NO_OPTION);
                if (res == JOptionPane.YES_OPTION) {
                    try {
                        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                    } catch (Exception ex) {
                    }
                }
                new TestFrame().setVisible(true);
            }

        });

    }

    public class MyModel extends AbstractTableModel {

        public int getRowCount() {
            return 10;
        }

        public int getColumnCount() {
            return 10;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            return "" + rowIndex + " X " + columnIndex;
        }

    }

    public class MyJTable extends JTable {

        /**
         *
         */
        private static final long serialVersionUID = -233098459210523146L;

        public MyJTable(TableModel model) {
            super(model);
        }

        public void doSomething() {
            System.out.println("HEHE");
        }
    }

    public class MyAlternativeJTable extends JTable {

        private WeakReference<TableCellRenderer> wrappedHeaderRendererRef = null;
        private TableCellRenderer wrapperHeaderRenderer = null;

        public MyAlternativeJTable(TableModel model) {
            super(model);
        }

        private class MyAlternativeTableColumn extends TableColumn {

            MyAlternativeTableColumn(int modelIndex) {
                super(modelIndex);
            }

            @Override
            public TableCellRenderer getHeaderRenderer() {
                TableCellRenderer defaultHeaderRenderer
                        = MyAlternativeJTable.this.getTableHeader().getDefaultRenderer();
                if (wrappedHeaderRendererRef == null
                        || wrappedHeaderRendererRef.get() != defaultHeaderRenderer) {
                    wrappedHeaderRendererRef
                            = new WeakReference<TableCellRenderer>(defaultHeaderRenderer);
                    wrapperHeaderRenderer
                            = new DecoratedHeaderRenderer(defaultHeaderRenderer);
                }
                return wrapperHeaderRenderer;
            }
        }

        @Override
        public void createDefaultColumnsFromModel() {
            TableModel m = getModel();
            if (m != null) {
                // Remove any current columns
                TableColumnModel cm = getColumnModel();
                while (cm.getColumnCount() > 0) {
                    cm.removeColumn(cm.getColumn(0));
                }

                // Create new columns from the data model info
                for (int i = 0; i < m.getColumnCount(); i++) {
                    TableColumn newColumn = new MyAlternativeTableColumn(i);
                    addColumn(newColumn);
                }
            }
        }
    }

    private JPanel jContentPane = null;
    private JScrollPane jScrollPane = null;
    private JTable table1 = null;
    private JScrollPane jScrollPane1 = null;
    private JTable table2 = null;

    /**
     * This is the default constructor
     */
    public TestFrame() {
        super();
        initialize();
        int res = JOptionPane.showConfirmDialog(null, "Do you want to call updateUI() on the tables ?", "laffo", JOptionPane.YES_NO_OPTION);
        if (res == JOptionPane.YES_OPTION) {
            table2.updateUI();
            table1.updateUI();
        }
    }

    /**
     * This method initializes this
     *
     * @return void
     */
    private void initialize() {
        this.setSize(753, 658);
        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        this.setContentPane(getJContentPane());
        this.setTitle("JFrame");
    }

    /**
     * This method initializes jContentPane
     *
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(null);
            jContentPane.add(getJScrollPane(), null);
            jContentPane.add(getJScrollPane1(), null);
        }
        return jContentPane;
    }

    /**
     * This method initializes jScrollPane
     *
     * @return javax.swing.JScrollPane
     */
    private JScrollPane getJScrollPane() {
        if (jScrollPane == null) {
            jScrollPane = new JScrollPane();
            jScrollPane.setBounds(new java.awt.Rectangle(358, 0, 387, 618));
            jScrollPane.setViewportView(getTable1());
        }
        return jScrollPane;
    }

    /**
     * This method initializes table1
     *
     * @return javax.swing.JTable
     */
    private JTable getTable1() {
        if (table1 == null) {
            table1 = new JTable(new MyModel());
        }
        return table1;
    }

    /**
     * This method initializes jScrollPane1
     *
     * @return javax.swing.JScrollPane
     */
    private JScrollPane getJScrollPane1() {
        if (jScrollPane1 == null) {
            jScrollPane1 = new JScrollPane();
            jScrollPane1.setBounds(new java.awt.Rectangle(0, 0, 350, 618));
            jScrollPane1.setViewportView(getTable2());
        }
        return jScrollPane1;
    }

    /**
     * This method initializes table2
     *
     * @return javax.swing.JTable
     */
    private JTable getTable2() {
        if (table2 == null) {
            if (I_WANT_THE_BUG_TO_HAPPEN) {
                table2 = new MyJTable(new MyModel());
                JTableHeader header = table2.getTableHeader();
                TableCellRenderer render = new DecoratedHeaderRenderer(header.getDefaultRenderer());
                header.setDefaultRenderer(render);
            } else {
                table2 = new MyAlternativeJTable(new MyModel());
            }
        }
        return table2;
    }

    private class DecoratedHeaderRenderer implements TableCellRenderer {

        public DecoratedHeaderRenderer(TableCellRenderer render) {
            this.render = render;
        }
        private TableCellRenderer render;

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = render.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            return c;
        }

    }

}

просто запустите пример и выбрать Yes дважды и смотреть, как он разваливается. Затем измените I_WANT_THE_BUG_TO_HAPPEN статический члены false и повторите. Случай с этим членом установлен в true по существу то же самое, что и самый популярный ответ здесь. Наиболее важной частью этого примера является extended JTable (MyAlternativeJTable), который делает обертку динамически.

в настоящее время принимаются ответ на этот вопрос широко используется, но это нецелесообразно. Вы можете воспроизвести его с потерянными приложениями, включая Netbeans 8.0.2 (который сам основан на Java), в то время как он показывает сортируемую таблицу, такую как Window > IDE Tools > Notifications, где вы также получите отчеты NPE, по иронии судьбы. Просто переключите тему Windows с Aero на Windows Classic (через right-click Desktop > Personalize > Change the visuals and sounds on your computer) в Windows 7.

если вы используете застекленные списки и звоните ca.odell.glazedlists.swing.TableComparatorChooser.install, Вы тоже пострадавшие. Он вводит собственный пользовательский визуализатор для сортировки стрелок.

я случайно наткнулся на это, пытаясь найти решение для этот вопрос что я подозреваю, что это связано.


попробуйте этот код

JTableHeader jtableHeader = jtable.getTableHeader();
DefaultTableCellRenderer rend = (DefaultTableCellRenderer) jtable.getTableHeader().getDefaultRenderer();
rend.setHorizontalAlignment(JLabel.CENTER);
jtableHeader.setDefaultRenderer(rend);

Я создал класс на основе решения pvbemmelen62, который можно использовать очень легко, например:

AlignHeaderRenderer.install(myTable, new int[] { SwingConstants.RIGHT,
                        SwingConstants.RIGHT, SwingConstants.LEFT });

или

AlignHeaderRenderer.install(myTable, 0, SwingConstants.RIGHT);
AlignHeaderRenderer.install(myTable, 1, SwingConstants.RIGHT);

вот код:

public class AlignHeaderRenderer implements TableCellRenderer {

private final TableCellRenderer renderer;
private final int alignment;

public static void install(final JTable table, final int[] alignments) {
    for (int i = 0; i < alignments.length; ++i)
        install(table, i, alignments[i]);
}

public static void install(final JTable table, final int row,
        final int alignment) {
    table.getTableHeader().getColumnModel().getColumn(row)
            .setHeaderRenderer(new AlignHeaderRenderer(table, alignment));
}

private AlignHeaderRenderer(final JTable table, final int alignment) {
    renderer = table.getTableHeader().getDefaultRenderer();
    this.alignment = alignment;
}

@Override
public Component getTableCellRendererComponent(final JTable table,
        final Object value, final boolean isSelected,
        final boolean hasFocus, final int row, final int col) {
    final Component c = renderer.getTableCellRendererComponent(table,
            value, isSelected, hasFocus, row, col);
    ((JLabel) c).setHorizontalAlignment(alignment);
    return c;
}

}

секрет в том, чтобы использовать визуализатор из фиктивной таблицы для получения правильного L&F и скопировать выравнивание из визуализатора строк реальной таблицы. Таким образом, каждый столбец выравнивается отдельно. Вот код:

table.getTableHeader().setDefaultRenderer(new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
        Component c2 = dummy.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
        if (table.getRowCount() > 0) {
            Component c3 = table.getCellRenderer(0, col).getTableCellRendererComponent(table, value, isSelected, hasFocus, 0, col);
            if (c2 instanceof JLabel && c3 instanceof JLabel)
                ((JLabel)c2).setHorizontalAlignment(((JLabel)c3).getHorizontalAlignment());
        }
        return c2;
    }
    private final JTable dummy = new JTable();
});

приведенный выше код не содержит ссылок на визуализаторы, поэтому он избегает ошибки NPE, упомянутой выше. Он не требует именованного класса, поэтому вы можете просто поместить код туда, где он вам нужен.


  ((DefaultTableCellRenderer)jTable2.getTableHeader().getDefaultRenderer())
    .setHorizontalAlignment(JLabel.CENTER);

((JLabel)mTabBOM.getTableHeader().getDefaultRenderer()).setHorizontalAlignment( JLabel.CENTER );