【发布时间】:2012-03-24 04:59:26
【问题描述】:
我需要一个 JToggleButton(具有自定义背景),其中包含一个 JPanel,其中包含多个 JLabel。那部分有效。
此按钮随后被放置在 JTable 单元格中,并且是供用户按下的。问题是我只能在第二次点击时按下按钮。 Apperenty 在第一次单击时,焦点首先跳转到带有 JLabels 的面板,然后才跳转到实际按钮。
我尝试了几种方法来尝试解决此问题,但同样的问题仍然存在。 A) 将带有标签的 JPanel 直接放在 JToggleButton#add() 上。 B) 使用 JLayeredPane 将 Button 和 JPanel 放置到 JToggleButton 采用约束 Integer(-) 的不同层上,以便带有 JLabels 的 JPanel 在顶部保持可见
你有什么建议吗?谢谢
以下是说明问题的示例代码。单击该按钮仅第二次起作用。
public class ClickableCustomButtonInTable extends JToggleButton {
public ClickableCustomButtonInTable() {
Dimension d = new Dimension(100, 100);
JLabel lFirst = new JLabel("1st label");
lFirst.setPreferredSize(d);
JLabel lSecond = new JLabel("2nd label");
lSecond.setPreferredSize(d);
JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setLayout(new BorderLayout());
panel.add(lFirst, BorderLayout.NORTH);
panel.add(lSecond, BorderLayout.SOUTH);
add(panel);
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});
}
private static class CustomButtonRenderer implements TableCellRenderer {
private final ClickableCustomButtonInTable button = new ClickableCustomButtonInTable();
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
return button;
}
}
private static class CustomButtonEditor extends AbstractCellEditor
implements TableCellEditor {
private final ClickableCustomButtonInTable button = new ClickableCustomButtonInTable();
@Override
public Object getCellEditorValue() {
return button.getText();
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
return button;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(200, 200));
Container content = frame.getContentPane();
TableModel model = new AbstractTableModel() {
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return null;
}
@Override
public int getRowCount() {
return 1;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return ClickableCustomButtonInTable.class;
}
};
JTable table = new JTable(model);
// table.setBounds(new Rectangle(0, 0, content.getWidth(), content
// .getHeight()));
table.setRowHeight(frame.getHeight());
table.setDefaultRenderer(ClickableCustomButtonInTable.class,
new CustomButtonRenderer());
table.setDefaultEditor(ClickableCustomButtonInTable.class,
new CustomButtonEditor());
content.add(table);
content.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
【问题讨论】:
-
与您的问题没有直接关系:编辑器实现无效:当编辑因内部原因终止时,它必须通知其侦听器。至于你的问题:基本上你必须a)确保在第一次点击时开始编辑b)抓住那个点击,计算它在编辑组件坐标中的位置并在编辑时发送到“真实”目标组件(fi按钮)面板
-
顺便说一句:你永远不会在你的 tableModel 中保留组件......因为你的 TableModel 实现也很可疑(它宣布可编辑但缺少任何 api 来更改单元格值),也许您应该阅读并理解一些表格基础知识,然后再跳到不那么琐碎的东西中间:-)
-
@kleopatra,感谢您的提示。您能否链接/显示如何 a) 确保在第一次单击时开始编辑 b) 抓住该单击,计算其在编辑组件坐标中的位置并发送到编辑面板上的“真实”目标组件我不确定是什么你的意思是通过将事件调度到真正的目标,是 doClick() 调用你的意思。如果是这样,恐怕我会失去 jToggleButton 提供的点击动画。
-
TablePopupEditor可以替代吗? -
垃圾神,不是真的。我需要的是一个可点击的 ToggleButton,上面放置了一些附加小部件,没有弹出窗口。
标签: java swing jtable jlayeredpane jtogglebutton