【问题标题】:JTable focus on entire row instead of cellJTable 专注于整行而不是单元格
【发布时间】:2016-11-06 00:36:58
【问题描述】:

有没有办法强制 JTable 专注于整行而不是单个单元格?我不是在谈论行选择突出显示,只是关于我想包含焦点行上的所有单元格的焦点边框。

更新:

具有不可编辑单元格和删除行功能的表格:

public class TableTest {

    private static void createAndShowGUI() {

        int rows = 20;
        int cols = 2;
        String[] headers = { "Column 1", "Column 2" };
        String[][] data = new String[rows][cols];

        for (int j = 0; j < rows; j++)
            for (int k = 0; k < cols; k++)
                data[j][k] = "item " + (j * cols + k + 1);

        JTable table = new JTable();

        DefaultTableModel tableModel = new DefaultTableModel(data, headers) {
            // Disable editing of the cells
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        table.setModel(tableModel);
        table.setShowGrid(false);
        table.setIntercellSpacing(new Dimension(0,0));

        // key binding to remove rows
        InputMap inputMap = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap actionMap = table.getActionMap();
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "REMOVE");
        actionMap.put("REMOVE", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int[] rows = table.getSelectedRows();     
                for (int i = rows.length - 1; i >= 0; i--) {
                    tableModel.removeRow(rows[i]);
                }
            }
        });

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(table));
        f.setSize(500, 500);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    //UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {}
                createAndShowGUI();
            }
        });
    }
}

选定行上的“焦点边框”:

未选择行的“焦点边框”:

Windows LAF 中的“焦点边框”:

我希望这个“焦点边框”包含该行的所有单元格(当可见时)。

下面是相同的代码,但我添加了@camickr 的部分代码:

public class TableTest {

    private static void createAndShowGUI() {

        int rows = 20;
        int cols = 2;
        String[] headers = { "Column 1", "Column 2" };
        String[][] data = new String[rows][cols];

        for (int j = 0; j < rows; j++)
            for (int k = 0; k < cols; k++)
                data[j][k] = "item " + (j * cols + k + 1);


        // ADDED CODE
        JTable table = new JTable() {

            private Border outside = new MatteBorder(1, 0, 1, 0, Color.BLACK);
            private Border inside = new EmptyBorder(0, 1, 0, 1);
            private Border border = new CompoundBorder(outside, inside);

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                JComponent jc = (JComponent) c;
                // Add a border to the selected row
                if (isRowSelected(row)) jc.setBorder(border);
                return c;
            }
        };


        DefaultTableModel tableModel = new DefaultTableModel(data, headers) {
            // Disable editing of the cells
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        table.setModel(tableModel);
        table.setShowGrid(false);
        table.setIntercellSpacing(new Dimension(0,0));

        // key binding to remove rows
        InputMap inputMap = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap actionMap = table.getActionMap();
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "REMOVE");
        actionMap.put("REMOVE", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int[] rows = table.getSelectedRows();     
                for (int i = rows.length - 1; i >= 0; i--) {
                    tableModel.removeRow(rows[i]);
                }
            }
        });

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(table));
        f.setSize(500, 500);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    //UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {}
                createAndShowGUI();
            }
        });
    }
}

这会在整行周围添加一个边框(但没有左/右插入以包含所有单元格)。这不是“焦点边框/矩形”,它是仅出现在选定行周围的边框。当我删除一行时,所选行被清除,焦点边框重新出现。

请注意,我确实想要隐藏焦点边框(我知道该怎么做),我想保持它的功能,但要包括该行的所有单元格而不是一个单元格当它变得可见时。

【问题讨论】:

  • 整行焦点的预期含义是什么?键盘输入应该去哪里?或者这只是一个显示问题,您想在整个行周围显示FocusBorder
  • 我只想在整行周围显示 FocusBorder。顺便说一句,这些单元格是不可编辑的。
  • 没有。焦点在那里显示当您开始键入时键盘输入的位置。做你想做的事违反惯例,并且没有被设计成框架。唯一的选择是在每列的自定义单元格渲染器中自己绘制焦点边框。这在一般情况下很难正确处理,因为用户可以重新排列列。更简单的解决方案是根本不使用 JTable,而是使用带有单个自定义单元格渲染器的 JList。
  • @Andrew Butenko 谢谢,我会看看 JList

标签: java swing jtable


【解决方案1】:

我只想在整行周围显示 FocusBorder。

看看Table Row Rendering

它展示了一种在行上放置边框而不是单个单元格的方法。

【讨论】:

  • 感谢您的建议,但这并不是我想要的,因为这不是实际的焦点边框。我试过了,它只适用于选定的行。当没有选择行但焦点边框可见时,它仍然占据一个单元格而不是全部。
  • @AndroidX, it works only for selected rows. - 一次只有一行可以接受输入,所以边框只会在一行上。我没有看到带有我建议的代码的单个单元格的边框。没有连续的“FocusBorder”之类的东西。正如已经提到的,只有一个单元格可以接受输入,所以只有一个单元格可以有一个看起来像虚线的边框。您需要通过发布正确的SSCCE 来阐明您的问题,该SSCCE 展示了您想要更改的行为。
  • 如果您不喜欢“红色边框”,那么您可以提供自己的“焦点边框”。我只是向你展示了一个概念。您可以自定义概念以满足您的实际需求。
  • 我没有提供 SSCCE,因为我认为这是基本的 JTable 功能。无论如何,我已经编辑了我的问题。
  • There is no such thing as a "FocusBorder" for a row. As has already been mentioned, only a cell can accept input so only a cell can have an Border that looks like a dotted line. 我想这回答了我的问题......“你做不到”。如果您将其包含在答案中,我会接受。
猜你喜欢
  • 2015-08-04
  • 2015-08-03
  • 2019-06-06
  • 2011-09-21
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多