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
Related
I am trying to add itmes in my checkComboBox but i don't Know why I am failing to do so. Here is what I am trying to do in this:
`// initialinzing FXML in my controller`
#FXML
CheckComboBox<String> checkComboBox;
// create the data to show in the CheckComboBox
final ObservableList<String> strings = FXCollections.observableArrayList();
for (int i = 0; i <= 10; i++) {
strings.add("Item " + i);
}
// Create the CheckComboBox with the data
checkComboBox = new CheckComboBox<String>(strings);
// and listen to the relevant events (e.g. when the selected indices or
// selected items change).
checkComboBox.getCheckModel().getSelectedItems().addListener(new ListChangeListener<String>() {
public void onChanged(ListChangeListener.Change<? extends String> c) {
System.out.println(checkComboBox.getCheckModel().getSelectedItems());
}
});
}
This Code is Working fine
My fxml code
<CheckComboBox fx:id="addFeaturesCheckComboBox" prefHeight="25.0" prefWidth="192.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
My Controller Code:
//to initialize my checkComboBox
#FXML
CheckComboBox<String> addFeaturesCheckComboBox;
public void initialize() throws SQLException{
ObservableList<String> strings = FXCollections.observableArrayList();
for (int i = 0; i <= 10; i++) {
strings.add("Item " + i);
}
addFeaturesCheckComboBox.getItems().addAll(strings);
//listen to the relevant events (e.g. when the selected indices or
// selected items change).
addFeaturesCheckComboBox.getCheckModel().getSelectedItems().addListener(new ListChangeListener<String>() {
public void onChanged(ListChangeListener.Change<? extends String> c) {
selectedFeatures = addFeaturesCheckComboBox.getCheckModel().getSelectedItems();
}
});
}
I am using 2 different classes: one holding a main JFrame with an edit JButton and one holding an edit JFrame that is called when the button is pressed.
First i select a row from a jtable for edit. After i press Edit button and a Jframe opens. If i press repeatedly the button, the same jframe are openning. So i want, after the first press of the button -> Jframe are openning and if i press again button I do not want to open the same frame again.
Here is a link with app image: https://ibb.co/gYfR9a
Here is my code for the Edit button:
JButton btnEdit = new JButton("Edit");
btnEdit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < table.getRowCount(); i++) {
Boolean chkDel = Boolean.valueOf(table.getValueAt(i, 0).toString());
if (chkDel) {
String id = table.getValueAt(i, 1).toString();
String num = table.getValueAt(i, 2).toString();
String pre = table.getValueAt(i, 3).toString();
String name = table.getValueAt(i, 4).toString();
String email = table.getValueAt(i, 5).toString();
EditFrame f = new EditFrame(Integer.valueOf(id), num, pre, name, email);
f.initFrame(Integer.valueOf(id), num, pre, name, email);
}
}
}
});
btnEdit.setBounds(150, 250, 90, 23);
getContentPane().add(btnEdit);`
And here is the code for the Edit Frame:
public class EditFrame extends JFrame {
private JPanel contentPane;
private JTextField idField;
private JTextField numField;
private JTextField preField;
private JTextField nameField;
private JTextField emailField;
private final JButton btnEdit = new JButton("Edit");
/**
* Launch the application.
*/
public void initFrame(int id, String num, String pre, String name, String email) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
EditFrame eframe = new EditFrame(id, num, pre, name, email);
eframe.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
In your actionPerformed method of your button you should memorize if it was already clicked by using a boolean. You can then do something like if(!wasClickedAlready) { ... }. However the boolean needs to be kept in the correct scope (one above the method). For example as member variable of your ActionListener or in the wrapping class, or something like this. Else the state of the boolean can not be memorized between method-calls.
For example see this snippet:
btnEdit.addActionListener(new ActionListener() {
private boolean wasClicked = false;
#Override
public void actionPerformed(ActionEvent e) {
if (wasClicked) {
// Do nothing if clicked already
return;
} else {
// The button was clicked for the first time
wasClicked = true;
}
for (int i = 0; i < table.getRowCount(); i++) {
// Your stuff
...
}
}
});
If your question refers to not opening a frame for the same table row again, then you need to memorize the rows you have already clicked, for example by using a table of boolean like boolean[] or a Map mapping the row-index to a boolean like HashMap<Integer, Boolean>. However the scheme remains the same. If that is the case, just tell me in the comments and I will show you another snippet.
Edit: You commented that you maximally one frame should be shown for each row, not for the whole table. As stated above you can apply the same scheme than before:
btnEdit.addActionListener(new ActionListener() {
private boolean[] wasClickedTable = new boolean[table.getRowCount()];
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < table.getRowCount(); i++) {
Boolean chkDel = Boolean.valueOf(table.getValueAt(i, 0).toString());
// A row should be processed
if (chkDel) {
// Lookup if row was already clicked before
if(wasClickedTable[i]) {
// It was, skip the row and do not process it
continue;
}
// The row was not clicked before
// However it is now, set it
wasClickedTable[i] = true;
// Further process the row
// Your stuff
...
}
}
}
});
I'm not sure if I understood correctly. So you have a button that opens a JFrame, but you don't want the JFrame to be opened every time the button is clicked? What is the expected behavior?
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);
When I create a table from an array, I fill ithe first column with the values present in the array, with the second column being ckeckBoxes with the values of the index of the array. I would need to retrieve the name of the selected checkBox. Below is my code, could anyone help me please?
Thanks for your help!
public class AddDoodlePart3 extends Composite {
MainView main = new MainView();
FlexTable table= new FlexTable();
VerticalPanel ab = new VerticalPanel();
HorizontalPanel hor = new HorizontalPanel();
InlineLabel lb = new InlineLabel("tette");
CheckBox ck ;
TextBox orario = new TextBox();
Button btn = new Button("Inserisci");
int culo;
public AddDoodlePart3(String det, ArrayList<String> listDate){
initWidget(this.ab);
this.ab.add(lb);
System.out.println(det+listDate.size());
table.setText(0, 0, " ");
table.setText(0, 1, "Opzione");
table.setText(0, 2, " ");
System.out.println("1");
for(int i=0;i<listDate.size();i++){
System.out.println(i);
this.ck = new CheckBox(""+i);
table.setWidget(i, 0, ck);
table.setText(i, 1, listDate.get(i));
ck.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
boolean checked = ((CheckBox) event.getSource()).getValue();
Window.alert("It is " + (checked ? "" : "not ") + "checked "+ culo);
}
});
}
this.ab.add(table);
this.hor.add(orario);
this.hor.add(btn);
this.ab.add(hor);
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
// System.out.println(culo);
}
});
}
}
You should use a DataGrid widget for these purposes. See GWT Showcase for an example. Click on a Source Code link to see how to implement this DataGrid.
You can set a SelectionModel on a DataGrid - in your case you need a MultiSelectionModel. Then, getting the list of selected items is as easy as:
selectionModel.getSelectedSet();
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>