gpt4 book ai didi

java - 将带有 JPanel 的 JToggleButton 放入 JTable 单元格中

转载 作者:搜寻专家 更新时间:2023-10-31 19:40:57 25 4
gpt4 key购买 nike

我需要一个 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);
}
}

最佳答案

当表格捕获鼠标事件以选择单元格时,它会将鼠标事件传递给最深的组件,而不管该组件是否可以处理鼠标事件。在您的示例中,第一次点击结束于其中一个 JLabels,完全绕过了 JToggleButton。一旦 JToggleButton 成为 Activity 的单元格编辑器,鼠标点击就会正常作用于它。如果它失去焦点,它将再次需要两次单击才能激活。

如果您在演示中注意到您单击了按钮边框而不是包含的面板,您也可以看到这一点,按钮按预期工作。

解决此问题的一种方法是确保针对 JToggleButton 中的任何组件的任何鼠标事件。您可以使用此静态方法执行此操作:

static void addEventBubble(final Container target, Container container) {
for(Component comp:container.getComponents()) {
if (comp instanceof Container) {
addEventBubble(target, (Container) comp);
}
comp.addMouseListener(new MouseAdapter() {
private MouseEvent retarget(MouseEvent e) {
return new MouseEvent(target, e.getID(), e.getWhen(),
e.getModifiers(), e.getX(), e.getY(),
e.getClickCount(), e.isPopupTrigger(),
e.getButton());
}


public void mousePressed(MouseEvent e) {
MouseEvent r = retarget(e);
for(MouseListener listen:target.getMouseListeners()) {
listen.mousePressed(r);
}
}


public void mouseReleased(MouseEvent e) {
MouseEvent r = retarget(e);
for(MouseListener listen:target.getMouseListeners()) {
listen.mouseReleased(r);
}
}


public void mouseClicked(MouseEvent e) {
MouseEvent r = retarget(e);
for(MouseListener listen:target.getMouseListeners()) {
listen.mouseClicked(r);
}
}
});
}
}

然后在构造函数调用的末尾:

addEventBubble(this,this);

在此之后,按钮内任何组件上的任何鼠标事件也将到达按钮并因此改变其状态。完成此操作后,我发现该按钮对每次点击都做出了所需的 react 。

关于java - 将带有 JPanel 的 JToggleButton 放入 JTable 单元格中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9588384/

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