【问题标题】:JTable frozen column alignment issue (Java 1.6)JTable 冻结列对齐问题 (Java 1.6)
【发布时间】:2012-07-31 14:54:58
【问题描述】:

我已经实现了如下的JTable冻结列。当使用垂直滚动条在大型数据集上滚动时,冻结表中的列与主表不对齐。请帮助

JTable      table,fixedTable
JScrollPane     _scrl_table;

table = new JTable();
table.setName("MAIN_TABLE");
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setVisibleRowCount(8);


fixedTable = new JTable();
fixedTable.setName("FIXED_TABLE");
fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

 _scrl_table = new JScrollPane(table,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

fixedTable.setPreferredScrollableViewportSize(fixedTable.getPreferredSize());
    _scrl_table.setRowHeaderView( fixedTable );
    _scrl_table.setCorner(JScrollPane.UPPER_LEFT_CORNER,         fixedTable.getTableHeader());  

【问题讨论】:

  • 我想我找到了问题所在。当主表的第一列的值有空格时,主表的行高会稍微偏离固定表,导致对齐问题。为了验证,我将主表的第一列更改为与固定表的最后一列相同,我没有注意到这个问题。有没有办法让主表的行高和固定表的行高一样?
  • 我通过将固定表的最后一列添加到主表作为第一列并将最小、首选和最大宽度设置为 1 解决了这个问题。

标签: java swing jtable


【解决方案1】:

示例滚动水平方向,必须更改为垂直

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;


public class FixedRowExample extends JFrame {

    private static final long serialVersionUID = 1L;
    private Object[][] data;
    private Object[] column;
    private JTable fixedTable, table;
    private int FIXED_NUM = 2;

    public FixedRowExample() {
        super("Fixed Row Example");
        data = new Object[][]{
                    {"a", "", "", "", "", ""},
                    {"", "b", "", "", "", ""},
                    {"", "", "c", "", "", ""},
                    {"", "", "", "d", "", ""},
                    {"", "", "", "", "e", ""},
                    {"", "", "", "", "", "f"},
                    {"fixed1", "", "", "", "", "", "", ""},
                    {"fixed2", "", "", "", "", "", "", ""}};
        column = new Object[]{"A", "B", "C", "D", "E", "F"};
        AbstractTableModel model = new AbstractTableModel() {

            private static final long serialVersionUID = 1L;

            @Override
            public int getColumnCount() {
                return column.length;
            }

            @Override
            public int getRowCount() {
                return data.length - FIXED_NUM;
            }

            @Override
            public String getColumnName(int col) {
                return (String) column[col];
            }

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

            @Override
            public void setValueAt(Object obj, int row, int col) {
                data[row][col] = obj;
            }

            public boolean CellEditable(int row, int col) {
                return true;
            }
        };

        AbstractTableModel fixedModel = new AbstractTableModel() {

            private static final long serialVersionUID = 1L;

            @Override
            public int getColumnCount() {
                return column.length;
            }

            @Override
            public int getRowCount() {
                return FIXED_NUM;
            }

            @Override
            public Object getValueAt(int row, int col) {
                return data[row + (data.length - FIXED_NUM)][col];
            }
        };
        table = new JTable(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        fixedTable = new JTable(fixedModel);
        fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane scroll = new JScrollPane(table);
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        JScrollPane fixedScroll = new JScrollPane(fixedTable) {

            private static final long serialVersionUID = 1L;

            @Override
            public void setColumnHeaderView(Component view) {
            } // work around
        }; // fixedScroll.setColumnHeader(null);  
        fixedScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        JScrollBar bar = fixedScroll.getVerticalScrollBar();
        JScrollBar dummyBar = new JScrollBar() {

            private static final long serialVersionUID = 1L;

            @Override
            public void paint(Graphics g) {
            }
        };
        dummyBar.setPreferredSize(bar.getPreferredSize());
        fixedScroll.setVerticalScrollBar(dummyBar);

        final JScrollBar bar1 = scroll.getHorizontalScrollBar();
        JScrollBar bar2 = fixedScroll.getHorizontalScrollBar();
        bar2.addAdjustmentListener(new AdjustmentListener() {

            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                bar1.setValue(e.getValue());
            }
        });
        scroll.setPreferredSize(new Dimension(400, 100));
        fixedScroll.setPreferredSize(new Dimension(400, 52)); 
        getContentPane().add(scroll, BorderLayout.CENTER);
        getContentPane().add(fixedScroll, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        FixedRowExample frame = new FixedRowExample();
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.pack();
        frame.setVisible(true);
    }
}

【讨论】:

  • 也许没有理由使用两个 JTables -- 我如何在没有两个 jtables 的情况下实现它?
  • 请注意,当我向下滚动(200 行以上)时,水平对齐会逐渐关闭
  • 感谢 mKorbel;我试试看。
  • JTable.setRowMargin(int);和 JTable.setRowHeight(int);可能是正确的方式
猜你喜欢
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
相关资源
最近更新 更多