【问题标题】:How to create a "naval Battle" style table with radio buttons in JSF如何在 JSF 中创建带有单选按钮的“海战”样式表
【发布时间】:2015-01-30 12:06:30
【问题描述】:

如何创建带有单选按钮的“海战”样式表,我在其中发送单选按钮 ( column ) 的值和 Line (line) 的值。

例如:

alfa beta omega

o     x     x    A
x     o     x    B
x     o     x    C

作为被选中的“o”,我想在 backing bean 中接收 ALFA 和 A、BETA 和 B 以及 BETA 和 C,在每一行而不是列中单独选择。 问题是根据从数据库中检索到的行数,列数是动态的。

这就是我现在设法做的事情。列是单位,行是线

<h:dataTable value="#{unidadeController.listLines}" var="itemList">

                            <h:column>
                                <c:forEach var="i" begin="0"
                                    end="#{bean.listUnits.size()-1}">

                                    <f:facet name="header">
                                        <h:outputText value="#{bean.getUnitName(i)}" />
                                        <p:spacer width="50" height="0" />
                                    </f:facet>
                                </c:forEach>
                                <h:selectOneRadio value="#{bean.unit}">
                                    <f:selectItems value="#{bean.listUnits}"
                                        var="c" itemLabel="" itemValue="#{c.id}" />
                                </h:selectOneRadio>
                            </h:column>

                            <h:column>
                                <f:facet name="header">
                                    <h:outputText value="#{labelController.name}" />
                                    <br />
                                </f:facet>
                                <h:outputText value="#{itemList.name}" />
                                <br />
                            </h:column>

                        </h:dataTable>

豆子:

private Unit unit = new Unit();

private List<Unit> units = new ArrayList<Unit>();

 public List<Unit> getListUnits()
    {
        if (this.units.isEmpty())
        {
            try
            {
                this.units= Cache.getInstance().getUnits();
            }
            catch (final WplexEOException e)
            {
                e.printStackTrace();
            }
        }
        return this.units;
    }

public List<Line> getListLines()
{
    try
    {
        return Cache.getInstance().getLines();
    }
    catch (final WplexEOException e)
    {
        e.exibeErroNaPagina();
    }
    return new ArrayList<Line>();
}

public String getUnitName(final int index)
    {
        return this.units.get(index).getName();
    }

阿尔法、贝塔、欧米茄是单位。 a,b,c 是线条。

Nome 是葡萄牙语中的名称,如行名。

它呈现我想要的方式,但是收音机没有将它的值传递给 bean,我还需要发送行索引或值。我该如何解决/改进这个问题?

编辑: 我将表格更改为使用地图,但是当我访问地图时它是空的。

        <h:dataTable value="#{bean.listLines}" var="itemList">

                        <h:column>
                            <c:forEach var="itemForEach" items="#{bean.listUnits}" >
                                <f:facet name="header">
                                    <h:outputText value="#{itemForEach.getName()}" />
                                    <p:spacer width="50" height="0" />
                                </f:facet>
                            </c:forEach>
                            <h:selectOneRadio value="#{bean.mapLines[itemList]}" converter="javax.faces.Integer">
                                <f:selectItems value="#{bean.listaUnits}"
                                    var="c" itemLabel="" itemValue="#{c.id}" />
                            </h:selectOneRadio>
                        </h:column>

                        <h:column>
                            <f:facet name="header">
                                <h:outputText value="#{labelController.name}" />
                                <br />
                            </f:facet>
                            <h:outputText value="#{itemList.name}" />
                            <br />
                        </h:column>

                    </h:dataTable>

豆子:

private Map<Line, Integer> mapLines = new HashMap<Line, Integer>();

线路类:(葡萄牙语,对不起)

林哈=线

名称 = 名称

Unidade = 单位

   /*
 * $Id: javadoctemplates.xml,v 1.2 2007/05/29 19:28:02 mauro Exp $
 * 
 * Copyright (c) 2004-2007 Wplex Software Ltda. All rights reserved.
 */

package com.wplexeo.model;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.GenericGenerator;

import com.wplexeo.exception.WplexEOException;

/**
 * Linha da programação
 *
 * @author 
 */
@Entity(name = "linha")
@GenericGenerator(name = "gen", strategy = "native")
public class Linha extends Entidade implements Serializable
{
    private static final long serialVersionUID = 1L;

    private String nome; //name

    @ManyToOne
    private Unidade unidade;

    /**
     * @param idDaBusca
     * @return Evento
     * @throws WplexEOException
     */
    public static Linha buscaPorId(final Long idDaBusca) throws WplexEOException
    {
        return (Linha) Entidade.buscaPorId(Linha.class, idDaBusca);
    }

    /**
     * @return Evento
     * @throws WplexEOException
     */
    @SuppressWarnings("unchecked")
    public static List<Linha> lista() throws WplexEOException
    {
        return (List<Linha>) Entidade.lista(Linha.class);
    }

    /**
     * @throws WplexEOException
     */
    public static void removeTodos() throws WplexEOException
    {
        Entidade.removeTodos(Linha.class);
    }

    /**
     * @return the nome
     */
    public String getNome()
    {
        return this.nome;
    }

    /**
     * @param nome the nome to set
     */
    public void setNome(final String nome)
    {
        this.nome = nome;
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + (this.nome == null ? 0 : this.nome.hashCode());
        result = prime * result + (this.unidade == null ? 0 : this.unidade.hashCode());
        return result;
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj)
    {
        if (this == obj)
        {
            return true;
        }
        if (!super.equals(obj))
        {
            return false;
        }
        if (this.getClass() != obj.getClass())
        {
            return false;
        }
        final Linha other = (Linha) obj;
        if (this.nome == null)
        {
            if (other.nome != null)
            {
                return false;
            }
        }
        else if (!this.nome.equals(other.nome))
        {
            return false;
        }
        if (this.unidade == null)
        {
            if (other.unidade != null)
            {
                return false;
            }
        }
        else if (!this.unidade.equals(other.unidade))
        {
            return false;
        }
        return true;
    }
}

【问题讨论】:

  • 我在上面的示例中缺少方法 bean.getUnitName(int i)。
  • 更新显示方法
  • 啊,是的,我没有解释这一点是我的错误。每行的单一选择。因此,在我的示例中,您可以选择三个 omega:omega a、omega b、omega c。
  • 啊大声笑...好吧忽略我的回答它很遥远,我没有时间重做它。我以为您只想在整个网格中进行 1 个选择。每行一个选择非常简单,我相信有人能够回答这个问题。否则我会在一天结束时改变我的答案
  • @Joeblade 不要删除它,它会有所帮助。让我玩一下你的想法

标签: jsf jsf-2


【解决方案1】:

首先我很确定你可以替换它

<c:forEach var="i" begin="0" end="#{bean.listUnits.size()-1}">
    <f:facet name="header">
        <h:outputText value="#{bean.getUnitName(i)}" />
        <p:spacer width="50" height="0" />
    </f:facet>
</c:forEach>

With(假设 bean 有一个 getName() 方法)

<c:forEach var="beanListUnit" items="#{bean.listUnits">
    <f:facet name="header">
        <h:outputText value="#{beanListUnit.getName()}" />
        <p:spacer width="50" height="0" />
    </f:facet>
</c:forEach>

其次,我不会使用 Cache.getInstance 并为不同的行重用私有 List 单元,但现在保持不变。

然后是如何检测行+列,我以前是怎么做的(这可能已经过时了,但是 :D 这是我想出来的方式)是做类似的事情:

<h:dataTable value="#{unidadeController.listLines}" var="itemList">
    <h:column>
        <c:forEach var="currentBean" items="#{bean.listUnits}">
            <f:facet name="header">
                <h:outputText value="#{bean.getUnitName(i)}" />
                <p:spacer width="50" height="0" />
            </f:facet>
        </c:forEach>
        <h:selectOneRadio value="#{bean.unit}" valueChangeListener="#{bean.radioButtonChange}">
            <f:selectItems value="#{bean.listUnits}" var="c" itemLabel="" itemValue="#{bean.id}:#{c.id}" />
        </h:selectOneRadio>
    </h:column>

    <h:column>
        <f:facet name="header">
            <h:outputText value="#{labelController.name}" /><br />
        </f:facet>
        <h:outputText value="#{itemList.name}" /><br />
    </h:column>
</h:dataTable>

并使用以下方法扩展您的 bean:(请参阅 mkyong's example

public void radioButtonChange(ValueChangeEvent valueChangeEvent) {
    // value was changed
    String newValue = e.getNewValue().toString(); // assert not null etc
    String[] rowCol = newValue.split(":"); // assert rowCol.length == 2
    String rowId = rowCol[0];
    String colId = rowCol[1];
    // do what you wanted to do, sink a battleship
}

我已经陷入了一些伪代码,

<f:selectItems value="#{bean.listUnits}" var="c" itemLabel="" itemValue="#{bean.id}:#{c.id}" />

但基本上,我会在 itemValue 中对行和列进行编码(假设 c.id 尚未包含两者的信息)并且 onItemChange 我会再次拆分此信息,以便您可以对其采取行动。

如果 id 已经包含此信息(每行/列唯一,则可以忽略此部分)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 2019-10-18
    相关资源
    最近更新 更多