【问题标题】:Change value of widget inside GWT flex table when other widget's value changes?当其他小部件值更改时,更改 GWT flextable 中小部件的值?
【发布时间】:2016-10-27 11:18:51
【问题描述】:

好的,所以我有一个非常具体且对我来说非常复杂的问题,因为我是 GWT 新手。

我有一个 GWT 弹性表,用于动态添加行,其单元格包含 GWT 小部件。行号发生变化,但静态的列数始终为 6。每行包含一个带有删除按钮的单元格和五个单元格,每个单元格都有自己的文本框。

我需要做的是以某种方式在一行的单元格 6 中的文本框和下一行的单元格 5 中的文本框之间编写一种关系(反之亦然)。

为了说明:当 [1,6] 处的文本框发生变化时,需要用相同的值覆盖 [2,5] 处的文本框内容。如果 [2,5] 处的文本框更改,则 [1,6] 处的文本框也需要更改。我不能使用按钮来提交更改,它需要通过 onValueChange 或 Blur 或类似的方式发生,这不需要用户执行特定操作。

我的问题主要源于试图弄清楚如何处理 flex 表中的特定单元格及其内容。对于删除按钮,使用单击事件处理程序很容易解决,但对于这个问题,我似乎无法提出解决方案。

很遗憾,我也无法提供到目前为止我拥有的任何代码,因为它是商业机密。我只能对上述问题进行广泛的描述。

编辑: 实际上,就这个具体问题而言,可能更多的是代码不多的问题。

我拥有的是一个弹性表格,它最初只有标题行。单击此表下方的按钮后,将调用 addNewField() 方法,该方法仅包含创建、设置默认值以及将文本字段添加到新行中。

addNewField() {
int rows = flextable.getRowCount();
Button removeBtn = new Button("x");
removeBtn.getElement().setId(Integer.toString(rows));
//then the button's event handler
TextBox name = new TextBox();
name.setText("something");
flextable.setWidget(rows, 0, "name");
//repeat 4 more times with incrementing columns for the other widgets
}

这样我可以添加整行可编辑的文本框。我需要一种方法来影响所选行的第 6 列 TextBox 和所选行 + 1 的第 5 列 TextBox 的值。

EDIT2:我尝试了dirty选项只是为了看看它会如何运行,并且if内部的比较会破坏应用程序。编译器检测到空指针异常,我什至无法使用断点对其进行调试,因为它无法编译并且无法启动。我不知道为什么。出于测试目的,我将代码直接放入事件中,请原谅丑陋。

TextBox bis = new TextBox();
bis.setText(rows + ":10:00");
subs.setWidget(rows, 5, bis);

bis.addValueChangeHandler(new ValueChangeHandler<String>()
{

    @Override
    public void onValueChange(ValueChangeEvent<String> event)
    {
        allRows: for (int i = 0; i < subs.getRowCount(); i++)
        {
            for (int j = 0; j < subs.getCellCount(i); j++)
            {
                if ( subs.getWidget(i, j) == bis )
                {
                    TextBox widgetAtColumnSix = ((TextBox) subs.getWidget(i, 5));
                    String text = widgetAtColumnSix.getText();

                    TextBox widgetAtColumnFiveRowPlusOne = ((TextBox) subs.getWidget(i + 1, 4));
                    widgetAtColumnFiveRowPlusOne.setText(text);
                    break allRows;
                }

            }
        }

    }
});

【问题讨论】:

  • 其实你可以给出一个不泄露商业机密的代码示例。展示你的所作所为会有很大帮助

标签: gwt


【解决方案1】:

编辑:由于您编辑了您的问题并且您不想使用 EventBus,您可以迭代您的 FlexTable 并根据您当前的 rowIndex 和 cellIndex 设置您的 TextBox 值......它不是很好,但它应该可以工作:

public class CellWidget extends Composite {

    private TextBox nameBox;

    public CellWidget() {
        FlowPanel flowPanel = new FlowPanel();
        Button deleteButton = new Button("x");
        nameBox = new TextBox();
        nameBox.addValueChangeHandler(new ValueChangeHandler<String>() {

            @Override
            public void onValueChange(ValueChangeEvent<String> event) {
                notifiyTextBox(CellWidget.this, event.getValue());
            }
        });
        flowPanel.add(nameBox);
        flowPanel.add(deleteButton);
        initWidget(flowPanel);
    }

    public void setText(String text) {
        nameBox.setText(text);
    }

}

public void notifiyTextBox(CellWidget source, String string) {
    rows: for (int i = 0; i < flextable.getRowCount(); i++) {
        columns: for (int j = 0; j < flextable.getCellCount(i); j++) {
            if (flextable.getWidget(i, j) == source) {
                CellWidget widgetAtColumnSix = ((CellWidget) flextable.getWidget(i, 5));
                widgetAtColumnSix.setText(string);

                CellWidget widgetAtColumnFiveRowPlusOne = ((CellWidget) flextable.getWidget(i + 1, 4));
                widgetAtColumnFiveRowPlusOne.setText(string);
                break rows;
            }

        }
    }

}

我仍然建议使用事件总线。为了使它更方便,还有GWT Event Binder lib,它使使用事件变得轻而易举。

因此,当您更改文本框 [2,5] 中的值时,它也会触发您的 CustomEvent。所有需要更改其文本框值的小部件只需要捕获...

【讨论】:

  • 请耐心等待,这是我第一次尝试制作和理解尚未内置的事件侦听器。我想我了解自定义事件和小部件的基本结构,但我似乎无法理解的是事件如何知道它应该只更改一个特定的文本框而不是全部。 textBox [1,6] 发生的事件如何知道仅影响 textBox [2,5],textBox [2,6] 如何知道仅影响 textBox [3,6] 等。我也不确定如果我什至可以使用自定义库,如果我不会,还有其他解决方案吗?
  • EventBinder 基本上只是内置 EventBus 的包装器,以减少样板文件 (gwtproject.org/javadoc/latest/com/google/gwt/event/shared/…)。区分 TextBox 应该监听哪个事件的最简单方法是为每个事件创建不同的事件。例如:TextBox1ChangedEventTextBox2ChangedEvent。如果TextBox1 的值发生变化,它会触发TextBox1ChangedEvent。您想要收听的所有其他文本框将实现 void onEvent(TextBox1ChangedEvent event) 并对其做出反应
  • 我添加了一个希望更简单快捷的解决方案
  • 如果他们允许的话,我会使用事件绑定器,但至少我还有一个替代方案。谢谢!
  • 其实我并没有测试脏代码,只是给你一个提示。如果任何单元格值可能为空,你应该为此设置一个 if 子句。如果您编辑最后一行的文本框,还会发生什么?它将尝试转到下一行并抛出异常。
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 2014-04-18
  • 2021-04-26
  • 2022-12-21
  • 2021-02-04
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多