Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在用户单击单元格时向其添加内容_Java_Swing_Jtable_Cell_Changelistener - Fatal编程技术网

Java 在用户单击单元格时向其添加内容

Java 在用户单击单元格时向其添加内容,java,swing,jtable,cell,changelistener,Java,Swing,Jtable,Cell,Changelistener,我在JTable中有一个功能,当用户单击单元格时,它会删除其中的某些字符(比如当有内容-Hello,当用户单击它时,它会显示Hello)。不再编辑时,它会再次显示-Hello 我的问题是,当某个单元格被选中(但尚未编辑)并且我开始键入Hi,它不会删除字符,因此可编辑单元格看起来像-Hello Hi 同样的问题是,当选择某个单元格时,用户按空格键 我想在JTable中添加功能,这样当单元格的内容开始被编辑时(通过任何方式-点击/选择时键入/空格键/可能还有更多我不知道的选项),我想先通过编程更改内

我在JTable中有一个功能,当用户单击单元格时,它会删除其中的某些字符(比如当有内容
-Hello
,当用户单击它时,它会显示
Hello
)。不再编辑时,它会再次显示
-Hello

我的问题是,当某个单元格被选中(但尚未编辑)并且我开始键入
Hi
,它不会删除字符,因此可编辑单元格看起来像
-Hello Hi

同样的问题是,当选择某个单元格时,用户按空格键

我想在JTable中添加功能,这样当单元格的内容开始被编辑时(通过任何方式-点击/选择时键入/空格键/可能还有更多我不知道的选项),我想先通过编程更改内容。另一个选项是在选中单元格时将其删除(但我必须记住最后一个选定单元格的位置,以便将字符读入其中)

我在类TableChangeListener中尝试了propertyChange:

 table.setValueAt(removeCharacter(table.getValueAt(row,column)), row, column);

但是它不起作用,因为单元格已经被编辑,我无法更改它。

我认为您根本不应该更改单元格的内容。
您需要在表上设置一个呈现单元格值的
TableCellRenderer
。实现单元渲染器,使其显示值“-Hello”(尽管实际数据可能只包含“Hello”)。渲染器只显示表中所需的任何组件。当用户开始编辑单元格时,不会显示渲染器组件。实际上,您也可以使用
TableCellEditor

操作编辑组件。我认为您根本不应该更改单元格的内容。 您需要在表上设置一个呈现单元格值的
TableCellRenderer
。实现单元渲染器,使其显示值“-Hello”(尽管实际数据可能只包含“Hello”)。渲染器只显示表中所需的任何组件。当用户开始编辑单元格时,不会显示渲染器组件。实际上,您还可以使用
TableCellEditor
操作编辑组件

  • 您必须使用自己的单元编辑器实现来满足自己的需求集
  • 因此,创建一个自定义CellEditor,实现
    FocusLisetener
    ActionListener
    并实现
    FocusGovered
    FocusLost
    功能
  • 执行
    actionPerformed
    功能,以在按下enter键时更新值
  • 处理焦点事件有点棘手。因为它会错误地更新单元格。这就是为什么我必须将引用表作为构造函数参数传递给
    CellEditor
    ,并读取单元格行col on Focus gain
  • 要反映
    -xxxx
    :将
    -
    放在单元格值之前,请尝试使用自定义的
    单元格渲染器。查看示例以了解详细信息。这部分功劳归@mKobel所有
    一个实现的方向自定义单元格编辑器:将其分配给目标表列并进行测试

    Giff我的测试结果:

    class CustomRenderer extends DefaultTableCellRenderer {
    
         public void setValue(Object value) 
         {
             setText("- "+value);
          }
      }
    
    class MyCellEditor extends AbstractCellEditor
                             implements TableCellEditor,
                                        FocusListener,
                                        ActionListener
    {
        JTextField textFeild;
        String currentValue;
    
        JTable table;
        int row, col;
        public MyCellEditor(JTable table) {
            this.table = table;
            textFeild = new JTextField();
            textFeild.addActionListener(this);
            textFeild.addFocusListener(this);
        }
    
    
        @Override
        public Object getCellEditorValue() {
            return currentValue;
        }
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    
            currentValue = (String)value;
            return textFeild;
    
        }
    
        @Override
        public void focusGained(FocusEvent e) {
            textFeild.setText("");
            row = table.getSelectedRow();
            col = table.getSelectedColumn();
    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
    
            if(!textFeild.getText().equals(""))
               //currentValue = textFeild.getText();
               table.setValueAt(textFeild.getText(), row, col);
    
            fireEditingStopped();
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
           if(!textFeild.getText().trim().equals(""))
               currentValue = textFeild.getText();
           fireEditingStopped();
        }
    
    
    }
    

    代码:

    class CustomRenderer extends DefaultTableCellRenderer {
    
         public void setValue(Object value) 
         {
             setText("- "+value);
          }
      }
    
    class MyCellEditor extends AbstractCellEditor
                             implements TableCellEditor,
                                        FocusListener,
                                        ActionListener
    {
        JTextField textFeild;
        String currentValue;
    
        JTable table;
        int row, col;
        public MyCellEditor(JTable table) {
            this.table = table;
            textFeild = new JTextField();
            textFeild.addActionListener(this);
            textFeild.addFocusListener(this);
        }
    
    
        @Override
        public Object getCellEditorValue() {
            return currentValue;
        }
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    
            currentValue = (String)value;
            return textFeild;
    
        }
    
        @Override
        public void focusGained(FocusEvent e) {
            textFeild.setText("");
            row = table.getSelectedRow();
            col = table.getSelectedColumn();
    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
    
            if(!textFeild.getText().equals(""))
               //currentValue = textFeild.getText();
               table.setValueAt(textFeild.getText(), row, col);
    
            fireEditingStopped();
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
           if(!textFeild.getText().trim().equals(""))
               currentValue = textFeild.getText();
           fireEditingStopped();
        }
    
    
    }
    
  • 您必须使用自己的单元编辑器实现来满足自己的需求集
  • 因此,创建一个自定义CellEditor,实现
    FocusLisetener
    ActionListener
    并实现
    FocusGovered
    FocusLost
    功能
  • 执行
    actionPerformed
    功能,以在按下enter键时更新值
  • 处理焦点事件有点棘手。因为它会错误地更新单元格。这就是为什么我必须将引用表作为构造函数参数传递给
    CellEditor
    ,并读取单元格行col on Focus gain
  • 要反映
    -xxxx
    :将
    -
    放在单元格值之前,请尝试使用自定义的
    单元格渲染器。查看示例以了解详细信息。这部分功劳归@mKobel所有
    一个实现的方向自定义单元格编辑器:将其分配给目标表列并进行测试

    Giff我的测试结果:

    class CustomRenderer extends DefaultTableCellRenderer {
    
         public void setValue(Object value) 
         {
             setText("- "+value);
          }
      }
    
    class MyCellEditor extends AbstractCellEditor
                             implements TableCellEditor,
                                        FocusListener,
                                        ActionListener
    {
        JTextField textFeild;
        String currentValue;
    
        JTable table;
        int row, col;
        public MyCellEditor(JTable table) {
            this.table = table;
            textFeild = new JTextField();
            textFeild.addActionListener(this);
            textFeild.addFocusListener(this);
        }
    
    
        @Override
        public Object getCellEditorValue() {
            return currentValue;
        }
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    
            currentValue = (String)value;
            return textFeild;
    
        }
    
        @Override
        public void focusGained(FocusEvent e) {
            textFeild.setText("");
            row = table.getSelectedRow();
            col = table.getSelectedColumn();
    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
    
            if(!textFeild.getText().equals(""))
               //currentValue = textFeild.getText();
               table.setValueAt(textFeild.getText(), row, col);
    
            fireEditingStopped();
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
           if(!textFeild.getText().trim().equals(""))
               currentValue = textFeild.getText();
           fireEditingStopped();
        }
    
    
    }
    

    代码:

    class CustomRenderer extends DefaultTableCellRenderer {
    
         public void setValue(Object value) 
         {
             setText("- "+value);
          }
      }
    
    class MyCellEditor extends AbstractCellEditor
                             implements TableCellEditor,
                                        FocusListener,
                                        ActionListener
    {
        JTextField textFeild;
        String currentValue;
    
        JTable table;
        int row, col;
        public MyCellEditor(JTable table) {
            this.table = table;
            textFeild = new JTextField();
            textFeild.addActionListener(this);
            textFeild.addFocusListener(this);
        }
    
    
        @Override
        public Object getCellEditorValue() {
            return currentValue;
        }
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    
            currentValue = (String)value;
            return textFeild;
    
        }
    
        @Override
        public void focusGained(FocusEvent e) {
            textFeild.setText("");
            row = table.getSelectedRow();
            col = table.getSelectedColumn();
    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
    
            if(!textFeild.getText().equals(""))
               //currentValue = textFeild.getText();
               table.setValueAt(textFeild.getText(), row, col);
    
            fireEditingStopped();
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
           if(!textFeild.getText().trim().equals(""))
               currentValue = textFeild.getText();
           fireEditingStopped();
        }
    
    
    }
    
    摘自:

    该表显示了“5美元”“20欧元”等价格,以及用户单击单元格时的价格 要改变价格,我想让标志消失。当用户 完成编辑(单击enter或其他方式),我希望符号 再次出现

    尽管@Sage post是一个非常好的通用解决方案(+1:),但在这种情况下,我将实现一个和使用它来管理货币格式问题,如下所示:

    • 为渲染器组件设置常规数字格式:
    • 为编辑器组件设置货币编号格式:
    这样,当显示单元格时,将显示货币符号,但当编辑单元格时,货币符号将“消失”

    请看以下实施示例:

    import java.awt.Color;
    import java.awt.Component;
    import java.awt.event.MouseEvent;
    import java.text.NumberFormat;
    import java.util.EventObject;
    import java.util.Locale;
    import javax.swing.AbstractCellEditor;
    import javax.swing.BorderFactory;
    import javax.swing.JFormattedTextField;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.border.Border;
    import javax.swing.table.TableCellEditor;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.text.NumberFormatter;
    
    public class CurrencyEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
    
        JFormattedTextField editor;
        JFormattedTextField renderer;
        Integer clickCountToStart = 2;
    
        public CurrencyEditor(Locale locale) {
            initEditor(locale);
            initRenderer(locale);
        }
    
        private void initRenderer(Locale locale) {
            NumberFormat format = locale != null ? 
                                            NumberFormat.getCurrencyInstance(locale) : NumberFormat.getCurrencyInstance();
    
            NumberFormatter formatter = new NumberFormatter(format);
            formatter.setMinimum(Double.MIN_VALUE);
            formatter.setMaximum(Double.MAX_VALUE);
            formatter.setAllowsInvalid(false);
            renderer = new JFormattedTextField(formatter);
        }
    
        private void initEditor(Locale locale) {
            NumberFormat format = locale != null ? 
                                            NumberFormat.getNumberInstance(locale) : NumberFormat.getNumberInstance();
    
            NumberFormatter formatter = new NumberFormatter(format);
            formatter.setMinimum(Double.MIN_VALUE);
            formatter.setMaximum(Double.MAX_VALUE);
            formatter.setAllowsInvalid(false);
            editor = new JFormattedTextField(formatter);
            editor.setBorder(UIManager.getBorder("Tree.editorBorder"));
        }
    
        @Override
        public Object getCellEditorValue() {
            return editor.getValue();
        }
    
        @Override
        public boolean isCellEditable(EventObject anEvent) {
            if (anEvent instanceof MouseEvent) {
                return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
            }
            return true;
        }
    
        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }
    
        @Override
        public boolean stopCellEditing() {
            fireEditingStopped();
            return true;
        }
    
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            if(value instanceof Double){
                editor.setValue(value);
            }
            return editor;
        }
    
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    
            if(value instanceof Double) {            
                Color background = isSelected ? UIManager.getColor("Table.selectionBackground") : UIManager.getColor("Table.background");
                Color foreground = isSelected ? UIManager.getColor("Table.selectionForeground") : UIManager.getColor("Table.foreground");
                Border border = hasFocus ? UIManager.getBorder("Table.focusCellHighlightBorder") : BorderFactory.createEmptyBorder();
    
                renderer.setBackground(background);
                renderer.setForeground(foreground);
                renderer.setBorder(border);
    
                renderer.setValue(value);
                return renderer;
    
            } else {
                String message = String.format("Not supported for %1$1s class!", value.getClass());
                throw new IllegalArgumentException(message);
            }
        }
    
    }
    
    免责声明:它可能无法与Nimbus外观一起正常工作,因为UIManager属性的名称不同。我用金属、窗户、经典窗户和Motif进行了测试

    下面是我用来测试它的代码:

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.util.Locale;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableColumn;
    
    public class Demo {
    
        private void initGUI(){
    
            DefaultTableModel model = new DefaultTableModel(new Object[]{"Item", "Price USD", "Price EUR"}, 0);
            model.addRow(new Object[]{"Fender stratocaster", 1599.99d, 1176.46d});
            model.addRow(new Object[]{"Gibson Les Paul", 1299.99d, 955.87d});
            model.addRow(new Object[]{"Pual Reed Smith Standard 24", 1999.99d, 1470.58d});
    
            JTable table = new JTable(model);
            table.setPreferredScrollableViewportSize(new Dimension(500, 300));
    
            TableColumn priceUSD = table.getColumn("Price USD");
            priceUSD.setCellRenderer(new CurrencyEditor(Locale.US));
            priceUSD.setCellEditor(new CurrencyEditor(Locale.US));
    
            TableColumn priceEUR = table.getColumn("Price EUR");
            priceEUR.setCellRenderer(new CurrencyEditor(Locale.GERMANY));
            priceEUR.setCellEditor(new CurrencyEditor(Locale.GERMANY));
    
            JPanel content = new JPanel(new BorderLayout());
            content.add(new JScrollPane(table));
    
            JFrame frame = new JFrame("Demo");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.getContentPane().add(content);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Demo().initGUI();                
                }
            });
        }    
    }
    
    截图 摘自:

    该表显示了“5美元”“20欧元”等价格,以及用户单击单元格时的价格 要改变价格,我想让标志消失。当用户 完成编辑(单击enter或其他方式),我希望符号 再次出现

    尽管@Sage post是一个非常好的通用解决方案(+1:),但在这种情况下,我将实现一个和使用它来管理货币格式问题,如下所示:

    • 为渲染器组件设置常规数字格式:
    • 为编辑器组件设置货币编号格式:
    这样当cel