当前位置: 首页 > 面试题库 >

TableModel setCellEditable并自动将值设置回false

臧欣怿
2023-03-14
问题内容

我目前正在尝试在JTable中实现一个JPopupMenu,该菜单允许使用

@Override 
public void actionPerformed(ActionEvent e){
    if(e.getActionCommand() == "Unlock"){
        pTableModel.setCellEditable(this.getSelectedRow(), this.getSelectedColumn(), true);
    }
}

这是TableModel中的相关方法

public void setCellEditable(int row, int col, boolean value) {
    editableCells[row][col] = value;
    this.fireTableCellUpdated(row, col); // I don't think I actually need this 
                                         //because nothing in the cell has changed yet?
}

isCellEditable()然后返回editableCells []
[]数组的值。但是当失去焦点时,我应该在代码的哪个位置将单元格改回不可编辑状态?

稍微相关一点,我也想让这个小组立即获得关注。我已经读过getEditorComponent().requestFocus()-但这似乎不太正确,因为当时没有进行任何编辑,仅选择了单元格(使用该方法会抛出nullpointerexception,这似乎支持我的思维过程)。

有人能指出我正确的方向吗?我看不到我要去哪里错了。谢谢

**编辑:为了在失去焦点时锁定单元格,我尝试添加带有focusListener的自定义cellrenderer:

private class CustomCellRenderer extends DefaultTableCellRenderer{
    public CustomCellRenderer(){
        addFocusListener(new FocusAdapter(){
            @Override
            public void focusLost(FocusEvent e) {
                pTableModel.setCellEditable(getSelectedRow(), getSelectedColumn(), false);

            }
        });
    }
}

但这似乎也不起作用,但是我可能实现不正确(尽管我已经检查了渲染器的添加)

社会科学中心

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

public class CellTest {    
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                createAndShowGUI();
            }
        });
    }
    private static void createAndShowGUI(){
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MyPanel panel = new MyPanel();

        f.add(panel);
        f.pack();
        f.setVisible(true);
    }
}


class MyPanel extends JPanel implements ActionListener{
    private JTable table;
    private MyTableModel model;
    private JScrollPane sp;
    private List<Person> people;

    MyPanel(){
        people = new ArrayList<>();
        people.add(new Person("Will", 1));
        model = new MyTableModel(people);

        table = new JTable(model);
        table.addMouseListener(new MouseAdapter(){
            @Override
            public void mousePressed(MouseEvent e){
                maybeShowPopup(e);
            }
            @Override
            public void mouseReleased(MouseEvent e){
                maybeShowPopup(e);
            }
        });

        table.setFillsViewportHeight(true);
        sp = new JScrollPane(table);  
        this.add(sp);
    }

    @Override
    public void actionPerformed(ActionEvent e){
        if(e.getActionCommand().equals("Unlock")) {
                model.setCellEditable(table.getSelectedRow(),table.getSelectedColumn(),true);   
        }
    }

    private JPopupMenu createPopupMenu(){
        JPopupMenu pop = new JPopupMenu();
        JMenuItem item = new JMenuItem("Unlock");
        item.addActionListener(this);
        pop.add(item);
        return pop;
    }

    private void maybeShowPopup(MouseEvent e){
        int currentRow = table.rowAtPoint(e.getPoint());
        if(currentRow >= 0 && currentRow < table.getRowCount())
            table.setRowSelectionInterval(currentRow, currentRow);
        else
            table.clearSelection();

        if(table.getSelectedRow() < 0) return;
        if(e.isPopupTrigger() && e.getComponent() instanceof JTable){
            JPopupMenu pop = createPopupMenu();
            pop.show(e.getComponent(), e.getX(), e.getY());
        }
    }
}

以及TableModel和数据类:

class MyTableModel extends AbstractTableModel{
    private List<Person> data;  
    private String[] colNames = new String[]{"Name","Age"};
    private boolean[][] editableCells;

    public MyTableModel(List<Person> data){
        this.data = data;
        this.editableCells = new boolean[this.getRowCount()][this.getColumnCount()];
    }

    @Override
    public int getRowCount() { return data.size(); }

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

    @Override
    public Object getValueAt(int row, int col){
        Person p = data.get(row);
        switch(col){
            case 0 : return p.getName();
            case 1 : return p.getAge();
        }
        return null;
    }

    @Override
    public boolean isCellEditable(int row, int col){
        return editableCells[row][col];
    }

    public void setCellEditable(int row, int col, boolean value){
        editableCells[row][col] = value;
    }

    @Override
    public void setValueAt(Object value, int row, int col){
        Person p = data.get(row);
        switch(col){
            case 0 : p.setName((String)value);break;
            case 1 : p.setAge((int)value);break;
        }
        this.setCellEditable(row, col, false);
        this.fireTableCellUpdated(row, col);
    }

    public void setData(List<Person> data){
        this.data = data;
        this.fireTableDataChanged();
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    public void setName(String name){ this.name = name;}
    public String getName(){ return name; }
    public void setAge(int age){ this.age = age;}
    public int getAge(){ return age; }
}

很抱歉,我不知道如何缩短长度,而又可能无法很好地重建我想要达到的目标。这段代码有一个错误,就是右键单击并“解锁”,您必须已经左键单击了一行,否则它们将成为arrayIndexOutOfBounds异常。我还没有找到确切的原因。

但是基本上,当您右键单击然后选择解锁时,我希望光标出现在单元格中。此刻,您单击解锁,然后必须双击该单元格。


问题答案:

但是当失去焦点时,我应该在代码的哪个位置将单元格改回不可编辑状态?--

你可以:

  1. setValueAt(...)更改数据后,重写TableModel 的方法以使单元格不可编辑。

  2. 使用TableModelListener单元格数据更新时,它将生成一个事件。



 类似资料:
  • 我正在阅读https://ci.apache.org/projects/flink/flink-docs-release-1.13/docs/connectors/datastream/kafka/#kafka-消费者补偿提交行为配置 它说: 启用检查点:如果启用了检查点,Flink Kafka使用者将在检查点完成时提交存储在检查点状态中的偏移量。这确保了Kafka代理中提交的偏移量与检查点状态中

  • 问题内容: 我有一个带有两个表的SQL Server 2008数据库。第一个表称为Department。第二个表称为票证。这两个表的定义如下: 我正在尝试找出一种动态更新Department.TotalTickets值的方法。当添加或删除工单时,我想自动增加或减少TotalTickets的值。有人可以告诉我在SQL Server 2008上执行此操作的最佳方法吗? 谢谢 问题答案: 有多种方法可以

  • 问题内容: 我想将用户持久保存到数据库中,并使用IDENTITY生成类型创建的User的ID(PK)的当前方案。例如 但我想在以下情况下进行操作:1)用户明确设置。2)如果未设置用户,则将自动分配它,并且它必须是唯一的。 请建议我一些可用的选项,以便我解决。谢谢。 问题答案: 您可以为此目的定义您的自定义ID生成器,如本SOAnswer中指出的那样 它的代码如下所示: 和

  • 例如,我正在创建下表: 创建人员表( 据我所知,Auto增量的值可以通过Alter表修改,如下所示 更改表人员AUTO_INCREMENT=100; 但我只是想知道,在创建表时是否有一种方法可以设置自动增量的值<像这样的事? 创建人员表(

  • 我正在尝试启动一个活动,其中包括捆绑包。我正在尝试将这个捆绑包设置为空,因为还没有任何东西传递给这个活动。 目前,Android系统导致活动崩溃。未找到资源错误 编辑添加错误日志 08-24 10:39:33.180:E/AndroidRuntime(21177):致命异常:main 08-24 10:39:33.180:E/AndroidRuntime(21177):java。lang.Runt