gpt4 book ai didi

java - 通过键盘在 JTable 中按下 JButton

转载 作者:行者123 更新时间:2023-11-29 03:29:30 24 4
gpt4 key购买 nike

我想在 JTable 中显示 JButton。这没什么特别的,我发现有很多这样做的例子。但是,我总是无法通过键盘(而不是通过鼠标)按下按钮。我希望我可以选择一个单元格并通过按 SPACE(无助记符)来按下(也可以在视觉上)按钮。

两个片段就像一个魅力,除了支持键:


http://tips4java.wordpress.com/2009/07/12/table-button-column/

作者声称按键有效。我相信他们做到了,但不是在我检查过的所有系统上。但是,支持的助记符可以完美地工作。

(张贴在这里:Adding Jbutton to JTable)


http://www.java2s.com/Code/Java/Swing-Components/ButtonTableExample.htm

(张贴在这里:Adding Jbutton to JTable)

在示例中,它完美运行!但是,它不适用于我的 table 。只需禁用行选择(我必须使用单元格选择),然后通过键按下按钮不再起作用:

table.setRowSelectionAllowed(false);


我努力找出问题所在或如何修复它,但我失败了。我唯一的成就是调用按钮后面的 Action ,但按钮没有被按下(我的意思是视觉行为)。


添加了一些信息:

我用了...(有很多组合)

  • Ubuntu 10.04、Windows 7、Windows 8
  • Java 7u21、JDK 1.6.0_33、OpenJDK 运行时环境 (IcedTea6 1.8.1) (6b18-1.8.1-0ubuntu1)
  • WindowsLookAndFeel、Metal(跨平台 LAF)、Nimbus

0% 成功!


TableTest.java

import java.awt.event.ActionEvent;
import java.util.LinkedList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;

public class TableTest extends JFrame {

public TableTest() {

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = new JTable(new TestModel());
table.setRowSelectionAllowed(false);
table.getColumnModel().getColumn(1).setPreferredWidth(3);
table.getColumnModel().getColumn(2).setPreferredWidth(3);
this.add(new JScrollPane(table));
Action increase = new AbstractAction("+") {

@Override
public void actionPerformed(ActionEvent e) {
JTable table = (JTable) e.getSource();
int row = Integer.valueOf(e.getActionCommand());
TestModel model = (TestModel) table.getModel();
model.increment(row, 0);
}
};
ButtonColumn inc = new ButtonColumn(table, increase, 1);
Action decrease = new AbstractAction("-") {

@Override
public void actionPerformed(ActionEvent e) {
JTable table = (JTable) e.getSource();
int row = Integer.valueOf(e.getActionCommand());
TestModel model = (TestModel) table.getModel();
model.decrement(row, 0);
}
};
ButtonColumn dec = new ButtonColumn(table, decrease, 2);
pack();
}

public static void main(String[] args) {
new TableTest().setVisible(true);
}
}

class TestModel extends AbstractTableModel {

List<TestRecord> records = new LinkedList<TestRecord>();

private static class TestRecord {

private int val = 0;
}

public void increment(int row, int col) {
records.get(row).val++;
fireTableCellUpdated(row, 0);
}

public void decrement(int row, int col) {
records.get(row).val--;
fireTableCellUpdated(row, 0);
}

public TestModel() {
records.add(new TestRecord());
records.add(new TestRecord());
}

@Override
public Class<?> getColumnClass(int col) {
if (col == 0) {
return Integer.class;
} else {
return ButtonColumn.class;
}
}

@Override
public boolean isCellEditable(int row, int col) {
return true;
}

@Override
public int getColumnCount() {
return 3;
}

@Override
public int getRowCount() {
return records.size();
}

@Override
public Object getValueAt(int row, int col) {
if (col == 0) {
return records.get(row).val;
} else if (col == 1) {
return "+";
} else {
return "-";
}
}
}

按钮列.java

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

/**
* The ButtonColumn class provides a renderer and an editor that looks like a
* JButton. The renderer and editor will then be used for a specified column in
* the table. The TableModel will contain the String to be displayed on the
* button.
*
* The button can be invoked by a mouse click or by pressing the space bar when
* the cell has focus. Optionally a mnemonic can be set to invoke the button.
* When the button is invoked the provided Action is invoked. The source of the
* Action will be the table. The action command will contain the model row
* number of the button that was clicked.
*
*/
public class ButtonColumn extends AbstractCellEditor implements
TableCellRenderer, TableCellEditor, ActionListener, MouseListener {
private JTable table;
private Action action;
private int mnemonic;
private Border originalBorder;
private Border focusBorder;

private JButton renderButton;
private JButton editButton;
private Object editorValue;
private boolean isButtonColumnEditor;

/**
* Create the ButtonColumn to be used as a renderer and editor. The renderer
* and editor will automatically be installed on the TableColumn of the
* specified column.
*
* @param table
* the table containing the button renderer/editor
* @param action
* the Action to be invoked when the button is invoked
* @param column
* the column to which the button renderer/editor is added
*/
public ButtonColumn(JTable table, Action action, int column) {
this.table = table;
this.action = action;

renderButton = new JButton();
editButton = new JButton();
editButton.setFocusPainted(false);
editButton.addActionListener(this);
originalBorder = editButton.getBorder();
setFocusBorder(new LineBorder(Color.BLUE));

TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(column).setCellRenderer(this);
columnModel.getColumn(column).setCellEditor(this);
table.addMouseListener(this);
}

/**
* Get foreground color of the button when the cell has focus
*
* @return the foreground color
*/
public Border getFocusBorder() {
return focusBorder;
}

/**
* The foreground color of the button when the cell has focus
*
* @param focusBorder
* the foreground color
*/
public void setFocusBorder(Border focusBorder) {
this.focusBorder = focusBorder;
editButton.setBorder(focusBorder);
}

public int getMnemonic() {
return mnemonic;
}

/**
* The mnemonic to activate the button when the cell has focus
*
* @param mnemonic
* the mnemonic
*/
public void setMnemonic(int mnemonic) {
this.mnemonic = mnemonic;
renderButton.setMnemonic(mnemonic);
editButton.setMnemonic(mnemonic);
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (value == null) {
editButton.setText("");
editButton.setIcon(null);
} else if (value instanceof Icon) {
editButton.setText("");
editButton.setIcon((Icon) value);
} else {
editButton.setText(value.toString());
editButton.setIcon(null);
}

this.editorValue = value;
return editButton;
}

@Override
public Object getCellEditorValue() {
return editorValue;
}

//
// Implement TableCellRenderer interface
//
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
renderButton.setForeground(table.getSelectionForeground());
renderButton.setBackground(table.getSelectionBackground());
} else {
renderButton.setForeground(table.getForeground());
renderButton.setBackground(UIManager.getColor("Button.background"));
}

if (hasFocus) {
renderButton.setBorder(focusBorder);
} else {
renderButton.setBorder(originalBorder);
}

// renderButton.setText( (value == null) ? "" : value.toString() );
if (value == null) {
renderButton.setText("");
renderButton.setIcon(null);
} else if (value instanceof Icon) {
renderButton.setText("");
renderButton.setIcon((Icon) value);
} else {
renderButton.setText(value.toString());
renderButton.setIcon(null);
}

return renderButton;
}

//
// Implement ActionListener interface
//
/*
* The button has been pressed. Stop editing and invoke the custom Action
*/
@Override
public void actionPerformed(ActionEvent e) {
int row = table.convertRowIndexToModel(table.getEditingRow());
fireEditingStopped();

// Invoke the Action

ActionEvent event = new ActionEvent(table,
ActionEvent.ACTION_PERFORMED, "" + row);
action.actionPerformed(event);
}

//
// Implement MouseListener interface
//
/*
* When the mouse is pressed the editor is invoked. If you then then drag
* the mouse to another cell before releasing it, the editor is still
* active. Make sure editing is stopped when the mouse is released.
*/
@Override
public void mousePressed(MouseEvent e) {
if (table.isEditing() && table.getCellEditor() == this)
isButtonColumnEditor = true;
}

@Override
public void mouseReleased(MouseEvent e) {
if (isButtonColumnEditor && table.isEditing())
table.getCellEditor().stopCellEditing();

isButtonColumnEditor = false;
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}
}

最佳答案

问题不在于编辑器。 SPACE 击键也不会转发到第一列中的默认编辑器。

问题在于 JTable 为 SPACE 键定义了一个 Action,因此它在有机会传递给编辑器之前就被拦截了。在我的博客中搜索 Key Bindings 条目,您会在其中找到一个列出 JTable 所有默认键绑定(bind)的程序。调用的操作称为“addToSelection”,所以我不确定为什么它会根据行选择而有所不同。

无论如何,一种解决方案是删除此操作:

InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke space = KeyStroke.getKeyStroke("SPACE");
im.put(space, "none");

关于java - 通过键盘在 JTable 中按下 JButton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19098689/

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