使用all(jComboBox,JTextField,jFileChooser)作为表编辑器会覆盖引用 [英] Using all (jComboBox, JTextField, jFileChooser) as table editor overrides the refrences

查看:116
本文介绍了使用all(jComboBox,JTextField,jFileChooser)作为表编辑器会覆盖引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,对于同一个表的各行,我尝试将可编辑组合框设置为第一行的编辑器(以便用户可以从可用选项中进行选择或键入自己的选项) ),第二行的filechooser和其余行的默认textFiled。

In the code below, for various rows of same table, I am trying to set an Editable comboBox as editor for first row ( so that the user can select from the available choices or type its own), a filechooser for second row and the default textFiled for the rest of rows.

问题:以及重现它的步骤:

1 - 运行代码,
2 - 点击第二行并选择一个文件夹(行变成黄色)
3 - 现在点击第一行选择电影类型(只需点击,无需键入任何内容或选择)
4- 现在再次点击第二行(文件夹选择)

1- Run the code, 2- click on second row and choose a folder (the row turns yellow) 3- now click on first row to select the type of movie (just click , no need to type anything or to choose) 4- now make another click back on second row(Folder selection)

你会看到这一行的内容会被复制到第一行吗?!

you will see the contents of this row will be copied to first row?!

我知道有很多事情我做得不对,可能是处理非线程安全的波动,处理引用等等。我想知道你们是否可以帮助我解决这个问题并将此代码变为可靠的代码。

I know there are many things that I did not do right, perhaps handling swings which are not thread safe, handling references and so on. I was wondering if you guys can help me to fix this bug and turn this code to something solid.

按照以上步骤操作:

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.TableModel;

public class CCellEditor extends DefaultCellEditor {

    private JTable m_Table = null;

    public CCellEditor(JFrame parentFrame, JTable table) { 
        super(new JTextField());
        super.setClickCountToStart(1);
        m_Table = table;
    }
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int row, int column){

        if(row==0) // comBoBox for First row
        {
            Object[] objectArray = {"3D","2D"};
            JComboBox comboBox = new JComboBox(objectArray);
            comboBox.setEditable(true);
            comboBox.setSelectedItem(value);

            ItemListener itemListener = new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        if(null != m_Table.getCellEditor()){ 
                            m_Table.getCellEditor().stopCellEditing();
                        }

                        m_Table.setValueAt(e.getItem(), row, 1);
                    }
                }
            };
            comboBox.addItemListener(itemListener);

            PopupMenuListener popMenuEvent = new PopupMenuListener() {

                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                }

                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                    String sValue = (String)m_Table.getValueAt(row, 1);
                    if(null != m_Table.getCellEditor()){ 
                        m_Table.getCellEditor().stopCellEditing();
                    }
                    m_Table.setValueAt(sValue, row, 1);
                }

                public void popupMenuCanceled(PopupMenuEvent e) {   
                }

            };
            comboBox.addPopupMenuListener(popMenuEvent);

            return comboBox;

        }

        else  if(row==1)  // fileChooser for Second row
        {
            JFileChooser fileChooser;
            fileChooser = new JFileChooser("c:\\");
            fileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
            fileChooser.setVisible(true);
            int returnVal = fileChooser.showOpenDialog(null);

            JTextField textField = (JTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
            textField.setBackground(Color.yellow);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File m_fFirmware= fileChooser.getSelectedFile();

                textField.setText(m_fFirmware.getPath());
                return textField;

            }else
            {
                return textField; 

            }
        }
                                // for any other rows
        JTextField textField = (JTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
        return textField;

    }

    public static void main(String[] a) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        String[] columnTitles = { "Name", "Value"};
        Object[][] dataEntries = {
                { "Movie Type:", "3D" }, {"Folder:","C:"}, {"# of Movies requested:","5"}};
        TableModel model = new EditableTableModel(columnTitles, dataEntries);
        JTable table = new JTable(model);
        table.createDefaultColumnsFromModel();
        table.setDefaultEditor(Object.class, new CCellEditor(frame, table));
        frame.add(new JScrollPane(table));
        frame.setSize(300, 200);
        frame.setVisible(true);
    }

}

这里是EditableTableModel类:

and here is the EditableTableModel class:

import javax.swing.table.AbstractTableModel;


class EditableTableModel extends AbstractTableModel {
  String[] columnTitles;

  Object[][] dataEntries;

  int rowCount;

  public EditableTableModel(String[] columnTitles, Object[][] dataEntries) {
    this.columnTitles = columnTitles;
    this.dataEntries = dataEntries;
  }

  public int getRowCount() {
    return dataEntries.length;
  }

  public int getColumnCount() {
    return columnTitles.length;
  }

  public Object getValueAt(int row, int column) {
    return dataEntries[row][column];
  }

  public String getColumnName(int column) {
    return columnTitles[column];
  }

  public Class getColumnClass(int column) {
    return getValueAt(0, column).getClass();
  }

  public boolean isCellEditable(int row, int column) {
    return true;
  }

  public void setValueAt(Object value, int row, int column) {
    dataEntries[row][column] = value;
  }



}


推荐答案

我必须承认我花了一段时间,但我发现了这个问题。您没有覆盖 DefaultCellEditor.getCellEditorValue()函数,这对您的实现很重要。当正在编辑的单元格失去焦点或其他导致编辑完成的任何其他内容时,将调用此函数。无论如何,在你的情况下,它只是从最后一个默认的TableCellEditor(来自DefaultCellEditor)获取最终值。这就是第一行不断被最后编辑的单元格值替换的原因。

I must admit it took me a while but I found the issue. You have not overridden the DefaultCellEditor.getCellEditorValue() function, which is important for your implementation. This function is called when when the cell being edited loses focus or whatever else causes editing to be complete. Anyway, in your case, it just gets the final value from the last default TableCellEditor (from DefaultCellEditor). This is why the first row keeps getting replaced with the last edited cell value.

这是一种解决问题的方法:

Here is a way to fix your problem:


  1. 创建对组合框的全局引用。

  2. 覆盖 getCellEditorValue()并返回 comboBox.getSelectedItem()如果最后编辑的项目是第二行。否则,只需返回 super.getCellEditorValue()

  1. Create a global reference to the comboBox.
  2. Override getCellEditorValue() and return comboBox.getSelectedItem() if the last edited item was the second row. Otherwise, just return super.getCellEditorValue().

这将修复你的当前的问题,但你的代码可以使用很多改进。

This will fix your current issue but your code could use a lot of improvement.

这篇关于使用all(jComboBox,JTextField,jFileChooser)作为表编辑器会覆盖引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆