使用 JPanel 作为 JTable 单元格编辑器时获取焦点的问题

发布于 2024-09-28 14:14:14 字数 2889 浏览 3 评论 0原文

我有一个单元格编辑器,其中包含一个小按钮,可以双击该按钮来弹出编辑对话框,然后是一个可用于内联编辑值的文本字段(需要弹出窗口才能编辑其他值,仅允许编辑第一个显示在 JTable 中)。

当用户单击字段时,一切正常,但如果他们使用 Tab 键进入该字段,则文本字段不会获得焦点,并且除非用鼠标单击该字段,否则他们无法编辑该字段。

我尝试摆弄 jpanel 的各种焦点方法,但没有什么区别,有人知道我做错了什么吗?

package com.jthink.jaikoz.celleditor;

import com.jthink.jaikoz.celldata.Cell;
import com.jthink.jaikoz.guielement.Focus;
import com.jthink.jaikoz.table.CellLocation;
import com.jthink.jaikoz.table.DatasheetToggleButton;
import com.jthink.jaikoz.table.datasheet.Datasheet;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class SimpleMultiRowCellEditor
    extends DefaultCellEditor implements ActionListener
{

    final JPanel panel;
    private final DatasheetToggleButton rowCount;
    Cell value;

    public SimpleMultiRowCellEditor(final JTextField text)
    {
        super(text);
        this.setClickCountToStart(1);

        rowCount = new DatasheetToggleButton();
        rowCount.setVisible(true);
        rowCount.addActionListener(this);
        panel = new JPanel();
        panel.setOpaque(false);
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        panel.add(rowCount);
        panel.add(editorComponent);
        /*panel.setFocusable(true);
        panel.setFocusCycleRoot(true);
        ArrayList focusOrder = new ArrayList();
        focusOrder.add(editorComponent);
        focusOrder.add(rowCount);
        focusOrder.add(panel);
        panel.setFocusTraversalPolicy(new Focus(focusOrder));
        */
    }

    public Component getTableCellEditorComponent(
        final JTable table, final Object val, final boolean isSelected,
        final int row, final int column)
    {
        value = (Cell) ((Cell) val).clone();
        rowCount.setText(String.valueOf(value.getValues().size()));
        delegate.setValue(value.getValue());
        return panel;
    }

    public Object getCellEditorValue()
    {
        final String s = (String) delegate.getCellEditorValue();
        value.setValue(s);
        return value;
    }

    public void actionPerformed(final ActionEvent e)
    {
        this.stopCellEditing();
        final CellLocation cl =  Datasheet.getActiveEditSheet()
            .getTable().getSelectedCellLocations().get(0);
        UpdateMultiRowCellDialog.getInstanceOf().display(value,cl);
    }
}

尝试将 focuslistener 添加到面板,似乎没有任何区别

class PanelFocusListener implements FocusListener
{
    public void focusGained(FocusEvent e)
    {
        System.out.println("Gained Focus");
        editorComponent.requestFocusInWindow();
    }

    public void focusLost(FocusEvent e)
    {
        System.out.println("Lost Focus");

    }
}

所以在按 Tab 键进入字段后,我键入一个键,看起来好像获得了焦点,但您无法在字段中输入任何内容,而如果我键入 RETURN 那么我可以开始编辑字段,按 RETURN 会做什么使其能够工作?

I have a cell editor that contains a little button that can be double clicked on to bring up an edit dialog, and then a textfield that can be used to edit the value inline (the popup is required to allow editing of additional values, only the first is shown in the JTable).

When user clicks on field everything is okay, but if they tab into the field they textfield doesn't receive focus and they cannot edit the field unless they click on it with the mouse.

I tried fiddling with the various focus methods of jpanel but it made no difference, anybody know what Im doing wrong ?

package com.jthink.jaikoz.celleditor;

import com.jthink.jaikoz.celldata.Cell;
import com.jthink.jaikoz.guielement.Focus;
import com.jthink.jaikoz.table.CellLocation;
import com.jthink.jaikoz.table.DatasheetToggleButton;
import com.jthink.jaikoz.table.datasheet.Datasheet;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class SimpleMultiRowCellEditor
    extends DefaultCellEditor implements ActionListener
{

    final JPanel panel;
    private final DatasheetToggleButton rowCount;
    Cell value;

    public SimpleMultiRowCellEditor(final JTextField text)
    {
        super(text);
        this.setClickCountToStart(1);

        rowCount = new DatasheetToggleButton();
        rowCount.setVisible(true);
        rowCount.addActionListener(this);
        panel = new JPanel();
        panel.setOpaque(false);
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        panel.add(rowCount);
        panel.add(editorComponent);
        /*panel.setFocusable(true);
        panel.setFocusCycleRoot(true);
        ArrayList focusOrder = new ArrayList();
        focusOrder.add(editorComponent);
        focusOrder.add(rowCount);
        focusOrder.add(panel);
        panel.setFocusTraversalPolicy(new Focus(focusOrder));
        */
    }

    public Component getTableCellEditorComponent(
        final JTable table, final Object val, final boolean isSelected,
        final int row, final int column)
    {
        value = (Cell) ((Cell) val).clone();
        rowCount.setText(String.valueOf(value.getValues().size()));
        delegate.setValue(value.getValue());
        return panel;
    }

    public Object getCellEditorValue()
    {
        final String s = (String) delegate.getCellEditorValue();
        value.setValue(s);
        return value;
    }

    public void actionPerformed(final ActionEvent e)
    {
        this.stopCellEditing();
        final CellLocation cl =  Datasheet.getActiveEditSheet()
            .getTable().getSelectedCellLocations().get(0);
        UpdateMultiRowCellDialog.getInstanceOf().display(value,cl);
    }
}

Tried adding focuslistener to panel, didnt seem to make any difference

class PanelFocusListener implements FocusListener
{
    public void focusGained(FocusEvent e)
    {
        System.out.println("Gained Focus");
        editorComponent.requestFocusInWindow();
    }

    public void focusLost(FocusEvent e)
    {
        System.out.println("Lost Focus");

    }
}

So after tabbing into field, I type a key and it sorts of look likes focus is gained but you cannot enter anything into the field whereas if I type RETURN then I can start editing the field, what does pressing RETURN do that allows it to work ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

按 RETURN 键有何作用使其能够工作?

如方便的按键绑定 应用程序,大多数 L&F 中默认的 ENTER 键绑定是 notify-field-accept。目前尚不清楚为什么您的 ActionListener stopCellEditing() 开头。我希望它在更新数据模型后调用 fireEditingStopped(),如 示例

遗憾的是,我不熟悉 Jaikoz。您可以查看概念:编辑器和渲染器 以及后续部分以获取更多指导。

附录:正如您的评论中所述,DefaultCellEditor 中的 JTextField 允许默认在所选字段中输入内容。从您的示例中尚不清楚该默认值如何被取消。如果没有说明问题的 sscce,您可以将您的代码与相关的 示例使用 JTextField 的子类展示默认行为。

what does pressing RETURN do that allows it to work?

As shown in the handy Key Bindings application, the default ENTER key binding in most L&Fs is notify-field-accept. It's not clear why your ActionListener begins with stopCellEditing(). I would have expected it to invoke fireEditingStopped() after updating the data model, as suggested in this example.

Sadly, I'm unfamiliar with Jaikoz. You might look at Concepts: Editors and Renderers and the subsequent sections for additional guidance.

Addendum: As noted in your comment, a JTextField in a DefaultCellEditor allows typing in the selected field by default. It's not clear from your example how that default is being nullified. Absent an sscce that demonstrates the problem, you might compare your code with this related example that exhibits the default behavior using a subclass of JTextField.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文