【问题标题】:Why is JXTable losing input where JTable is not?为什么 JXTable 会丢失 JTable 没有的输入?
【发布时间】:2015-02-04 21:31:41
【问题描述】:

当我使用 JXTable 呈现和编辑我的数据时,某些输入到 CellEditor 的内容会丢失。 如果我单击 JXTable-ColumnHeader 的 Resizing-Divider 或更改 JFrame 的宽度,CellEditor 将终止而不提交该值。如果我使用 JTable,则会保存这些值。

我想使用 JXTable 是因为它的其他功能,那么有没有办法修复 JXTable?

例子:

package table.columnresize;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import org.jdesktop.swingx.JXTable;

/**
 * Demo of differing behaviour of JXTable and JTable. JXTable loses input in a TableCell where JTable persists
 * it.
 * <p>
 * <table border=1>
 * <tr>
 * <th></th>
 * <th>JXTable</th>
 * <th>JTable</th>
 * </tr>
 * <tr>
 * <td>Click on TableColumnHeader</td>
 * <td>saved</td>
 * <td>saved</td>
 * </tr>
 * <tr>
 * <td>Resizing with Divider of TableColumnHeader</td>
 * <td>lost</td>
 * <td>saved</td>
 * </tr>
 * <tr>
 * <td>Changing the width of JFrame</td>
 * <td>lost</td>
 * <td>saved</td>
 * </tr>
 * 
 * </table>
 * </p>
 * 
 * @author bobndrew 2015-01-29
 */
public class JXTableAndJTableEditLossDemo
{
  private static class DataModel extends DefaultTableModel
  {
    public DataModel( Object[][] data, Object[] columnNames )
    {
      super( data, columnNames );
    }
  }

  private static void createAndShowUI()
  {
    Object[][] DATA = { { "One", 1 }, { "Two", 2 }, { "Three", 3 }, { "Four", 4 }, { "Five", 5 } };
    String[] COLUMNS = { "A", "B" };
    DataModel dataModel = new DataModel( DATA, COLUMNS );

    JFrame frame1 = new JFrame( "JXTable" );
    JXTable jXTable = new JXTable( dataModel );
    //does not change anything:    jXTable.setTerminateEditOnFocusLost( true );
    System.out.println( jXTable.isTerminateEditOnFocusLost() );
    frame1.add( new JScrollPane( jXTable ) );
    frame1.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame1.pack();
    frame1.setVisible( true );

    JFrame frame2 = new JFrame( "JTable" );
    JTable jTable = new JTable( dataModel );
    //does not change anything:    jTable.putClientProperty( "terminateEditOnFocusLost", Boolean.FALSE );
    System.out.println( jTable.getClientProperty( "terminateEditOnFocusLost" ) );
    frame2.add( new JScrollPane( jTable ) );
    frame2.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame2.pack();
    frame2.setLocation( (int) frame1.getLocation().getX() + frame1.getWidth() + 100, (int) frame1
        .getLocation().getY() );
    frame2.setVisible( true );
  }

  public static void main( String[] args )
  {
    java.awt.EventQueue.invokeLater( new Runnable()
    {
      @Override
      public void run()
      {
        createAndShowUI();
      }
    } );
  }

}

【问题讨论】:

  • 您是否尝试向 JXTable 添加自定义焦点侦听器?请参阅这篇文章的第二个和第三个答案。 stackoverflow.com/questions/1652942/…
  • 好主意,但是 FocusListener 在不同操作系统下太不可靠了。

标签: java swing jtable swingx jxtable


【解决方案1】:

在调试JXTableJTable 时,我找到了丢失CellEdits 的原因。 区别在于方法columnMarginChanged()

JXTable:

if (isEditing()) {
  removeEditor();
}

JTable:

if (isEditing() && !getCellEditor().stopCellEditing()) {
  getCellEditor().cancelCellEditing();
} 

起初我认为removeEditor() 方法是JTable 的增强...但后来我发现这个OpenJDK changeset from September 2010 修复了错误“4330950:调整大小时单元格中丢失新输入的数据列宽”。似乎 JDK 的更改并未应用于 SwingX 源代码。

我会接受我自己的答案,因为不同行为的原因现在很清楚了。 为了为我和其他 SwingX 用户解决此问题,我将前往 SwingX 邮件列表和错误跟踪器。

【讨论】:

    【解决方案2】:

    当您查看 JTable 的 frameInit() 方法时,您可以看到它绑定到所有 AWTEvent.WINDOW* 事件。在 JXTable 中,initActionsAndBindings() 方法绑定到特定操作(例如值更改),并且仅针对表。

    您需要添加自己的监听器

        jXTable.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
            @Override
            public void columnMarginChanged(ChangeEvent e) {
    
            }
        });
    

    然后必须公开表的某些功能以允许事件触发更新表。或者你可以从那里触发一个 TableModelEvent。

    【讨论】:

    • frameInit()JFrame.java 中的一个方法,而不是JTable.java。但是您对TableColumnModelListenercolumnMarginChanged() 的想法与我的发现相似;看我的回答。
    猜你喜欢
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 2014-11-30
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多