I'm trying to make an EventStream from a DoubleProperty in ReactFX (I've tried both 2.0M5 and 1.4.1 stable). I constantly get this error from IntelliJ:
I've tried using the sample code from the wiki:
Circle streamCircle = new Circle();
EventStream<Double> widthValues = EventStreams.nonNullValuesOf(streamCircle.radiusProperty());
...and I get the same error.
What am I doing wrong?
DoubleProperty, IntegerProperty and similar properties implement ObservableValue<Number>, not ObservableValue<Double>, ObservableValue<Integer>, ect.
You could use asObject for conversion to such a type:
EventStream<Double> widthValues = EventStreams.nonNullValuesOf(streamCircle.radiusProperty().asObject());
But if I correctly understand what nonNullValuesOf is supposed to do, you should replace this by EventStreams.valuesOf, since a DoubleProperty never contains null as value.
Related
I cannot seem to understand the proper way to bind the ColorPicker value property to an ObjectProperty in ScalaFX. This is what I have done so far:
private val colorProp = new ObjectProperty[Color](this, "test", Color.White)
// Create color picker
val cp: ColorPicker = new ColorPicker(Color.White) {
prefWidth = Prop.pickerWidth
}
colorProp <==> cp.value
However, I get this type error here:
[error] (v: javafx.beans.property.Property[scalafx.scene.paint.Color])Unit <and>
[error] (v: scalafx.beans.property.Property[scalafx.scene.paint.Color,scalafx.scene.paint.Color])Unit
[error] cannot be applied to (scalafx.beans.property.ObjectProperty[javafx.scene.paint.Color])
[error] colorProp <==> cp.value
I have been able to make things like StringProperty work correctly, but as soon as I try using the ObjectProperty, this problem arises. Any help would be great!
Well turned out that I needed to use a JavaFX color instead of a ScalaFX color. This still seems odd to me, but it works! Any further explanation would be great though.
private val colorProp = new ObjectProperty[javafx.scene.paint.Color](this, "test", Color.White)
I've been messing around with CM conventions trying to understand how they work but i haven't found a decent article somewhere explaining step-by-step how and why.
However I've found a few code snippets that i've been working with with some success.
In this case, however, i don't understand what is going on.
I'm trying to bind a NumericUpDown Value and Maximum to a corresponding ViewModel property. I was able to do it with the following code:
Value
ConventionManager.AddElementConvention<NumericUpDown>(NumericUpDown.ValueProperty, "Value", "ValueChanged");
Maximum
ConventionManager.AddElementConvention<NumericUpDown>(NumericUpDown.MaximumProperty, "Maximum", "MaximumChanged");
var baseBindProperties = ViewModelBinder.BindProperties;
ViewModelBinder.BindProperties =
(frameWorkElements, viewModels) =>
{
foreach (var frameworkElement in frameWorkElements)
{
var propertyName = frameworkElement.Name + "Max";
var property = viewModels.GetPropertyCaseInsensitive(propertyName);
if (property != null)
{
var convention = ConventionManager.GetElementConvention(typeof(NumericUpDown));
ConventionManager.SetBindingWithoutBindingOverwrite(
viewModels,
propertyName,
property,
frameworkElement,
convention,
convention.GetBindableProperty(frameworkElement));
}
}
return baseBindProperties(frameWorkElements, viewModels);
};
However, an here comes the weird part, i can only make one of them to work. That makes me believe that i'm doing some noob mistake somewhere. It almost seems i can only call AddElementConvention and therefor only the last call is executed.
I would appreciate either a help with this piece of code or a reference to some good documentation that could help me with it.
Best Regards
i found out somewhere that CM only allows one convention per item so that's the reason of this behavior...
However since items like ComboBox allows binding for multiple properties (SelectedItem, ItemSource and so on...) i'm not completed convinced...
I'm trying to have a ComboBox list the contents in sorted order. I've come up with one solution, but it still has some issues.
final ObservableList<String> oal = FXCollections.observableArrayList();
final SimpleListProperty<String> slp = new SimpleListProperty<String>(oal);
final SortedList<String> sl = new SortedList<String>(slp, (string1, string2) -> {
return string1.compareTo(string2);
});
final ComboBox<String> comboBox = new ComboBox<String>();
comboBox.setItems(sl);
I can add values to OAL or SLP.
oal.addAll("cccc", "aaaa", "bbbb");
slp.addAll("ffff", "dddd", "eeee");
But if I try to add values to SL, it fails.
sl.addAll("iiii", "hhhh", "gggg");
Exception in thread "main" java.lang.UnsupportedOperationException
So of course any attempts to add values to comboBox also fail. Does anybody know a way to fix this, or is there a totally different approach to sorting the contents of the ComboBox?
I appreciate any help here.
I'm using Java 8u5.
Can't you just add items to the underlying list instead of the sorted list?
final ObservableList<String> comboBoxItems = FXCollections.observableArrayList();
final ComboBox<String> comboBox = new ComboBox<String>();
comboBox.setItems(new SortedList<String>(comboBoxItems, Collator.getInstance()));
And then just always add items to comboBoxItems.
I'm adding this as an answer as I don't have enough stackoverflow reputation to comment.
Be aware that there is currently (Java 8u92 and probably before) a bug JDK-8087838 that causes extra unwanted Combobox OnAction events to fire when adding items to an editable combobox when a SortedList is used instead of an ObservableList. This bug makes it difficult to properly code for the combobox events, so I suggest not using a SortedList until the bug is fixed. See also this stackoverflow question.
Hey folks, i ve got this issue implementing the Factory method.
Following is the snippet of the the main chart class which calls ChartFactory's method to attain the proper object. I Type Cast chartobject so as to be able to call the Show method;i m apprehensive about that as well.
container = new VBox();
container.percentWidth = 100;
container.percentHeight = 100;
super.media.addChild(container);
chartObject = new ChartBase();
chartObject = ChartFactory.CreateChartObject(chartType);
IChart(chartObject).Show(o);
container.addChild(chartObject);
legend = new Legend();
legend.dataProvider = IChart(chartObject);
container.addChild(legend);
Following is the snippet of ChartFactory's method:
public static function CreateChartObject(subType:String):ChartBase
{
switch(subType)
{
case ChartFactory.AREA_CHART:
return new AreaCharts();
break;
case ChartFactory.COLUMN_CHART:
return new ColumnCharts();
break;
case ChartFactory.PIE_CHART:
return new PieCharts();
break;
default:
throw new ArgumentError(subType + ": Chart type is not recognized.");
}
}
And following is Show method of one of the several Charts type classes: AreaCharts, PieCharts etc. All of which implements IChart Interface.
public function Show(o:ObjectProxy):void
{
var grids:GridLines;
var stroke:SolidColorStroke;
var horizontalAxis:CategoryAxis;
var verticalAxis:LinearAxis;
var horizontalAxisRenderer:AxisRenderer;
var verticalAxisRenderer:AxisRenderer;
grids = new GridLines();
if(WidgetStylesheet.instance.LineChart_ShowGrid)
grids.setStyle("gridDirection", "both");
else
grids.setStyle("gridDirection", "");
stroke = new SolidColorStroke(WidgetStylesheet.instance.LineChart_GridLineColor, WidgetStylesheet.instance.LineChart_GridLineThickness);
grids.setStyle("horizontalStroke", stroke);
grids.setStyle("verticalStroke", stroke);
horizontalAxis = new CategoryAxis();
horizontalAxis.categoryField = o.LargeUrl.Chart.xField;
horizontalAxis.title = o.LargeUrl.Chart.xAxisTitle.toString();
verticalAxis = new LinearAxis();
verticalAxis.title = o.LargeUrl.Chart.yAxisTitle.toString();
horizontalAxisRenderer = new AxisRenderer();
horizontalAxisRenderer.axis = horizontalAxis;
horizontalAxisRenderer.setStyle("tickLength", 0);
horizontalAxisRenderer.setStyle("showLine", false);
horizontalAxisRenderer.setStyle("showLabels", true);
horizontalAxisRenderer.setStyle("fontSize", WidgetStylesheet.instance.ComputeChartAxisFontSize(o.HeadlineFontSize));
verticalAxisRenderer = new AxisRenderer();
verticalAxisRenderer.axis = verticalAxis;
verticalAxisRenderer.setStyle("tickLength", 0);
verticalAxisRenderer.setStyle("showLine", false);
verticalAxisRenderer.setStyle("fontSize", WidgetStylesheet.instance.ComputeChartAxisFontSize(o.HeadlineFontSize));
this.series = this.m_createSeries(o);
this.horizontalAxis = horizontalAxis;
this.horizontalAxisRenderers = [horizontalAxisRenderer];
this.verticalAxis = verticalAxis;
this.verticalAxisRenderers = [verticalAxisRenderer];
this.backgroundElements = [grids];
}
I'm afraid that there is more than one issue with this code. Unfortunately it is not obvious why your chart doesn't show up so you may apply some of advices below and use debugger to analyse the issue.
There is no point in creating ChartBase instance if you are going to change value of chartObject reference in the next line
chartObject = new ChartBase();
chartObject = ChartFactory.CreateChartObject(chartType);
If the API of your charts is IChart your factory should return IChart instead of casting.
public static function CreateChartObject(subType:String):IChart
Make sure that you are returning instances of the correct class from the factory. i.e. that you are returning your subclass of standard PieChart. Generally it's not the best idea to extend the class keeping the same name and just changing the package.
Once again, if you are not sure if the program enters some function use the Flash Builder debugger to check this. I can't imagine development without debugger.
Some thoughts:
you call the Show method, pass it some object but nowhere in that method is any child added to a displayObject. What exactly is Show supposed to do?
a lot of member variables in your classes start with UpperCase. The compiler can easily confuse those with class names, in case your classes are named the same. Bad practice to start variable and function names with capitals.
If your casting an instance to another class or interface fails, you will get a runtime error. Those are easy to debug using the Flash Builder debugger.
Hey ppl..
i found out wat wnt wrng..as olwys it wa "I".
I ve a habit of mkin mock ups secluded from the main project n dn integrate it. So in mock up i hd used an xml whch hd a format slightly diff dn d one being used in the main project.
N i hd a conditional chk to return from the prog if certain value doesnt match, n due to faulty xml i did'nt.
So this more a lexical error than a logical one.
Sorry n Thanx evryone for responding.
I have a UI component that, for various reasons, I have to construct programatically. The component is a table of radio buttons grouped by column.
Right now, I'm constructing the column groups like so:
private function createGroupsForItemList(items: XMLList): void {
for each (var item: XML in items) {
var rbGroup: RadioButtonGroup = new RadioButtonGroup();
groups[item.#level.toString()] = rbGroup;
}
}
I'm trying to associate the RadioButton instances with the column groups like so:
private function createValueControl(item: XML): UIComponent {
var control: RadioButton = new RadioButton();
control.label = "";
control.group = groups[item.#level.toString()];
control.addEventListener(Event.SELECT, updateSelection);
return control;
}
I can see in the debugger that the control has an association to the group:
control.group == groups[item.#level.toString()]
However, I can see equally that the group does not know anything about the control:
group.radioButtons.length == 0
I imagine that this is because the setter for group in RadioButton is a dumb setter; all it does is copy to the variable, which doesn't do the magic that groupName does. However, I can't seem to find the value I should use to set the RadioButton.groupName property correctly.
So, in short, I'm stumped on how to get these bits to talk to each other. How do I do this?
-- EDIT --
It turns out that I can have the groups created and associated simply by setting the groupName property, but I can't get at the group to set up a selection listener; the group is NULL immediately after the setting process, which means that the second line below throws the Flex equivalent of an NPE:
control.groupName = groupNameForLevel(item);
control.group.addEventListener(Event.SELECT, updateSelection);
First instinct is that this issue has to do with invalidateDisplayList and when and how that is called. Of course, since issues related to that function are behind a number of Flex's quirks, I may just be scapegoating.
This is not the answer to your question per se, but it seems like it might actually work as an alternate solution.
RadioButtonGroups will initialize based on a IFlexDisplayObject. This means that you can do something like:
var c:HBox = new HBox();
var rbg:RadioButtonGroup = new RadioButtonGroup( c );
// do stuff with rbg.
c.addChild( new RadioButton() );
The problem is that it may not be the most practical answer, but it has the decided benefit of being a workable solution.
Setting groupName should work.
All I can suggest is to step through the group() getter of the RadioButton component and see where exactly it is failing. Are you programmatically creating the group too? If that's the case, maybe it isn't initialized fully yet.