簡體   English   中英

在Jtable單元格中單擊JComboBox時將調用ActionPerformed

[英]ActionPerformed being called when JComboBox is clicked in Jtable cell

我在Jtable單元中使用JComboBox 當我單擊JComboBox並從中選擇一個值時,它將調用ActionPerformed函數。 到這里為止一切正常,但是當我再次單擊JComboBox時,它將調用ActionPerformed函數,但不應。 我想要的是在JComboBox選擇該項目時調用ActionPerformed函數。 換句話說,當從JComboBox中選擇該項目然后調用ActionPerformed函數時,它應該像它第一次工作時那樣工作。 我不知道為什么會出現此問題。 這是我研究過的鏈接,我也進行了一些其他搜索,但仍然找不到上述問題的任何相對答案。

  1. 將JComboBox添加到JTable單元中
  2. 如何在ComboBox上使用ActionListener為變量賦值
  3. https://coderanch.com/t/339842/java/ComboBox-ItemListener-calling

這是代碼,您可以復制粘貼並檢查它。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumn;

public class TableExample implements ActionListener{

    JFrame frame;
    JComboBox skuNameComboBoxTable;

    TableExample() {
        frame = new JFrame();
        String data[][] = {{"101", "Amit", "Choose"},
        {"102", "Jai", "Choose"},
        {"101", "Sachin", "Choose"}};
        String column[] = {"ID", "Name", "Degree"};
        JTable table = new JTable(data, column);
        table.setBounds(30, 40, 200, 300);
        JScrollPane scrollPane = new JScrollPane(table);
        frame.add(scrollPane);
        frame.setSize(300, 400);
        frame.setVisible(true);

        String[] array = {"BS(SE)", "BS(CS)", "BS(IT)"};
        skuNameComboBoxTable = new JComboBox(array);
        skuNameComboBoxTable.addActionListener(this);

        TableColumn col = table.getColumnModel().getColumn(2);
        col.setCellEditor(new DefaultCellEditor(skuNameComboBoxTable));
    }

    public static void main(String[] args) {
        new TableExample();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(null, "actionPerformed called");
    }
}

請告訴我為什么會出現此問題以及如何解決。

您可以嘗試使用ItemListener並根據ItemEvent過濾操作。

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;


public class JComboBoxTest {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        String[] items = {"One", "Two", "Three"};
        JComboBox cb = new JComboBox(items);
        cb.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    System.out.println("Selected " + e.getItem());
                } else {
                    System.out.println("Deselected " + e.getItem());
                }
            }
        });

        frame.add(cb);

        frame.pack();
        frame.setVisible(true);
    }
}

不幸的是,使用DefaultCellEditor不能做太多事情-這就是它的行為方式。 您可以在代碼中添加檢查以確保在處理事件之前發生值更改。 如下所示:

public void actionPerformed(ActionEvent e) {
    if (skuNameSelected == null || skuNameComboBoxTable.getSelectedItem() != skuNameSelected)
        JOptionPane.showMessageDialog(null, "actionPerformed called: ");
    skuNameSelected = (String) skuNameComboBoxTable.getSelectedItem();
}

發生這種情況的原因是,您在第2列使用與DefaultCellEditor相同的JComboBox。

每當您單擊第2列中的單元格時,組合框都將更改為當前單元格上的值,並觸發DESELECT (從舊值開始)和SELECT (對於新值)。 僅當舊值和新值不相同時,才會發生這種情況。

一種避免這種情況的方法是在您使用的DefaultCellEditor上添加一個CellEditorListener,如下所示:

TableColumn col = table.getColumnModel().getColumn(2);
DefaultCellEditor cellEditor = new DefaultCellEditor(skuNameComboBoxTable);
col.setCellEditor(cellEditor);

cellEditor.addCellEditorListener(new CellEditorListener() {

            @Override
            public void editingStopped(ChangeEvent e) {
                System.out.println("Value of combo box defined!");
            }

            @Override
            public void editingCanceled(ChangeEvent e) {
                System.out.println("Edition canceled, set the old value");
            }
});

這樣,您將只能在ComboBox定義了值時采取行動。

我希望這有幫助。

您不應該為此使用ActionListener。 選擇一個項目時,組合框使用其自己的ActionListener來更新TableModel。

因此,相反,您應該偵聽TableModel中的更改以便執行自定義代碼。 因此,您應該使用TableModelListener來偵聽數據中的更改。 但是,即使只是開始和停止單元格的編輯, TableModelListener也會觸發事件,這可能對您造成問題。

在這種情況下,您可以使用Table Cell Listener 僅當TableModel中的值更改時,它才會生成一個事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM