gpt4 book ai didi

java - 如何仅单击一次鼠标即可编辑 JXTreeTable 单元格?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:22:56 26 4
gpt4 key购买 nike

我想使用 JComboBox 作为 JXTreeTable 中的单元格编辑器.它适用于标准 DefaultCellEditor(即 开始点击次数 等于 2)。

现在我希望只需单击一次 即可编辑该列。所以我在我的代码中添加了一个 cellEditor.setClickCountToStart(1); 语句。

这是我的 SSCCE :

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
import org.jdesktop.swingx.treetable.DefaultTreeTableModel;

public class TestCellEditorForJXTreeTable {

/** The JXTreeTable */
JXTreeTable treeTable;
/** The model */
DefaultTreeTableModel treeTableModel;

/** Constructor */
public TestCellEditorForJXTreeTable() {

treeTable = new JXTreeTable();
treeTableModel = new DefaultTreeTableModel() {
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "A";
case 1:
return "B";
}
return null;
}
@Override
public Object getValueAt(Object node, int column) {
switch (column) {
case 0:
return ((DefaultMutableTreeTableNode) node).getUserObject();
case 1:
return "Value in B";
}
return null;
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public boolean isCellEditable(Object node, int column) {
return column == 1;
}
};
treeTable.setTreeTableModel(treeTableModel);

}

public static void main(String[] args) {
TestCellEditorForJXTreeTable test = new TestCellEditorForJXTreeTable();

// Root node
DefaultMutableTreeTableNode root = new DefaultMutableTreeTableNode("root");
test.treeTableModel.setRoot(root);

// New nodes/rows
DefaultMutableTreeTableNode node = new DefaultMutableTreeTableNode("child_node");
test.treeTableModel.insertNodeInto(node, root, 0);
DefaultMutableTreeTableNode node2 = new DefaultMutableTreeTableNode("child_node2");
test.treeTableModel.insertNodeInto(node2, root, 1);

// Showing the frame
showTable(test.treeTable);

// Setting the cell editor
DefaultCellEditor cellEditor = new DefaultCellEditor(new JComboBox(new String[]{"1", "2", "3"}));
cellEditor.setClickCountToStart(1);
test.treeTable.getColumn(1).setCellEditor(cellEditor);

}

/** Shows a JXTreeTable in a frame */
private static void showTable(JXTreeTable table) {
JFrame frame = new JFrame("Testing cell editor for JXTreeTable");
frame.setPreferredSize(new Dimension(640, 480));
frame.setLayout(new BorderLayout());
frame.add(table, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

但是现在看起来很丑:

当我点击一个可编辑的单元格时,它会打开 JComboBox 弹出菜单(太棒了!这正是我所期待的!),但是这个弹出菜单立即关闭(< em>Erf!)。它闪烁。我必须在选定的单元格上再次单击才能最终打开它。

每次我在可编辑列中选择另一个单元格时,问题都会重复。

如何才能在第一次单击后真正打开 JComboBox 弹出菜单?

谢谢。

编辑 2014-01-24

这里是同一个例子,但是使用了 JTableJComboBox 弹出菜单不会闪烁

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class TestCellEditorForJTable {

/** The JTable */
JTable table;
/** The model */
DefaultTableModel tableModel;

/** Constructor */
public TestCellEditorForJTable() {
table = new JTable();
tableModel = new DefaultTableModel(new String[] {"A", "B"}, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return column == 1;
}
};
table.setModel(tableModel);

}

public static void main(String[] args) {
TestCellEditorForJTable test = new TestCellEditorForJTable();

// New rows
test.tableModel.insertRow(0, new String[] {"Value1 in A", "Value1 in B"});
test.tableModel.insertRow(1, new String[] {"Value2 in A", "Value2 in B"});

// Showing the frame
showTable(test.table);

// Setting the cell editor
DefaultCellEditor cellEditor = new DefaultCellEditor(new JComboBox(new String[]{"1", "2", "3"}));
cellEditor.setClickCountToStart(1);
test.table.getColumnModel().getColumn(1).setCellEditor(cellEditor);

}

/** Shows a table in a frame */
private static void showTable(JTable table) {
JFrame frame = new JFrame("Testing cell editor for JTable");
frame.setPreferredSize(new Dimension(640, 480));
frame.setLayout(new BorderLayout());
frame.add(table, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

我忘了说我使用的是 Java 1.6。

编辑2014-01-24(2)

使用 kleopatra's answerContainerListenerFocusListener ,并运行相同的执行流程,我通过 JXTreeTable SSCCE 获得以下输出:

// first click
24.01.2014 13:10:59 my.pkg.TestCellEditorForJXTreeTable$2 componentAdded
INFO: java.awt.event.ContainerEvent[COMPONENT_ADDED...JXTreeTable...
24.01.2014 13:10:59 my.pkg.TestCellEditorForJXTreeTable$3 focusGained
INFO: java.awt.FocusEvent[FOCUS_GAINED...JXTreeTable...
24.01.2014 13:10:59 my.pkg.TestCellEditorForJXTreeTable$2 componentRemoved
INFO: java.awt.event.ContainerEvent[COMPONENT_REMOVED...JXTreeTable...
24.01.2014 13:10:59 my.pkg.TestCellEditorForJXTreeTable$3 focusLost
INFO: java.awt.FocusEvent[FOCUS_LOST...JXTreeTable...

// second click
24.01.2014 13:11:02 my.pkg.TestCellEditorForJXTreeTable$2 componentAdded
INFO: java.awt.event.ContainerEvent[COMPONENT_ADDED...JXTreeTable...
24.01.2014 13:11:02 my.pkg.TestCellEditorForJXTreeTable$3 focusGained
INFO: java.awt.FocusEvent[FOCUS_GAINED...JXTreeTable...
24.01.2014 13:11:02 my.pkg.TestCellEditorForJXTreeTable$2 componentRemoved
INFO: java.awt.event.ContainerEvent[COMPONENT_REMOVED...JXTreeTable...
24.01.2014 13:11:02 my.pkg.TestCellEditorForJXTreeTable$3 focusLost
INFO: java.awt.FocusEvent[FOCUS_LOST...JXTreeTable...

最佳答案

Tricky bugger - 我认为这确实是一个核心问题。

让我们首先准确定义它发生了什么/什么时候发生:以普通表格为例(顺便说一句:+1 表示漂亮简洁的 SSCCE!)

  • 运行
  • 点击单元格 (1, 1),即最后一行,第二列:表格开始编辑,显示组合的弹出窗口
  • 仍在编辑时(请注意,不要点击中间的任何其他地方很重要),点击单元格 (0, 1):表格开始编辑该单元格,组合的弹出窗口被隐藏

挖掘揭示了可能的原因:它是一个无序的 focusLost 收到之后组合被再次添加为编辑组件。要查看,请将 containerListener 注册到表,将 focusListener 注册到组合并打印事件

ContainerListener containerL = new ContainerListener() {

@Override
public void componentRemoved(ContainerEvent e) {
LOG.info("" + e);
}

@Override
public void componentAdded(ContainerEvent e) {
LOG.info("" + e);
}
};
table.addContainerListener(containerL);
FocusListener focusL = new FocusListener() {

@Override
public void focusGained(FocusEvent e) {
LOG.info("" + e);
// following line is a hack around: force the popup open
// ((JComboBox) cellEditor.getComponent()).setPopupVisible(true);
}

@Override
public void focusLost(FocusEvent e) {
LOG.info("" + e);
}

};
cellEditor.getComponent().addFocusListener(focusL);

输出:

// first click
24.01.2014 12:13:44 org.jdesktop.swingx.table.TestCellEditorForJTable$2 componentAdded
INFO: java.awt.event.ContainerEvent[COMPONENT_ADDED,child=null] on javax.swing.JTable...
24.01.2014 12:13:44 org.jdesktop.swingx.table.TestCellEditorForJTable$3 focusGained
INFO: java.awt.FocusEvent[FOCUS_GAINED,permanent,opposite=javax.swing.JTable

// second click
24.01.2014 12:13:49 org.jdesktop.swingx.table.TestCellEditorForJTable$2 componentRemoved
INFO: java.awt.event.ContainerEvent[COMPONENT_REMOVED,child=null] on javax.swing.JTable
24.01.2014 12:13:49 org.jdesktop.swingx.table.TestCellEditorForJTable$2 componentAdded
INFO: java.awt.event.ContainerEvent[COMPONENT_ADDED,child=null] on javax.swing.JTable
// here's the problem: focusLost _after_ added again
24.01.2014 12:13:49 org.jdesktop.swingx.table.TestCellEditorForJTable$3 focusLost
INFO: java.awt.FocusEvent[FOCUS_LOST,permanent,opposite=javax.swing.JTable
24.01.2014 12:13:49 org.jdesktop.swingx.table.TestCellEditorForJTable$3 focusGained
INFO: java.awt.FocusEvent[FOCUS_GAINED,permanent,opposite=javax.swing.JTable

一个快速的 hack 可能是强制在 focusListener 中打开弹出窗口。不过,没有检查副作用。

关于java - 如何仅单击一次鼠标即可编辑 JXTreeTable 单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21309528/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com