在JTable中显示行选择器(光标/指针)

ist

我正在将MS-Access应用程序迁移到Java。我关心的是数据网格。我的第一个是可以的(JScrollPane中的JTable),但是缺少您可以在MS-Access网格或OpenOffice Base网格中看到的行选择器(光标)。所谓“行选择器”,是指该行左侧的黑色小箭头。是否有使用JTable实现此视觉效果的标准方法。(我还想知道此缺失功能背后的原理:Sun试图通过不实施它来避免什么问题(如果有)?)。

谢谢。

-编辑:Camickr,我已经将您的代码段与您在编辑中显示的修改一起使用了。效果很好!谢谢 !!!

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

/*
 *    Use a JTable as a renderer for row numbers of a given main table.
 *  This table must be added to the row header of the scrollpane that
 *  contains the main table.
 */
public class RowNumberTable extends JTable
    implements ChangeListener, PropertyChangeListener, TableModelListener
{
    private JTable main;

    public static void main(String[] args) {
        JTable mainTable = new JTable(new MyTableModel());
        mainTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane scrollPane = new JScrollPane(mainTable);
        RowNumberTable rowTable = new RowNumberTable(mainTable);
        rowTable.getSelectionModel()
            .addListSelectionListener(rowTable.new RowListener());
        scrollPane.setRowHeaderView(rowTable);
        scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());

        // Create a panel to hold all other components
        JPanel topPanel = new JPanel();
        topPanel.setLayout( new BorderLayout() );
        topPanel.add( scrollPane, BorderLayout.CENTER );

        // Set the frame characteristics
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle( "Selector" );
        frame.setBackground( Color.gray );
        frame.getContentPane().add( topPanel );
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public RowNumberTable(JTable table)
    {
        main = table;
        main.addPropertyChangeListener( this );
        main.getModel().addTableModelListener( this );

        setFocusable( false );
        setAutoCreateColumnsFromModel( false );
        setSelectionModel( main.getSelectionModel() );

        TableColumn column = new TableColumn();
        column.setHeaderValue(" ");
        addColumn( column );
        column.setCellRenderer(new RowNumberRenderer());

        getColumnModel().getColumn(0).setPreferredWidth(22);
        setPreferredScrollableViewportSize(getPreferredSize());
    }

    @Override
    public void addNotify()
    {
        super.addNotify();

        Component c = getParent();

        //  Keep scrolling of the row table in sync with the main table.

        if (c instanceof JViewport)
        {
            JViewport viewport = (JViewport)c;
            viewport.addChangeListener( this );
        }
    }

    /*
     *  Delegate method to main table
     */
    @Override
    public int getRowCount()
    {
        return main.getRowCount();
    }

    @Override
    public int getRowHeight(int row)
    {
        int rowHeight = main.getRowHeight(row);

        if (rowHeight != super.getRowHeight(row))
        {
            super.setRowHeight(row, rowHeight);
        }

        return rowHeight;
    }

    /*
     *  No model is being used for this table so just use the row number
     *  as the value of the cell.
     */
    @Override
    public Object getValueAt(int row, int column)
    {
        //return Integer.toString(row + 1);
        if (main.isRowSelected(row))
            return "\u25BA"; // Unicode Black Right-pointing Pointer
        else
            return " ";
    }

    /*
     *  Don't edit data in the main TableModel by mistake
     */
    @Override
    public boolean isCellEditable(int row, int column)
    {
        return false;
    }

    /*
     *  Do nothing since the table ignores the model
     */
    @Override
    public void setValueAt(Object value, int row, int column) {}

    //
    //  Implement the ChangeListener
    //
    public void stateChanged(ChangeEvent e)
    {
        //  Keep the scrolling of the row table in sync with main table

        JViewport viewport = (JViewport) e.getSource();
        JScrollPane scrollPane = (JScrollPane)viewport.getParent();
        scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
    }

    //
    //  Implement the PropertyChangeListener
    //
    public void propertyChange(PropertyChangeEvent e)
    {
        //  Keep the row table in sync with the main table

        if ("selectionModel".equals(e.getPropertyName()))
        {
            setSelectionModel( main.getSelectionModel() );
        }

        if ("rowHeight".equals(e.getPropertyName()))
        {
            repaint();
        }

        if ("model".equals(e.getPropertyName()))
        {
            main.getModel().addTableModelListener( this );
            revalidate();
        }
    }

    //
    //  Implement the TableModelListener
    //
    @Override
    public void tableChanged(TableModelEvent e)
    {
        revalidate();
    }

    /*
     *  Attempt to mimic the table header renderer
     */
    private static class RowNumberRenderer extends DefaultTableCellRenderer
    {
        public RowNumberRenderer()
        {
            setHorizontalAlignment(JLabel.CENTER);
        }

        public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column)
        {
            if (table != null)
            {
                JTableHeader header = table.getTableHeader();

                if (header != null)
                {
                    setForeground(header.getForeground());
                    setBackground(header.getBackground());
                    setFont(header.getFont());
                }
            }

            setText((value == null) ? "" : value.toString());
            setBorder(UIManager.getBorder("TableHeader.cellBorder"));

            return this;
        }
    }

    private class RowListener implements ListSelectionListener {
        public void valueChanged(ListSelectionEvent event) {
            if (event.getValueIsAdjusting()) {
                return;
            }
            int row =  main.getSelectedRow();
            System.out.println("selected row : "  +
                main.getSelectionModel().getLeadSelectionIndex() + " - " +
                main.getModel().getValueAt(row, 0) ); 
        }
    }
}

class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {"First Name",
        "Last Name",
        "Sport",
        "# of Years",
        "Vegetarian"};
    private Object[][] data = {
        {"Kathy", "Smith",
            "Snowboarding", new Integer(5), new Boolean(false)},
        {"John", "Doe",
            "Rowing", new Integer(3), new Boolean(true)},
        {"Sue", "Black",
            "Knitting", new Integer(2), new Boolean(false)},
        {"Jane", "White",
            "Speed reading", new Integer(20), new Boolean(true)},
        {"Joe", "Brown",
            "Pool", new Integer(10), new Boolean(false)}
        };

    public int getColumnCount() {
        return columnNames.length;
    }

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

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

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

    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
}
卡米克尔

您将需要在滚动窗格中添加“行标题”。

请查看“行号表”以获取此方法的示例。默认实现将行号显示为当前选定的行以粗体显示。

如果需要,可以自定义渲染器以显示“箭头图标”而不是粗体。

编辑:

您需要对原始代码进行的唯一更改如下:

@Override
public Object getValueAt(int row, int column)
{
    //return Integer.toString(row + 1);
    if (main.isRowSelected(row))
        return "\u25BA";
    else
        return " ";
}

不需要ListSelectionListener。您可以仅在呈现行时查询行选择。

无需将TableModel传递给RowTableModel的构造函数。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在选择器中显示数据

来自分类Dev

在选择器中显示数据集

来自分类Dev

PO行帐户选择器选择未显示在字段中

来自分类Dev

使用jscolor颜色选择器向表添加了行,但选择器未显示

来自分类Dev

我如何在列项目日期的 jtable 中添加日期选择器和时间选择器?

来自分类Dev

显示日期选择器

来自分类Dev

如何使背景img显示在:after选择器中?

来自分类Dev

根据Sling选择器在Sightly中显示不同的标记

来自分类Dev

Bootstrap日期时间选择器未在mvc中显示

来自分类Dev

颜色选择器未显示在我的代码中

来自分类Dev

反应本地选择器未显示在Android中

来自分类Dev

显示/隐藏长列表选择器模板中的控件

来自分类Dev

shieldui日期选择器不会显示在aspx中

来自分类Dev

在ComboBox-颜色选择器中显示颜色列表

来自分类Dev

在Cheerio中无法显示选择器内容

来自分类Dev

rtl datepicker:日期选择器显示中的问题

来自分类Dev

Xamarin选择器未显示列表中的日期

来自分类Dev

在SwiftUI中以固有尺寸显示分段选择器

来自分类Dev

如何在日期选择器中显示所选日期?

来自分类Dev

Android中的数字选择器无法正确显示

来自分类Dev

Bootstrap日期时间选择器未在mvc中显示

来自分类Dev

尝试让选择器{}显示在SmartFace App Studio中

来自分类Dev

显示/隐藏长列表选择器模板中的控件

来自分类Dev

在 html 页面中显示日历(日期选择器)

来自分类Dev

选择器选择的Swiftui显示项目

来自分类Dev

在Kendo内联编辑中仅显示日期选择器,而不显示日期时间选择器

来自分类Dev

在Kendo内联编辑中仅显示日期选择器,而不显示日期时间选择器

来自分类Dev

在合金的选择器中添加一行

来自分类Dev

在选择器中串联

Related 相关文章

  1. 1

    在选择器中显示数据

  2. 2

    在选择器中显示数据集

  3. 3

    PO行帐户选择器选择未显示在字段中

  4. 4

    使用jscolor颜色选择器向表添加了行,但选择器未显示

  5. 5

    我如何在列项目日期的 jtable 中添加日期选择器和时间选择器?

  6. 6

    显示日期选择器

  7. 7

    如何使背景img显示在:after选择器中?

  8. 8

    根据Sling选择器在Sightly中显示不同的标记

  9. 9

    Bootstrap日期时间选择器未在mvc中显示

  10. 10

    颜色选择器未显示在我的代码中

  11. 11

    反应本地选择器未显示在Android中

  12. 12

    显示/隐藏长列表选择器模板中的控件

  13. 13

    shieldui日期选择器不会显示在aspx中

  14. 14

    在ComboBox-颜色选择器中显示颜色列表

  15. 15

    在Cheerio中无法显示选择器内容

  16. 16

    rtl datepicker:日期选择器显示中的问题

  17. 17

    Xamarin选择器未显示列表中的日期

  18. 18

    在SwiftUI中以固有尺寸显示分段选择器

  19. 19

    如何在日期选择器中显示所选日期?

  20. 20

    Android中的数字选择器无法正确显示

  21. 21

    Bootstrap日期时间选择器未在mvc中显示

  22. 22

    尝试让选择器{}显示在SmartFace App Studio中

  23. 23

    显示/隐藏长列表选择器模板中的控件

  24. 24

    在 html 页面中显示日历(日期选择器)

  25. 25

    选择器选择的Swiftui显示项目

  26. 26

    在Kendo内联编辑中仅显示日期选择器,而不显示日期时间选择器

  27. 27

    在Kendo内联编辑中仅显示日期选择器,而不显示日期时间选择器

  28. 28

    在合金的选择器中添加一行

  29. 29

    在选择器中串联

热门标签

归档