java - 如何修复 JTable 中的列以使该列始终可见

标签 java swing jtable

如何修复 JTable 中的列以使该列始终可见? 如果我使用 JViewport,则第一次表会正确,但当我第二次单击 btn 时,Jtable 中的下一列已修复,每次都会继续。

最佳答案

上面的示例中您必须创建一个固定表和一个可滚动表,这并不是最好的。我建议这样做(我只粘贴重要的行):

public class TestPaperino extends JFrame {

public TestPaperino() throws Exception {
    super("Fixed Column Example");
    setSize(400, 150);

    Object[][] data = new Object[][] { { "1", "11", "A", "", "", "", "", "" },
            { "2", "22", "", "B", "", "", "", "" }, { "3", "33", "", "", "C", "", "", "" },
            { "4", "44", "", "", "", "D", "", "" }, { "5", "55", "", "", "", "", "E", "" },
            { "6", "66", "", "", "", "", "", "F" } };
    Object[] column = new Object[] { "fixed 1", "fixed 2", "a", "b", "c", "d", "e", "f" };

    AbstractTableModel model = new AbstractTableModel() {
        public int getColumnCount() {
            return column.length;
        }

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

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

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

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

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

    JTable table = new JTable(model);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setAutoCreateRowSorter(true);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    MyAdjustmentListener hListener = new MyAdjustmentListener(table, 1, 75);
    JScrollBar hBar = new JScrollBar(Adjustable.HORIZONTAL, 0, 20, 0, 500);
    hBar.addAdjustmentListener(hListener);
    JScrollPane panel = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    JPanel panel2 = new JPanel(new BorderLayout());
    panel2.add(panel, BorderLayout.WEST);
    panel2.add(hBar, BorderLayout.SOUTH);
    add(panel2);

}

public static void main(String[] args) {
    TestPaperino frame;
    try {
        frame = new TestPaperino();
        frame.setSize(500, 500);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setVisible(true);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}


private class MyAdjustmentListener implements AdjustmentListener {

    private int last = 0;
    private BigDecimal ratio;
    private JTable table;
    private int lastFixedIndexCol;
    private int preferredWidth;

    public MyAdjustmentListener(JTable table, int lastFixedIndexCol, int preferredWidth) {
        this.table = table;
        this.lastFixedIndexCol = lastFixedIndexCol;
        this.preferredWidth = preferredWidth;
        this.initScrollBarListener();
    }

    private void initScrollBarListener() {
        int totCols = table.getColumnCount();
        int i = 0;
        int tableWidth = 0;
        int fixedWidth = 0;
        while (i < totCols) {

            TableColumn tableColumn = table.getColumnModel().getColumn(i);
            tableColumn.setWidth(preferredWidth);
            tableColumn.setMinWidth(preferredWidth);
            tableColumn.setMaxWidth(preferredWidth);
            tableColumn.setPreferredWidth(preferredWidth);
            int colwidth = table.getColumnModel().getColumn(i).getWidth();
            tableWidth = tableWidth + preferredWidth;
            fixedWidth = (i <= lastFixedIndexCol) ? (fixedWidth + colwidth) : fixedWidth;

            i++;
        }

        ratio = BigDecimal.valueOf(tableWidth - fixedWidth).divide(BigDecimal.valueOf(480),
                RoundingMode.HALF_UP);
        table.repaint();
    }

    public void adjustmentValueChanged(AdjustmentEvent e) {
        action(e);
    }

    private void action(AdjustmentEvent e) {
        int valueOnLeft = e.getValue(); 
        int diff = valueOnLeft - last;
        if (diff == 0) {
            return;
        }

        last = valueOnLeft;
        BigDecimal val = BigDecimal.valueOf(diff > 0 ? diff : -diff).multiply(ratio);
        int realDiff = diff > 0 ? val.intValue() : -val.intValue();
        if (diff > 0) {
            toRight(realDiff);
        } else if (diff < 0) {
            toLeft(preferredWidth, realDiff);
        }

    }

    private void toRight(int diff) {
        TableColumnModel columnModel2 = table.getColumnModel();
        for (int i = lastFixedIndexCol + 1; i < columnModel2.getColumnCount(); i++) {

            TableColumn column = columnModel2.getColumn(i);
            int width2 = column.getWidth();
            if (width2 == 0) {
                continue;
            }
            int appDiff = width2 - diff < 0 ? (width2) : diff;
            diff = diff - appDiff;
            action(appDiff, column, width2);
            if (diff <= 0) {
                break;
            }
        }
    }

    private void toLeft(int preferredWidth, int diff) {
        TableColumnModel columnModel2 = table.getColumnModel();
        for (int i = table.getColumnModel().getColumnCount() - 1; i > lastFixedIndexCol; i--) {             
            TableColumn column = columnModel2.getColumn(i);
            int width2 = column.getWidth();
            if (width2 < preferredWidth) {
                int appDiff = width2 - diff >= preferredWidth ? (width2 - preferredWidth) : diff;
                diff = diff - appDiff;
                action(appDiff, column, width2);
            }

            if (diff >= 0) {
                break;
            }
        }
    }

    private void action(int diff, TableColumn tableColumn, int width2) {
        tableColumn.setWidth(width2 - diff);
        tableColumn.setMinWidth(width2 - diff);
        tableColumn.setMaxWidth(width2 - diff);
        tableColumn.setPreferredWidth(width2 - diff);
    }

}
}

enter image description here

关于java - 如何修复 JTable 中的列以使该列始终可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3353933/

相关文章:

java - 当我明确地将一些键绑定(bind)分配给另一个对象时,为什么我的所有键绑定(bind)仅适用于一个对象?

java - 将 JScrollPane 和 JTextArea 添加到 JDailog 中

java - 表渲染器在 Java 中无法正常工作

java - jTable 将所有内容排序为字符串

java - 松香阈值处理(单峰阈值处理)JAVA

java - 右键单击复制 JTable 的单元格值

java - 类型转换为嵌套在泛型类中的类

Java JTable - 首先单击列以降序排序

Java:捕获未初始化的变量

java - 如何将 Maven 生成的源置于版本控制之下?