使用 EditorDelegate 监控 JTable 中的 EditingStarted 和 EditingStopped

问题描述 投票:0回答:1

当尝试监视单元格编辑的开始和停止时,我发现了

DefaultCellEditor.EditorDelegate
类,其中包含有前途的方法
startCellEditing(EventObject anEvent)
。下面的代码的第一个版本没有
MouseListener
startCellEditing(...)
从未被解雇。查看来源 说明了原因:该方法的单行内容为
return true

由于
fireEditingStarted()
方法不存在,所以我添加了
MouseListener
编辑器组件侦听编辑启动双击,然后调用
startCellEditing(...)
。但
MouseListener
也不会被解雇。
那么如何让
startCellEditing(...)
继续下去呢?

附注:
我知道可以通过覆盖

JTable
来监视编辑的开始
prepareEditor(...)
,但我仍然想看看代码中缺少什么。

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

public class MonitorEditingStartStopped extends JFrame {

  public MonitorEditingStartStopped() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(220, 150);
    setLocationRelativeTo(null);

    String headers[] = {"Fruit", "Count", "Profit"};
    Object data[][] = {
        {"Apple", 6, -0.3},
        {"Banana", 3, 0.4},
        {"Cherry", 10, 1.},
        {"Date", -3, -1.}
      };

    DefaultTableModel model= new DefaultTableModel(headers, 0) {
      public Class<?> getColumnClass(int column) {
        Class<?> returnValue;
        if (getRowCount()>0 && getValueAt(0, column)!=null)
          returnValue= getValueAt(0, column).getClass();
        else
          returnValue= Object.class;
        return returnValue;
      }
    };
    for (int i=0; i<data.length; i++) {
      model.addRow(data[i]);
    }
    JTable table= new JTable(model);
    JTextField tf= new JTextField(10);
    tf.setHorizontalAlignment(SwingConstants.RIGHT);
    StartStopEditor editor= new StartStopEditor(table, tf);
    TableColumnModel tcm= table.getColumnModel();
    tcm.getColumn(1).setCellEditor(editor);
    JScrollPane scrollPane= new JScrollPane(table);
    add(scrollPane, BorderLayout.CENTER);
    setVisible(true);
  }


  public static void main(String args[]) {
    EventQueue.invokeLater(MonitorEditingStartStopped::new);
  }


  class StartStopEditor extends DefaultCellEditor {
    public StartStopEditor(JTable table, JTextField tf) {
      super(tf);
      delegate= new EditorDelegate() {
        @Override
        public Object getCellEditorValue() {
          if (tf.getText().isBlank()) return Integer.valueOf(0);
          return Integer.valueOf(tf.getText());
        }

        @Override
        public boolean startCellEditing(EventObject anEvent) {
          int row= table.getSelectedRow();
          int column= table.getSelectedColumn();
          System.out.println("started", row, column);
          tf.setText(table.getValueAt(row, column).toString());
          return true;
        }

        @Override
        public boolean stopCellEditing() {
          System.out.println("editing stopped", getCellEditorValue());
          return super.stopCellEditing();
        }
      };
      tf.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
          System.out.println("Click");
          if (e.getClickCount()!=2) return;
          delegate.startCellEditing(new EventObject(tf));
        }
      });
    }
  }

}

java swing jtable
1个回答
0
投票

按照 MadProgrammer 使用 JFormattedTextField 的想法,我想出了以下代码。

import java.awt.*;
import java.awt.event.*;
import java.text.*; // DecimalFormat, NumberFormat.
import java.util.EventObject;
import javax.swing.*;
import javax.swing.text.*; // NumberFormatter.
import javax.swing.table.*;

public class MonitorEditingStartStoppedFTF extends JFrame {
  int row, column;
  JFormattedTextField ftf;

  public MonitorEditingStartStoppedFTF() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(220, 150);
    setLocationRelativeTo(null);

    String headers[] = {"Fruit", "Count", "Profit"};
    Object data[][] = {
        {"Apple", 6, -0.3},
        {"Banana", 3, 0.4},
        {"Cherry", 10, 1.},
        {"Date", -3, -1.}
      };

    DefaultTableModel model= new DefaultTableModel(headers, 0) {
      public Class<?> getColumnClass(int column) {
        Class<?> returnValue;
        if (getRowCount()>0 && getValueAt(0, column)!=null)
          returnValue= getValueAt(0, column).getClass();
        else
          returnValue= Object.class;
        return returnValue;
      }
    };
    for (int i=0; i<data.length; i++)
      model.addRow(data[i]);

    JTable table= new JTable(model);
    NumberFormatter numFmt = new NumberFormatter(new DecimalFormat("#,###"));
    numFmt.setAllowsInvalid(false);
/*  Even if ftf is made final, if ftf is not a class variable, the compiler
    reports "variable ftf might not have been initialized" for the following two
    System.out.println(... ftf.getValue()).
    JFormattedTextField ftf= new JFormattedTextField(numFmt) {
*/      
    ftf= new JFormattedTextField(numFmt) {
      @Override
      protected void processFocusEvent(FocusEvent e) {
        String s= e.paramString();
        s= s.substring(0, s.indexOf(','));
        if (s.equals("FOCUS_GAINED")) {
          System.out.println("Editing starts "+ftf.getValue());
          row= table.getSelectedRow();
          column= table.getSelectedColumn();
          System.out.printf("Row/column %d/%d value: %s%n", row, column,
                        table.getValueAt(row, column));
        }
        else if (s.equals("FOCUS_LOST")) {
          System.out.println("Editing stopped "+ftf.getValue());
          s= table.getValueAt(row, column).toString().replace(".", "");
          System.out.printf("Row, column %d,%d value: %s%n%n", row, column, s);
          table.setValueAt(Integer.valueOf(s), row, column);
          ftf.setValue(Integer.valueOf(0));
        }
        super.processFocusEvent(e);
      }
    };
    ftf.setHorizontalAlignment(SwingConstants.RIGHT);
    DefaultCellEditor editor= new DefaultCellEditor(ftf);
    TableColumnModel tcm= table.getColumnModel();
    tcm.getColumn(1).setCellEditor(editor);
    JScrollPane scrollPane= new JScrollPane(table);
    add(scrollPane, BorderLayout.CENTER);
    setVisible(true);
  }


  public static void main(String args[]) {
    EventQueue.invokeLater(MonitorEditingStartStoppedFTF::new);
  }

}
© www.soinside.com 2019 - 2024. All rights reserved.