使用 IceFaces 的动态样式:如何在渲染时更改 outputText 的颜色?

Dynamic styling with IceFaces: how can I change the color of the outputText at the time of rendering?

我是 ICEFaces 的新手,我必须维护别人的代码。我正在进行网络聊天,用户可以在其中发送和接收消息。我希望消息根据它们是由用户发送还是由其他人发送而具有不同的颜色。

目前我的 xhtml 文件中有以下代码:

<h:dataTable id="history" value="#{chatBean.messages}" var="message" border="0" align="left" style="width: 100%" >
    <h:column width="590" height="25" align="left" valign="bottom" >
        <h:outputText value="#{message}" styleClass="#{chatBean.messageColor}" />
    </h:column>
</h:dataTable>

这显示了所有发送和接收的消息,但所有消息都具有相同的颜色,即使聊天 bean 的 messageColor 属性 发生了变化:我做了一个实验并在末尾附加了 getMessageColor() 的结果每条消息的颜色确实发生了变化,但文本仍以相同的颜色呈现。

CSS 具有以下 classes(以及其他):

.class1
{
  color:#818181;
  width: 100%; 
  font-size: 15px; 
  font-family: Arial, Helvetica, sans-serif; 
  font-weight: bold;    
}

.class2
{
  color:#00657c;
  width: 100%; 
  font-size: 15px; 
  font-family: Arial, Helvetica, sans-serif; 
  font-weight: bold;
} 

这是 ChatBean 的代码 class:

@ManagedBean(name = "chatBean")
@SessionScoped
public class ChatBean implements Serializable {
  private static final long serialVersionUID = -12636320254821872L;
  private static final String PUSH_GROUP = "chatPage";
  private PortableRenderer renderer;
  private String message;
  private String lastMessageSent = "";
  private Date lastMessageTime = new Date();
  private String isDown = "false";
  private List<String> messages = new ArrayList<String>();
  private String buttonDisabled = "true";
  private String buttonCancelDisabled = "true";
  private String pollDisabled = "false";
  private String id = "";
  private ChatClient chat;
  private Timer timer = new Timer();
  private String messageColor;

  public class ChatThread extends Thread implements Serializable {
      private static final long serialVersionUID = -7636532554421738019L;
      private Map<String, String> data;
      private String mail;
      public ChatThread(final Map<String, String> data, final String mail) {
          this.data = data;
          this.mail = mail;
      }
      @Override
      public void run() {
          chat = new ChatClient(new ChatClient.Event() {
              @Override
              public void handle(String msg) {
                  if(msg != null && msg.length() > 0)
                      pushMessage(msg);
              }
              @Override
              public void agentConnected(String msg) {
                  buttonDisabled = "false";
                  buttonCancelDisabled = "false";
                  pushMessage(msg);
              }
              @Override
              public void agentDisconnected(String msg) {
                  buttonDisabled = "true";
                  pushMessage(msg);
                  try {
                      timer.cancel();
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          });

          chat.login(mail, data);
          chat.join(mail, data.get("partner"), data.get("business"));
          timer.scheduleAtFixedRate(new RefreshTimerTask(), 0, 1000);
      }
  }
  public class RefreshTimerTask extends TimerTask implements Serializable {
      private static final long serialVersionUID = 1852678537009150141L;
      public void run() {
          chat.refresh();
      }
  }

  public ChatBean() {
      if(getSession() != null) {
          id = getSession().getId();
          PushRenderer.addCurrentSession(PUSH_GROUP + id);
          renderer = PushRenderer.getPortableRenderer();
          setMessageColor("class1");
          Log.getLogger().debug("New chat bean.");
          if(getData().containsKey("login_chat")) {
              ChatThread chat = new ChatThread(getData(), getSessionAttribute(GenesysSingleton.getInstance().getConfigApp().getDisplayName(), "<mail>"));
              chat.start();
          }
      }
  }

  private void pushMessage(String msg) {
      if(msg != null && !msg.isEmpty()) {
          ChatBean.this.isDown = "true";
          messages.add(msg);//Acá se puede acceder a textColor.
          try {
              PushRenderer.render(PUSH_GROUP + id);
          } catch (Exception e) {
              renderer.render(PUSH_GROUP + id);
          }
          setMessageColor("class1");
      }
  }
  private String getSessionAttribute(String key, String ref) {
      Object value = getSession().getAttribute(key);
      return value != null ? value.toString() : ref;
  }

  private Map<String, String> getData() {
      Map<String, String> data = new HashMap<String, String>();
      HttpSession session = getSession();
      @SuppressWarnings("rawtypes")
      Enumeration enums = session.getAttributeNames();
      while(enums.hasMoreElements()) {
          String key = enums.nextElement().toString();
          if(!"com.sun.faces.application.view.activeViewMaps".equals(key)
              && !"com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap".equals(key)
              && !"javax.faces.request.charset".equals(key))
              data.put(key, session.getAttribute(key).toString());
      }
      return data;
  }

  public void sendMessage(ActionEvent event) {
      sendMessage();
  }

  protected synchronized void sendMessage() {
      if (message != null && !message.trim().isEmpty()){
          Date now = new Date();
          //No permito mandar el mismo mensaje 2 veces seguidas en un intervalo menor a un segundo.
          message = message.trim();
          if (message.equals(lastMessageSent)&&(now.getTime()<(1000+lastMessageTime.getTime()))){
              message = null;
          }
          else{
              setMessageColor("class2");
              lastMessageSent = message;
              message = null;
              lastMessageTime = new Date();
              chat.refresh(lastMessageSent);
          }
      }
  }

  public String disconnect() {
      pollDisabled = "true";
      return "login";
  }

  public void sendClose(ActionEvent event) {
  }

  public void receiveMessage() {
  }

  @PreDestroy
  public void destroy() {
      buttonDisabled = "true";
      try {

          //pushMessage(SISTEMA_3);
      } catch (Exception e) {
          e.printStackTrace();
      }
      try {
          Thread.sleep(1000);
      } catch (InterruptedException e) {
          e.printStackTrace();
      };
      System.out.println(id + "- ssssssss");
      try {
          timer.cancel();
      } catch (Exception e) {
      }
      chat.logout();
      chat.close();
  }

  private HttpSession getSession() {
      return (HttpSession) getContext().getSession(false);
  }
  private ExternalContext getContext() {
      return getFacesContext().getExternalContext();
  }
  private FacesContext getFacesContext() {
      return FacesContext.getCurrentInstance();
  }

  public String getMessage() {
      return message;
  }

  public void setMessage(String message) {
      this.message = message;
  }

  public String getButtonDisabled() {
      return buttonDisabled;
  }

  public void setButtonDisabled(String buttonDisabled) {
      this.buttonDisabled = buttonDisabled;
  }

  public List<String> getMessages() {
      try {
          JavascriptContext.addJavascriptCall(getFacesContext(), "document.getElementById('scrollDataTable').scrollIntoView();");
      } catch (Exception e) {
          e.printStackTrace();
      }
      return messages;
  }

  public void setMessages(List<String> messages) {
      this.messages = messages;
  }

  public String getPollDisabled() {
      return pollDisabled;
  }

  public void setPollDisabled(String pollDisabled) {
      this.pollDisabled = pollDisabled;
  }

  public String getButtonCancelDisabled() {
      return buttonCancelDisabled;
  }

  public void setButtonCancelDisabled(String buttonCancelDisabled) {
      this.buttonCancelDisabled = buttonCancelDisabled;
  }

  public String getIsDown() {
      return isDown;
  }

  public void setIsDown(String isDown) {
      this.isDown = isDown;
  }

  public String getMessageColor() {
      return messageColor;
  }

  public void setMessageColor(String textColor) {
      this.messageColor = textColor;
  }

}

我们将不胜感激。提前谢谢你。

我根据 bean 属性 动态更改 css 的一种可能方法是使用 <h:outputText>.

styleClass 属性

在您的 css 文件中定义两个不同的 class,例如

.class1
{
    color:red; //Put your colour here (#818181)
}

.class2
{
    color:green; //Put your colour here (#00657c)
} 

然后在您的 java bean 代码中,您可以声明一个带有 getter 和 setter 的 String 字段,例如

private String messageColor;

然后在你的代码中你做的地方

setTextColor(COLOR_AGENTE);

您可以将其更改为您想要将文本更改为的 class,例如:

setMessageColor("class1");

然后在你的<h:outputText>上附上

styleClass="#{chatBean.messageColor}"

这应该很有用;

由于我最初的建议无效,你可以试试这个。
从您 chatBean 和 getters/setters 中删除 private String messageColor; 以及对 setMessageColor("class1");.

的所有调用

但请将两个 类 保留在您的 css 中。

现在在 chatBean 中声明一个带有 getter 和 setter 的布尔值 属性:

private boolean colourAgente;

声明一个方法:

public String setColor() {
    if (colourAgente) {
        return "class1";
    } else {
        return "class2";
    }

}

然后在您的 xhtml 中将 styleClass 属性更改为:

styleClass="#{chatBean.setColor()}"

最后,在您的 java 代码更改中:

setMessageColor("class1");

colourAgente = true;colourAgente=false; 取决于你想设置什么颜色。

我终于做到了,但我不得不使用丑陋的 JavaScript 解决方法。也就是说,我现在每次聊天刷新时运行这个脚本:

function updateColors(){
    var username = document.getElementById("form:username").value;
    if (username.length > 0){
        var x = document.getElementsByClassName("class1");
        if (x != null){
            for (i = 0; i < x.length; i++){
                if (x[i].innerHTML.indexOf(username) === 0){
                    x[i].className = "class2";
                }
            }
        }
    }
}

无论如何,感谢您的帮助,LiamWilson94。我仍然不知道我正在使用的代码的哪一部分使你的答案不起作用,但你给了我很多帮助我达到这个 "solution" 的见解,我在此过程中了解了一些有关 IceFaces 的知识。

好的,我找到了更好的解决方案。

我创建了一个 TextModel class:

import java.io.Serializable;



public class TextModel implements Serializable {

    private static final long serialVersionUID = -8470475291191399871L;

    private String text;

    private String clase;



    public TextModel() {

    }



    public TextModel(String text, String clase) {

        this.text = text;

        this.clase = clase;

    }



    public String getText() {

        return text;

    }



    public void setText(String text) {

        this.text = text;

    }



    public String getClase() {

        return clase;

    }



    public void setClase(String clase) {

        this.clase = clase;

    }



    public String toString() {

        return text;

    }

}

然后我把ChatBean中的messages从List改成了List,并且在ChatBean.java中改了如下函数:

private void pushMessage(String msg) {
    if(msg != null && !msg.isEmpty()) {
        ChatBean.this.isDown = "true";
        messages.add(new TextModel(msg,clase));
        try {
            PushRenderer.render(PUSH_GROUP + id);
        } catch (Exception e) {
            renderer.render(PUSH_GROUP + id);
        }
        clase = "class1";
    }
}
protected synchronized void sendMessage() {
    if (message != null && !message.trim().isEmpty()){
        Date now = new Date();
        message = message.trim();
        if (message.equals(lastMessageSent)&&(now.getTime()<(1000+lastMessageTime.getTime()))){
            message = null;
        }
        else{
            clase = "class2";
            lastMessageSent = message;
            message = null;
            lastMessageTime = new Date();
            chat.refresh(lastMessageSent);
        }
    }
}

其中 clase 是 "class1" 或 "class2"(可能更整洁,但目前有效,以后我总是可以使它更整洁)。

最后,在 chat.xhtml 上,我将 outputtext 标签更改为:

<h:outputText value="#{message.text}" styleClass="#{message.clase}" />

就是这样。不再有乱七八糟的 JavaScript 补丁。

诀窍是使 class 成为消息本身的 属性 而不是 ChatBean。

我希望这对以后的其他人有所帮助。