我想要一个包含4列的jtable。 一列必须是组合框。 其他列是字符串。
当我在单元格上单击一次时,我希望单元格可以使用闪烁的插入符号/光标进行编辑。此外,如果我单击组合框,我希望combox设置弹出窗口可见。
我已经阅读并测试了教程“如何使用表格”,如果我只在单元格中单击组合框,它就会打开。我的第一个问题是,当我们实现抽象表模型而不是使用DefaultTableModel时,我不明白为什么教程中的代码有效。
我的代码是:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class JtabletestOK {
public static void main(String[] args) {
JtabletestOK test = new JtabletestOK();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create a table and add it to a scroll pane in a new tab
JTable jTable1 = new JTable()
{
// Place cell in edit mode when it 'gains focus'
public void changeSelection(
int row, int column, boolean toggle, boolean extend)
{
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column))
{
Component editor = getEditorComponent();
editor.requestFocusInWindow();
// System.out.println("ffin focus gagne");
if (editor instanceof JTextField) {
JTextField jf = (JTextField) editor;
jf.select(0, jf.toString().length());
}}
}
};
jTable1.setPreferredScrollableViewportSize(new Dimension(800,100));
jTable1.setFillsViewportHeight(true);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(jTable1);
Object columnNames[] = { "DataCombo", "Data 2", "Data 3", "Data 4" };
DefaultTableModel model = new DefaultTableModel(columnNames, 0);
Object rowData[] = { "", "Row1-Column2", "Row1-Column3", "Row1-Column3" };
model.addRow(rowData);
jTable1.setModel(model);
String[] comboBoxArray = {"proem1","veitem2","atem3"};
JComboBox jcb = new JComboBox(comboBoxArray);
jcb.setEditable(true);
TableColumn colCombo = jTable1.getColumnModel().getColumn(0);
colCombo.setCellEditor(new DefaultCellEditor(jcb));
jcb.setEditable(true);
frame.getContentPane().add(scrollPane);
frame.pack();
frame.setVisible(true);
}
找到问题:在评论语句时jcb.setEditable(true);如果我在comboxcell上单击它就会打开单元格。 但我不知道为什么它会更好。另外,我希望combox可以编辑。
我如何为其他单元格拥有相同的行为。
您好,我已更新代码以便拥有 - 如果我通过覆盖方法在单元格上单击一次,则单元格变为可编辑 - 如果我通过覆盖方法
在单元格上单击一次,组合框就变得可编辑我把新代码放在这里,它可能有助于其他代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.text.JTextComponent;
public class JtabletestOK {
public static void main(String[] args) {
JtabletestOK test = new JtabletestOK();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create a table and add it to a scroll pane in a new tab
JTable jTable1 = new JTable()
{
// Place cell in edit mode when it 'gains focus'
public void changeSelection(
int row, int column, boolean toggle, boolean extend)
{
super.changeSelection(row, column, toggle, extend);
if (column > 0)
{
if (editCellAt(row, column))
{
Component editor = getEditorComponent();
editor.requestFocusInWindow();
// System.out.println("ffin focus gagne");
if (editor instanceof JTextField) {
JTextField jf = (JTextField) editor;
jf.select(0, jf.toString().length());
}}
}
}
};
jTable1.setPreferredScrollableViewportSize(new Dimension(800,100));
jTable1.setFillsViewportHeight(true);
replaceTabByEnter(jTable1);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(jTable1);
Object columnNames[] = { "DataCombo", "Data 2", "Data 3", "Data 4" };
DefaultTableModel model = new DefaultTableModel(columnNames, 0);
Object rowData[] = { "", "Row1-Column2", "Row1-Column3", "Row1-Column3" };
model.addRow(rowData);
jTable1.setModel(model);
String[] comboBoxArray = {"proem1","veitem2","atem3"};
JComboBox jca = new JComboBox(comboBoxArray);
jca.setSelectedItem("");
JTextComponent editor = (JTextComponent) jca.getEditor().getEditorComponent();
jca.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JComponent ja = (JComponent) e.getSource();
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
JComponent ja = (JComponent) e.getSource();
JTable jtb = (JTable) ja.getParent();
jtb.changeSelection(0,1,false,false);
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
});
editor.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("Not mouseClicked yet.");
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("Not mousePressed yet.");
}
@Override
public void mouseReleased(MouseEvent e) {
JComponent ja = (JComponent) e.getSource();
JComponent jcbloc = (JComponent) ja.getParent();
JComboBox jcb = (JComboBox) jcbloc;
jcb.setPopupVisible(true);
System.out.println("Not mouseReleased yet.");
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Not mouseEntered yet.");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("Not mouseExited yet.");
}
});
autocompletecombo jcb =new autocompletecombo(jca);
TableColumn colCombo = jTable1.getColumnModel().getColumn(0);
jca.setEditable(true);
comboboxEditor cbe = new comboboxEditor(jca);
colCombo.setCellEditor(cbe);
frame.getContentPane().add(scrollPane);
frame.pack();
frame.setVisible(true);
}
public void replaceTabByEnter(JTable jtane) {
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
InputMap im = jtane.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.put(enter, im.get(tab));
}
class comboboxEditor extends AbstractCellEditor implements TableCellEditor{
JComboBox comboBox;
JTextField jtf;
S11InitialSelection sjcb;
@Override
public Object getCellEditorValue() {
return comboBox.getSelectedItem();
}
public comboboxEditor(JComboBox jcb) {
comboBox = jcb;
jtf.selectAll();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
comboBox.setSelectedItem(value);
return comboBox;
}
public boolean stopCellEditing() {
fireEditingStopped();
// jt.EditNextCell();
return true;
}
}
}
我找到了解决方案:
public void mouseReleased(MouseEvent e) {
JComponent ja = (JComponent) e.getSource();
JComponent jcbloc = (JComponent) ja.getParent();
JComboBox jcb = (JComboBox) jcbloc;
jcb.setPopupVisible(true);
JTextComponent editor = (JTextComponent) jcb.getEditor().getEditorComponent();
editor.setSelectionStart(0);
editor.setSelectionEnd(editor.getText().length());
System.out.println("Not mouseReleased yet.");
}
感谢您的帮助。
答案 0 :(得分:1)
我终于找到了解决所有问题的方法。我发布了所有代码。 我希望它会帮助别人。如果您找到更好的方法来解决问题,我就会打开。
它仍然是两件奇怪的事情,但它可以按照我想要的方式工作,所以如果有人作为一个想法:
如果我移动代码
if(e.getKeyChar() == KeyEvent.VK_ENTER){
JComponent ja = (JComponent) e.getSource();
JComboBox jcbloc = (JComboBox) ja.getParent();
JTable jtb = (JTable) jcbloc.getParent();
jtb.changeSelection(0,1,false,false);
}
在keyReleased而不是keyPressed中,它不起作用。
这里的所有代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicTextUI;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.text.JTextComponent;
public class JtabletestOKStackOver {
public static void main(String[] args) {
JtabletestOKStackOver test = new JtabletestOKStackOver();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create a table and add it to a scroll pane in a new tab
JTable jTable1 = new JTable()
{
// Place cell in edit mode when it 'gains focus'
public void changeSelection(
int row, int column, boolean toggle, boolean extend)
{
super.changeSelection(row, column, toggle, extend);
if (column > -1)
{
if (editCellAt(row, column))
{
Component editor = getEditorComponent();
editor.requestFocusInWindow();
if (editor instanceof JTextField) {
JTextField jf = (JTextField) editor;
jf.select(0, jf.toString().length());
}
if (editor instanceof JComboBox) {
JComboBox jcb = (JComboBox) editor;
jcb.setPopupVisible(true);
JTextComponent editorCombo = (JTextComponent) jcb.getEditor().getEditorComponent();
editorCombo.setSelectionStart(0);
editorCombo.setSelectionEnd(editorCombo.getText().length());
}
}
}
}
};
jTable1.setPreferredScrollableViewportSize(new Dimension(800,100));
jTable1.setFillsViewportHeight(true);
jTable1.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(jTable1);
Object columnNames[] = { "DataCombo", "Data 2", "Data 3", "Data 4" };
DefaultTableModel model = new DefaultTableModel(columnNames, 0);
Object rowData[] = { "", "Row1-Column2", "Row1-Column3", "Row1-Column3" };
model.addRow(rowData);
jTable1.setModel(model);
String[] comboBoxArray = {"proem1","veitem2","atem3"};
JComboBox jca = new JComboBox(comboBoxArray);
jca.setSelectedItem("");
JTextComponent editor = (JTextComponent) jca.getEditor().getEditorComponent();
editor.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyChar() == KeyEvent.VK_ENTER){
JComponent ja = (JComponent) e.getSource();
JComboBox jcbloc = (JComboBox) ja.getParent();
JTable jtb = (JTable) jcbloc.getParent();
jtb.changeSelection(0,1,false,false);
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
editor.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
JComponent ja = (JComponent) e.getSource();
JComponent jcbloc = (JComponent) ja.getParent();
JComboBox jcb = (JComboBox) jcbloc;
jcb.setPopupVisible(true);
JTextComponent editor = (JTextComponent) jcb.getEditor().getEditorComponent();
editor.setSelectionStart(0);
editor.setSelectionEnd(editor.getText().length());
}
@Override
public void focusLost(FocusEvent e) {
}
});
TableColumn colCombo = jTable1.getColumnModel().getColumn(0);
jca.setEditable(true);
comboboxEditor cbe = new comboboxEditor(jca);
colCombo.setCellEditor(cbe);
TableColumn colAutre = jTable1.getColumnModel().getColumn(1);
TableColumn colAutre2 = jTable1.getColumnModel().getColumn(2);
TableColumn colAutre3 = jTable1.getColumnModel().getColumn(3);
textCellEditor dce = new textCellEditor(new JTextField());
colAutre.setCellEditor(dce);
colAutre2.setCellEditor(dce);
colAutre3.setCellEditor(dce);
frame.getContentPane().add(scrollPane);
frame.pack();
frame.setVisible(true);
}
class comboboxEditor extends AbstractCellEditor implements TableCellEditor{
JComboBox comboBox;
public comboboxEditor(JComboBox jcb) {
comboBox = jcb;
}
public Object getCellEditorValue() {
return comboBox.getSelectedItem();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
comboBox.setSelectedItem(value);
return comboBox;
}
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
}
class textCellEditor extends AbstractCellEditor implements TableCellEditor{
JTextField jtextfield;
public textCellEditor(JTextField jtf) {
jtextfield = jtf;
}
public Object getCellEditorValue() {
return jtextfield.getText();
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if (isSelected) {
// cell (and perhaps other cells) are selected
}
if (value== null)
{
value="";
}
value = value.toString();
if (value instanceof Integer) {
value = value.toString();
}
jtextfield.setText((String) value);
// Return the configured component
return jtextfield;
}
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
}
}
感谢您的帮助。
答案 1 :(得分:0)
不要在组合框上使用ActionListener。 " popup"当您单击单元格时,编辑器将显示它。
我的第一个问题是,当我们实现抽象表模型而不是使用DefaultTableModel时,我不明白为什么教程中的代码有效。
编辑由TableModel的isCellEditable(...)
方法控制。当您单击可编辑的单元格时,JTable将使用适当的编辑器。如果编辑器是组合框,则单击单元格时将显示弹出窗口。
找到问题:在评论语句时jcb.setEditable(true);如果我在comboxcell上单击它就会打开单元格。但我不知道为什么它会更好用
当您单击一个单元格时,我相信MouseEvent会转发到编辑器(即组合框)。由于组合框是可编辑的,因此MouseEvent将转到文本字段,因此焦点仍然是文本字段,并且不显示弹出窗口。尝试使用普通的组合框,而不是在JTable中显示,所以看到相同的行为。
答案 2 :(得分:-1)
我不知道为什么使用AbstractTableModel的代码有效(因为我看不到它)。但我可以帮助你让你的榜样有效。
jcb.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
System.out.println("test");
final JComboBox j= (JComboBox)evt.getSource();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (j.isDisplayable()) j.setPopupVisible(true);
}
});
}});