Update one Wicket Panel from clicking an item in another Wicket Panel - java

I have looked at many update Panel answers in SO but could not solve my problem. It is very straight forward and I don't know why I dont get the panel updated.
I have two panel created in the RadioChoicePage.java:
public class RadioChoicePage extends ApplicationPageBase{
private static final long serialVersionUID = 1L;
public TestPanel tp;
public static TextPanel txp;
public RadioChoicePage(){
tp = new TestPanel("testPanel");
txp = new TextPanel("textPanel");
txp.setMsg("Before");
add(tp);
add(txp);
}
}
The markup file looks like the following:RadioChoicePage.html
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<body>
<wicket:extend>
<div wicket:id="testPanel" style="position:absolute; left:10px ; width:50%; z-index:10;">
</div>
<div wicket:id="textPanel" style="position:absolute; left:450px; width:50%; z-index:5">
</div>
</wicket:extend>
</body>
</html>
The two panel are TestPanel.java and TextPanel.java. I have a TestPanel.js file adding svg using d3.js and clicking on a circle I want to update the text panel.
I am able to call the wicket method from javascript and print that the circle was clicked on the console. But I am not able to update the text Panel.
Below is the code for TestPanel.java, TestPanel.html, TestPanel.js , TextPanel.java and TextPanel.html.
TestPanel.java
public class TestPanel extends Panel{
public static final JavaScriptResourceReference TEST_JS = new JavaScriptResourceReference(
TestPanel.class, "TestPanel.js");
TextPanel ttxp = new TextPanel("textPanel");
public TestPanel(String id) {
super(id);
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
private static final long serialVersionUID = 1L;
public void renderHead(Component component,IHeaderResponse aResponse){
super.renderHead(component, aResponse);
String componentMarkupId = component.getMarkupId();
String callbackUrl = getCallbackUrl().toString();
aResponse.render(JavaScriptReferenceHeaderItem.forReference(TEST_JS));
aResponse.render(JavaScriptReferenceHeaderItem.forReference(D3Reference.D3_JS));
aResponse.render(OnDomReadyHeaderItem.forScript("draw(" + componentMarkupId + ",\"" + callbackUrl + "\")"));
}
protected void respond(final AjaxRequestTarget target) {
//target.add(new Label("msg", "Yeah I was just called from Javascript!"));
System.out.println("I was succesfully clicked");
ttxp.setMsg("After");
target.add(ttxp);
}
};
add(behave);
}
}
TestPanel.html
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<head>
<wicket:head>
</wicket:head>
</head>
<body>
<wicket:panel>
<div id="chart" style="position:absolute; width:400px; height:400px; border:2px solid blue;"></div>
</wicket:panel>
</body>
</html>
TestPanel.js
function draw(componentMarkupId,callbackUrl){
console.log(" Draw is called!");
//Width and height
var w = 300;
var h = 100;
//Data
var dataset = [ 5, 10, 15, 20, 25 ];
//Create SVG element
var svg = d3.select("#chart")
.append("svg")
.attr("width", w)
.attr("height", h);
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return (i * 50) + 25;
})
.attr("cy", h/2)
.attr("r", function(d) {
return d;
})
.attr("fill", "red")
.attr("stroke", "orange")
.attr("stroke-width", function(d) {
return d/2;
});
circles.on("click",function(d){
this.style.stroke = "steelblue";
$(function() {
var wcall = Wicket.Ajax.get({ u:callbackUrl });
//var wcall = wicketAjaxGet('$callbackUrl$');
alert(wcall);
});
});
}
TextPanel.java
public class TextPanel extends Panel{
String msg;
boolean initialize = true;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public TextPanel(String id) {
super(id);
// TODO Auto-generated constructor stub
System.out.println(getMsg());
if(initialize){
setMsg("Before");
initialize = false;
}
Label mmsg = new Label("msg", getMsg());
add(mmsg);
setOutputMarkupId(true);
}
}
TextPanel.html
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<head>
<wicket:head>
</wicket:head>
</head>
<body>
<wicket:panel>
<div wicket:id="msg" style="border: 2px solid blue;"></div>
</wicket:panel>
</body>
</html>
Please do give me a solution with explanation. As I have read so many solutions and explanations on SO and other resources but I feel im missing something basic here.
You can copy the code exactly and run it to check whats the real problem. I do not get any errors but Panels simple dont get updated.
Thank you for taking time to read this huge question with a small problem.

RadioChoicePage's textPanel should not be static, otherwise the component will be shared between multiple sessions:
public TextPanel txp;
Why is TestPanel creating its own instance of TextPanel?
TextPanel ttxp = new TextPanel("textPanel");
Remove that! Add a hook method to TestPanel instead:
protected void onClicked(AjaxRequestTarget target) {
}
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
protected void respond(final AjaxRequestTarget target) {
onClicked(target);
}
}
Let RadioChoicePage decide what to do when anything is clicked:
tp = new TestPanel("testPanel") {
protected void onClicked(AjaxRequestTarget target) {
target.add(txp);
}
};
txp = new TextPanel("textPanel");
txp.setOutputMarkupId(true);

Related

Vaadin Set Image as background

I am trying to implement a background image on my webpage but it does not work.
here the code for the css:
backgroundimage {
body{
background: url("common/images/blue.jpg");
}
}
Here is the implementing code:
public class LogInView extends VerticalLayout implements View {
private Navigator navigator;
TextField txtusername = new TextField("Username: ");
PasswordField txtpassword = new PasswordField("Password: ");
Image image = null;
JDBCConnectionPool connectionPool;
public LogInView() {
setStyleName("backgroundimage");
}
}
try this css (without body selector):
.backgroundimage {
background: url("common/images/blue.jpg") !important;
}
and inspect layout in browser, ensure image path is correct.

How to push updates to a Primefaces chart?

Primefaces comes with chart components. I try to update the chart through a push action, using the Atmosphere/push framework.
The xhtml:
<h:body>
<p:panel id="panel">
<p:lineChart id="category" value="#{beanViz.categoryModel}" legendPosition="e"
title="Category Chart" minY="0" maxY="200" style="height:300px;margin-top:20px"/>
</p:panel>
<h:form>
<p:commandButton value="Update" actionListener="#{beanViz.update()}"></p:commandButton>
</h:form>
<p:socket onMessage="handleMessage" channel="/counter" />
The code in beanViz to create the line chart:
int increment = 0;
private CartesianChartModel categoryModel;
public CartesianChartModel getCategoryModel() {
return categoryModel;
}
private void createCategoryModel() {
categoryModel = new CartesianChartModel();
ChartSeries boys = new ChartSeries();
boys.setLabel("Boys");
boys.set("2004", 120 + increment);
boys.set("2005", 100);
boys.set("2006", 44);
boys.set("2007", 150);
boys.set("2008", 25);
categoryModel.addSeries(boys);
}
Now, a commandButton on the same page as the chart triggers the update of one value in the chart at one second intervals:
public void update() {
for (int i = 0; i < 50; i = i+5) {
increment = increment + i;
createCategoryModel();
PushContext pushContext = PushContextFactory.getDefault().getPushContext();
pushContext.push("/counter", "");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(BeanViz.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Problem: it doesn't update the values of the chart as it should, and I am not sure at all this is the correct way to proceed. Any help?
recently implemented in primefaces showcase
http://www.primefaces.org/showcase-labs/push/chart.jsf

Container Visibility control on Change behavior of text field in Wicket 1.4

I've a container which output markup placeholder tag is set to true. I want to display it only if I digit in a certain text field a certain string. For example if I digit "show" in text field, container appears, if I digit "hide" it disappears. I made this code:
container.setOutputPlaceHolderTag(true);
container.setOuputMarkupId(true);
textfield.add(new OnChangeAjaxBehavior() {
#Override
protected void onUpdate(AjaxRequestTarget target) {
form.modelChanged();
if ("SHOW".equals(textfield.getModelObject())) {
container.setVisible(true);
} else {
container.setVisible(false);
}
target.addComponent(container);
}
this code works only if I write SHOW, BUT when I write another string it doesn't disappear. To make it disappear I've to refresh the whole form they are into (and I don't want it).
How can I solve this problem??
some details: all component I'm refering to are in a form, and only if I refresh the form setVisible(false) works. From now only setVisible(true) works, it seems the container stucks on visibility true.
This code works:
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
private String someValue;
private WebMarkupContainer container;
public HomePage(final PageParameters parameters) {
super(parameters);
add(container = container());
add(textfield());
}
private WebMarkupContainer container() {
WebMarkupContainer wmc = new WebMarkupContainer("container") {
#Override
protected void onConfigure() {
super.onConfigure();
setVisible("SHOW".equals(someValue));
}
};
wmc.setOutputMarkupPlaceholderTag(true);
return wmc;
}
private TextField textfield() {
TextField tf = new TextField("textfield", new PropertyModel(HomePage.this, "someValue"));
tf.add(new OnChangeAjaxBehavior() {
#Override
protected void onUpdate(AjaxRequestTarget art) {
//just model update
art.add(container);
}
});
return tf;
}
}
Use
container.setOutputPlaceHolderTag(true);
container.setOuputMarkupId(true);
textfield.add(new OnChangeAjaxBehavior() {
#Override
protected void onUpdate(AjaxRequestTarget target) {
form.modelChanged();
if ("SHOW".equals(((TextField<String>) getComponent()).getModelObject())) { //change this
container.setVisible(true);
} else {
container.setVisible(false);
}
target.addComponent(container);
}
I got this tip from Getting a Wicket text box's value in an AJAX onchange event

Java AWT multiple screens don't show up

I'm working on a task-planning AWT applet for my dev team, and I'm running into a problem.
I'm using a screen system, where the main class has a "current screen" variable that it uses to paint other screens. When the applet starts, it loads the "main screen" which has a "Chatroom" button. When you click the button, it should open the chatroom screen.
My problem is that it displays the main screen just fine, but when you click the button everything just goes blank and the chatroom does not show up at all. What am I doing wrong?
Each screen is a subclass of the Screen class, which is a subclass of Container.
Main Class:
public class TPApplet extends Applet
{
private static final long serialVersionUID = 7611084043153150559L;
private static final int WIDTH = 400;
private static final int HEIGHT = 350;
private static final String TITLE = "TaskPlanner v";
private static final double VERSION = 0.01;
private boolean setup = false;
public Screen currentScreen;
public void init()
{
setLayout(null);
setScreen(new MainScreen(this));
}
public void stop()
{
}
public void setScreen(Screen s)
{
if (currentScreen != null)
{
currentScreen.destroy();
remove(currentScreen);
}
currentScreen = s;
if (currentScreen != null)
{
currentScreen.init();
add(currentScreen);
}
}
public void paint(Graphics g)
{
if (!setup)
{
setSize(WIDTH, HEIGHT);
setName(TITLE + VERSION);
currentScreen.setLocation(0, 0);
currentScreen.setSize(WIDTH, HEIGHT);
setup = true;
}
if (currentScreen != null)
{
currentScreen.paint(g);
}
}
}
Main Menu class:
public class MainScreen extends Screen
{
private static final long serialVersionUID = -993648854350389881L;
private TPApplet applet;
private Button todoButton;
private Button chatButton;
private boolean setup = false;
public MainScreen(TPApplet tpApplet)
{
applet = tpApplet;
}
#Override
public void init()
{
setLayout(null);
todoButton = createButton("To-Do List");
chatButton = createButton("Chatroom");
}
#Override
public void destroy()
{
removeAll();
}
#Override
public void paint(Graphics g)
{
if (!setup)
{
todoButton.setLocation(25, 50);
todoButton.setSize(100, 40);
chatButton.setLocation(135, 50);
chatButton.setSize(100, 40);
setup = true;
}
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() instanceof Button)
{
Button button = (Button) e.getSource();
if (button.getLabel() == chatButton.getLabel())
{
applet.setScreen(new ChatScreen(applet));
}
}
}
}
Chatroom Class:
public class ChatScreen extends Screen
{
private static final long serialVersionUID = -8774060448361093669L;
private TPApplet applet;
private ScrollPane chatWindow;
private TextField textField;
private Button sendButton;
private boolean setup = false;
public ChatScreen(TPApplet tpApplet)
{
applet = tpApplet;
}
#Override
public void init()
{
setLayout(null);
sendButton = createButton("Send");
chatWindow = new ScrollPane();
textField = new TextField();
add(chatWindow);
add(textField);
}
#Override
public void destroy()
{
removeAll();
}
#Override
public void paint(Graphics g)
{
if (!setup)
{
chatWindow.setLocation(20, 20);
chatWindow.setSize(100, 100);
textField.setLocation(150, 150);
textField.setSize(60, 20);
sendButton.setLocation(220, 150);
sendButton.setSize(40, 20);
setup = true;
}
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() instanceof Button)
{
Button button = (Button) e.getSource();
if (button.getLabel() == sendButton.getLabel())
{
String text = textField.getText();
}
}
}
}
Thank you in advance for your help!
I suspect that seen as you've chosen to discard the use of layout managers, when you add a new screen, the screen is being added with a 0x0 size
public void setScreen(Screen s)
{
//...//
if (currentScreen != null)
{
currentScreen.init();
// Look ma, I have no size...
add(currentScreen);
}
}
One of the jobs of a layout manger is to decide how any new components should be laid out.
Try setting the applet's layout manager to something like BorderLayout.
The next problem is that the child screens suffer from the same problem, so even though the screen will be sized (based on the needs of the layout manager), the screens themselves also have no layout manager, so the components you add to them have no size and it will appear that the screen hasn't been updated.
I'd also recommend that you take a look at Andrew's example of CardLayout
You could also check out A Visual Guide to Layout Managers and Using Layout Managers for more details...
You will need to invalidate() the applet in your setScreen method.
The new screen component needs to be laid out again to compute the sizes of its children.
It's a shame this isn't done automatically when adding!
Also, consider doing this using a LayoutManager if possible. Would a CardLayout work for you?

AjaxFormComponentUpdatingBehaviour issue after Form submitting in Wicket

I have such problem with Wickets AjaxFormComponentUpdatingBehaviour. When you set this to some components on the form, and add validation to them, after you press "Submit form" button, and, lets say, you get an error, that your component has not passed validation, after that ajax is behaving different, does not update models.
Here is code example:
TextField someText = new TextField("someTextId");
someText.setRequired(true); //added validation on requireness
CheckBox checkBx = new CheckBox("checkBxId");
TextField changeableTxt = new TextField("changeableTxtId");
changeableTxt.setEnabled(false);
checkBx.add(new AjaxFormComponentUpdatingBehaviour("onclick"){
protected void onUpdate(AjaxRequestTarget target) {
if(compoundModel.isCheckBx()){
changeableTxt.setEnabled(true);
target.addComponent(changeableTxt);
}else{
compoundModel.setChangeableTxt(null);
changeableTxt.setEnabled(false);
target.addComponent(changeableTxt);
}
}
});
Form form = new Form("form", compoundModel);
form.add(someText, checkBx, changeableTxt);
add(form);
So if check the checkBx, input some value to changeableTxt, leave someText empty and press submit button, error will appear, that field someText is required. After that, if we click on checkBx, it will make changeableTxt field disabled, but it will leave before the input value inside, instead of null.
Well let's start with explaining why you might think your code is working:
The AjaxFormComponentUpdatingBehavior will update the model of your CheckBox but only this model. That means that the changeableTxt will even stay empty if you remove the code line compoundModel.setChangeableTxt(null);
So if the Checkbox is supposed to change the value of the changeableTxt TextField it should submit the value it has while clicking it as well. You can achieve this by wrapping a Form around checkBx and changeableTxt and submit this form when click on the CheckBox by using a AjaxFormSubmitBehavior.
public class TestingPanel extends Panel {
public TestingPanel(String id) {
super(id);
final CompoundModel compoundModel = new CompoundModel();
final Form<CompoundModel> form = new Form<CompoundModel>("form",
new CompoundPropertyModel<CompoundModel>(compoundModel)) {
#Override
protected void onValidate() {
System.out.println("validate: "
+ compoundModel.getChangeableTxt());
System.out.println("validate: "
+ getModel().getObject().getChangeableTxt());
super.onValidate();
}
};
form.setOutputMarkupId(true);
add(form);
TextField someText = new TextField("someText");
someText.setRequired(true); // added validation on requireness
final CheckBox checkBx = new CheckBox("checkBx");
final TextField changeableTxt = new TextField("changeableTxt");
changeableTxt.setOutputMarkupId(true);
changeableTxt.setEnabled(false);
Form checkBoxForm = new Form("checkBoxForm");
form.add(checkBoxForm);
AjaxFormSubmitBehavior submitBehavior = new AjaxFormSubmitBehavior(
checkBoxForm, "onclick") {
#Override
protected void onSubmit(AjaxRequestTarget target) {
if (checkBx.getModelObject() == true) {
changeableTxt.setEnabled(true);
target.add(changeableTxt);
} else {
compoundModel.setChangeableTxt(null);
changeableTxt.setEnabled(false);
target.add(changeableTxt);
}
}
#Override
protected void onError(AjaxRequestTarget target) {
}
};
checkBx.add(submitBehavior);
checkBoxForm.add(checkBx, changeableTxt);
AjaxFormComponentUpdatingBehavior updateBehavior = new AjaxFormComponentUpdatingBehavior(
"onclick") {
protected void onUpdate(AjaxRequestTarget target) {
if (compoundModel.isCheckBx()) {
changeableTxt.setEnabled(true);
target.addComponent(changeableTxt);
} else {
// compoundModel.setChangeableTxt("");
changeableTxt.setEnabled(false);
target.add(changeableTxt);
}
}
};
form.add(someText);
FeedbackPanel feedbackPanel = new FeedbackPanel("feedbackPanel");
form.add(feedbackPanel);
AjaxSubmitLink submit = new AjaxSubmitLink("submit", form) {
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
target.add(form);
}
#Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
target.add(form);
}
};
add(submit);
}
class CompoundModel implements Serializable {
private boolean checkBx = false;
private String someText = null;
private String changeableTxt = null;
public boolean isCheckBx() {
return checkBx;
}
public void setCheckBx(boolean checkBx) {
this.checkBx = checkBx;
}
public String getSomeText() {
return someText;
}
public void setSomeText(String someText) {
this.someText = someText;
}
public String getChangeableTxt() {
return changeableTxt;
}
public void setChangeableTxt(String changeableTxt) {
this.changeableTxt = changeableTxt;
}
}
}
with the following html:
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<form wicket:id="form">
<div wicket:id="feedbackPanel" />
<input type="text" wicket:id="someText" /><br />
<form wicket:id="checkBoxForm">
<input type="checkbox" wicket:id="checkBx" /><br />
<input type="text" wicket:id="changeableTxt" /><br />
</form>
</form>
<a wicket:id="submit">submit</a>
</wicket:panel>

Categories

Resources