tomasmikula / reactfx Goto Github PK
View Code? Open in Web Editor NEWReactive event streams, observable values and more for JavaFX.
License: BSD 2-Clause "Simplified" License
Reactive event streams, observable values and more for JavaFX.
License: BSD 2-Clause "Simplified" License
Both variables are used during the configuration phase of the build, so they'll cause an error:
No such property: sonatypeUsername for class: org.gradle.api.publication.maven.internal.ant.DefaultGroovyMavenDeployer
The evaluation of both properties needs to be delayed until the execution phase. Right now the onlyIf
condition has no effect since the configuration phase can't be skipped.
I think the easiest way to delay property evaluation is to use a closure for those properties, but I'm not positive it's the correct way. You'll have to test it to make sure it doesn't break uploading archives.
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: {sonatypeUsername}, password: {sonatypePassword})
}
snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots') {
authentication(userName: {sonatypeUsername}, password: {sonatypePassword})
}
Hi,
I have come across the following exception:
Caused by: java.lang.NoSuchMethodError: org.reactfx.EventStreamBase.subscribe(Ljava/lang/Object;)Lorg/reactfx/Subscription;
at org.reactfx.BiEventSource.subscribe(BiEventSource.java:5)
here is my code:
BiEventSource<Metadata,Metadata> itemUpdateES = new BiEventSource();
public Subscription subscribeToUpdates(BiConsumer<Metadata, Metadata> bc) {
return itemUpdateES.subscribe(bc);
}
another exception that seems to have the same cause is:
Caused by: java.lang.NoSuchMethodError: org.reactfx.MappedBiStream.subscribeToBi(Lorg/reactfx/BiEventStream;Ljava/util/function/BiConsumer;)Lorg/reactfx/Subscription;
at org.reactfx.MappedBiStream.subscribeToInputs(MappedStream.java:46)
at org.reactfx.LazilyBoundStream.firstSubscriber(LazilyBoundStream.java:17)
at org.reactfx.EventStreamBase.subscribe(EventStreamBase.java:35)
at org.reactfx.EventStreams$StreamBoundValueImpl.(EventStreams.java:689)
at org.reactfx.EventStreams.toObservableValue(EventStreams.java:544)
at org.reactfx.EventStream.toObservableValue(EventStream.java:72)
thrown when used toObservableValue() on an event stream that is a result of :
itemUpdateES.map((ov,nv)->nv).toObservableValue(value)
Any thoughts?
It looks like a problem with BiEventStreamBase implementation. I know i can always use BiTouple, but id rather not.
Or am doing something wrong? Not sure why it is looking for subscribe(Object). Should the parameter not be a BiConsumer?
edit: the problem turns out to be outdated .jar in the download section. Using the sources.jar directly does not cause any problems. The method toObservable() was apparently renamed to toBinding().
JavaFX has a few different WeakXXX
wrappers for listeners. I currently need a similar thing for a Consumer
that I can subscribe with, but that will automatically be removed if it's owners get garbage collected. LimitedInvocationSubscriber
offers similar functionality, but with a different "reason" to revoke the subscription.
Coming from FXMisc/RichTextFX#189, provide an additional ticks
EventStream that will restart its timer whenever some other EventStream (impulse) emits an event.
Hi,
I am using a Val bound to the text property of a TextField. I filter out strings which cannot be converted to LocalDateTime with a predicate in the string formatter
Val.filter(this.textField.textProperty(), this.format::isValidDateTime)
and them map the Val to LocalDateTime. In my program I start observing null values in the the Val when the isValidDateTime returns false. From the documentation of Val.filter, I would expect that values that do not satisfy the predicate are dropped and not replaced with null. However, I am not sure because I did not find a definition for an empty Val. Here is the code with the javadoc from
/**
* Returns a new {@linkplain Val} that holds the same value
* as this {@linkplain Val} when the value satisfies the predicate
* and is empty when this {@linkplain Val} is empty or its value
* does not satisfy the given predicate.
*/
default Val<T> filter(Predicate<? super T> p) {
return filter(this, p);
}
static <T> Val<T> filter(
ObservableValue<T> src,
Predicate<? super T> p) {
return map(src, t -> p.test(t) ? t : null);
}
It is obvious that values failing the predicate are substituted by null. Is that how it is supposed to work?
For a normal EventSource, it cannot be recursively pushed events into. This way will lead to a illegal state exception because of the recursive operation.
So what is the graceful way for the recursive operations?
Thanks
hi tomas, i would like to suggest adding Api to create snippets. the idea is that those snippets would know if they are bing selected, hovered over, etc. and a text area would know these snippets' locations, their style, etc. and probably have a property to report on which, if any, snippet is being clicked inside of or selected.
i implemented a very sketchy version, which half-works for the purpose of my project, but i thought such element type would be cool to have i richtextfx.
thanks !
Maher
I wanna do some work to make ReactFX running on android.
Any advice?
Regards
I've read all the documentation I can find and have experimented quite a bit, but I just can't figure out what's going on. I posted my question on StackOverflow and I'm posting here with the hope of getting my issue some attention. If my problem can be solved I think it would make a good use example to go in the wiki.
Hi,
I'm thinking about an extension to Val
/Var
, or rather to the provided factory methods. The idea is to provide a Supplier
that gets called the first time the value is actually read.
Val<String> lazyVal = Val.lazy(this::calculateComplicatedName); // not called yet
// do some stuff
System.out.println(lazyVal.getValue()); // calculateComplicatedName called now
System.out.println(lazyVal.getValue()); // result was cached, not called again
This is obviously useful for cases where a default value is expensive to calculate. But I was actually thinking about loading remote values on demand. Instead of loading everythink immediately, this would provide a clean API for lazy loading. For remote calls, this would have to be done async.
Val<String> lazyVal = Val.lazyAsync(String placeholder, this::loadNameFromServer); // not called yet
// do some stuff
System.out.println(lazyVal.getValue()); // returns placeholder, loadNameFromServer started in separate thread
// some time later
System.out.println(lazyVal.getValue()); // loading was finished, returns result now
While it's easy enough for a Val
, because it cannot change, I'm not so sure how or even if it's useful for a Var
. But I would be grateful for any input on this. If there is interest, I would be happy to code it myself and start a pull request.
MenuItem menuItem = ...;
EventStream<ActionEvent> stream = EventStreams.eventsOf(menuItem, ActionEvent.ACTION);
Doesn't work because MenuItem doesn't extend Node.
This is just a minor inconvenience because I can simply adjust that method for MenuItem.
Hi,
in a current project I use a lot "min" and "max" methods (like the methods from the java stream api).
So in this project I wrote a small event stream extension with this methods but maybe there is the possibility to add these methods in a upcoming release/milestone/snapshot ;)
default EventStream<T> min(Comparator<? super T> comparator) {
return accumulate(BinaryOperator.minBy(comparator));
}
default EventStream<T> max(Comparator<? super T> comparator) {
return accumulate(BinaryOperator.maxBy(comparator));
}
I would like to know opinions on usefulness of the error reporting mechanism. I increasingly feel we could do just as well (or better) without it.
STATUS QUO: Currently, when an event stream encounters an error (exception), instead of letting the exception propagate up the call stack, it is caught and propagated through the network of event streams until it is handled (or printed to stderr by default). The consequence is that even when exceptions are being thrown, the program continues normally, likely with incorrect behavior, while exceptions are just being logged.
I increasingly feel that exceptions caused by bugs in the code should just be propagated up the call stack; it is unlikely they can be handled in any meaningful way anyway.
Note that in situations where failure is a valid outcome (such as IO or async tasks), it has always been recommended to materialize the error in the event type, i.e. use EventStream<Try<T>>
instead of EventStream<T>
.
There will be many backward incompatible changes in 2.0 already, so this seems like a good point to deal with the error reporting mechanism, too.
Does anyone have any opinions on this matter?
Hello,
i use an EventStream which emit values on each tick of a "timer" stream:
SimpleBooleanProperty property = new SimpleBooleanProperty(this, "test", true);
EventStream<?> timerStream = EventStreams.ticks(ofMillis(10));
EventStreams.valuesOf(property).emitOnEach(timerStream).subscribe(System.err::println);
this cause a memory leak in my application, the FxTimer seems to be kept by the Toolkit. This is the output of the eclipse memory analyser.
-----------------------------------------------------------------------------------------------------------------------------------------
com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$48 @ 0x76eb0b328 Native Stack
'- arg$1 com.sun.javafx.tk.quantum.QuantumToolkit @ 0x76eb103a8
'- animationRunnable com.sun.scenario.animation.AbstractMasterTimer$MainLoop @ 0x76ece3b10
'- this$0 com.sun.javafx.tk.quantum.MasterTimer @ 0x76eb7f068
'- receivers com.sun.scenario.animation.shared.PulseReceiver[2] @ 0x76eb7f0b8
'- [0] javafx.animation.Animation$1 @ 0x76eb7f0d0
'- this$0 javafx.animation.Timeline @ 0x76eb7f0e0
'- clipCore com.sun.scenario.animation.shared.TimelineClipCore @ 0x76eb7f420
'- keyFrames javafx.animation.KeyFrame[1] @ 0x76eb7f450
'- [0] javafx.animation.KeyFrame @ 0x76eb7f468
'- onFinished org.reactfx.util.FxTimer$$Lambda$213 @ 0x76eb7f498
'- arg$1 org.reactfx.util.FxTimer @ 0x76eb7f4b0
'- action org.reactfx.EventStreams$14$$Lambda$184 @ 0x76eb7f4d0
'- arg$1 org.reactfx.EventStreams$14 @ 0x76eb7f4e0
'- observers org.reactfx.util.ListHelper$SingleElemHelper @ 0x76eb7f500
'- elem org.reactfx.SuspendableBase$$Lambda$212 @ 0x76eb7f510
'- arg$1 org.reactfx.PausableEventStream @ 0x76eb7f520
'- observers org.reactfx.util.ListHelper$SingleElemHelper @ 0x76eb7f550
'- elem org.reactfx.SuspendWhenStream$$Lambda$211 @ 0x76eb7f560
'- arg$1 org.reactfx.SuspendWhenStream @ 0x76eb7f570
'- observers org.reactfx.util.ListHelper$SingleElemHelper @ 0x76eb7f598
'- elem org.reactfx.EmitOnEachStream$$Lambda$209 @ 0x76eb7f5a8
'- arg$1 org.reactfx.EmitOnEachStream @ 0x76eb7f5b8
'- observers org.reactfx.util.ListHelper$SingleElemHelper @ 0x76eb7f5e0
'- elem org.reactfx.MappedStream$$Lambda$196 @ 0x76eb7f5f0
'- arg$1 org.reactfx.MappedStream @ 0x76eb7f600
-----------------------------------------------------------------------------------------------------------------------------------------
am i missing something ?
The links to the javadoc are broken in the different pages of the wiki.
How do I make an EventStream active only when an ObjectProperty's bean matches a specific value? (In this case, the ObjectProperty holds an Enum.) As of right now, a stream is always active unless suspended when an Observable is true. What's the best way to reverse this (an EventStream is active only when an ObjectProperty holds a specific value)?
enum State {
UNFINISHED,
CONNECTED,
ROOT
}
SimpleObjectProperty<State> state = new SimpleObjectProperty(State.UNFINISHED)
I want to create 3 EventStreams, each of which are only active when 'state' holds a specific value:
How do I pause and resume using Timer ?
I followed your approach in http://tomasmikula.github.io/blog/2014/06/04/timers-in-javafx-and-reactfx.html
In javafx, I can do
Timeline autosaveTimer = new Timeline(
new KeyFrame(Duration.seconds(60 * MINUTES),
ae -> masterClock.setSaveSim(DEFAULT)));
At some point I have to call autosaveTimer().pause()
to pause
and later call autosaveTimer().play()
to resume
In ReactFX, I do the following
Timer autosaveTimer = FxTimer.runLater(
java.time.Duration.ofMinutes(60 * MINUTES),
() -> masterClock.setSaveSim(DEFAULT)));
I notice there is a stop() and restart() for Timer
but I don't want to stop autosaveTimer completely and restart from the beginning of MINUTES. I want to resume from whatever MINUTES has elapsed.
Is there a pause() and resume() that I can call ?
I've noticed some strange behavior with list change events when using EventStreams
or LiveList
.
LiveList
does not support update events.ListChangeListener.Change::next
contract is not followed.import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import java.util.function.Consumer;
import javafx.beans.Observable;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.reactfx.EventStreams;
import org.reactfx.collection.ListChange;
import org.reactfx.collection.LiveList;
@RunWith(MockitoJUnitRunner.class)
public class LiveListUpdateTest {
private static class Data {
private final Property<String> string = new SimpleObjectProperty<>();
public String getString() {
return string.getValue();
}
public Property<String> stringProperty() {
return string;
}
}
@Captor
ArgumentCaptor<ListChangeListener.Change<? extends Data>> originalChange;
@Captor
ArgumentCaptor<ListChangeListener.Change<? extends Data>> eventStreamChange;
@Captor
ArgumentCaptor<ListChange<? extends Data>> liveListChange;
@Captor
ArgumentCaptor<ListChangeListener.Change<? extends String>> mappedChange;
@Mock
ListChangeListener<? super Data> originalListener;
@Mock
Consumer<ListChangeListener.Change<? extends Data>> eventStreamListener;
@Mock
Consumer<ListChange<? extends Data>> liveListListener;
@Mock
ListChangeListener<? super String> mappedListener;
Data data;
ObservableList<Data> updateableList;
ObservableList<String> mappedList;
@Before
public void before() {
data = new Data();
updateableList = FXCollections.observableArrayList(d -> new Observable[] { d.stringProperty() });
updateableList.add(data);
mappedList = LiveList.map(updateableList, Data::getString);
}
@Test
public void initialChangeState() {
updateableList.addListener(originalListener);
EventStreams.changesOf(updateableList).subscribe(eventStreamListener);
data.stringProperty().setValue("foo");
verify(originalListener).onChanged(originalChange.capture());
assertTrue(originalChange.getValue().next());
verify(eventStreamListener).accept(eventStreamChange.capture());
assertTrue(eventStreamChange.getValue().next()); // Fails
}
@Test
public void liveListShouldNotInvalidateInitialChangeState() {
updateableList.addListener(originalListener);
LiveList.changesOf(updateableList).subscribe(liveListListener);
data.stringProperty().setValue("foo");
verify(originalListener).onChanged(originalChange.capture());
assertTrue(originalChange.getValue().next()); // Fails
verify(liveListListener).accept(liveListChange.capture());
assertEquals(1, liveListChange.getValue().getModificationCount());
}
@Test
public void mappedUpdates() {
updateableList.addListener(originalListener);
mappedList.addListener(mappedListener);
data.stringProperty().setValue("foo");
assertThat(mappedList, contains("foo"));
verify(originalListener).onChanged(originalChange.capture());
assertTrue(originalChange.getValue().next()); // Fails
assertTrue(originalChange.getValue().wasUpdated());
assertFalse(originalChange.getValue().next());
verify(mappedListener).onChanged(mappedChange.capture());
assertTrue(originalChange.getValue().next()); // Fails
assertTrue(mappedChange.getValue().wasUpdated()); // Fails
assertFalse(originalChange.getValue().next());
}
}
Adding a way to combine instances of Val
, like EasyBind.combine(...)
would fully cover functionallity of EasyBind.
May be except EasyBind.select(...)
, but I dont use it :)
I'm confused why the code below isn't working.
I have a list of episodes, each with a watched
property. This list can get large, so I'm trying to avoid binding to each item, but only binding to the activate one, as indicated by episodeProp
. I create a Val
that indicates the state of the current episode.
Next, I create a Val
that will reflect the percentage of episodes watched, using the aforementioned Val
which indicates the state of the current episode. However, despite a change listener being present on this derived Val
, it doesn't update, even though it does get invalidated (and as far as I know, if something gets invalidated that has a change listener attached to it, then it must get revalidated again...)
It seems to me that properties are not getting revalidated, resulting in further invalidations to be lost.
Solutions are to add episodeProp
as an additional dependency for watchedPercentage
, or to add a ChangeListener
to episodeWatched
.
The output of the program is:
Recalculating...
WatchedPercentage = 0
1, expecting invalidation as episodeProp is changed:
>> EpisodeWatched Invalidated
>> WatchedPercentage Invalidated
Recalculating...
Watched Percentage = 25
2, expecting invalidation as episodeProp->watched is changed:
3, expecting invalidation as episodeProp is changed:
4
The code:
public static void main(String[] args) throws InterruptedException {
List<Ep> eps = new ArrayList<>();
eps.addAll(Arrays.asList(new Ep(), new Ep(), new Ep(), new Ep()));
ObjectProperty<Ep> episodeProp = new SimpleObjectProperty<>();
Val<Boolean> episodeWatched = Val.wrap(episodeProp).flatMap(ep -> ep.watched);
Val<Integer> watchedPercentage = Val.create(() -> {
System.out.println("Recalculating...");
int watched = 0;
int total = 0;
for(Ep ep : eps) {
total++;
if(ep.watched.get()) {
watched++;
}
}
return 100 * watched / total;
}, episodeWatched);
episodeWatched.addListener((obs) -> System.out.println(">> EpisodeWatched Invalidated"));
watchedPercentage.addListener((obs) -> System.out.println(">> WatchedPercentage Invalidated"));
System.out.println("WatchedPercentage = " + watchedPercentage.getValue());
watchedPercentage.addListener((obs, old, current) -> System.out.println("Watched Percentage = " + current));
eps.get(0).watched.set(true);
System.out.println("1, expecting invalidation as episodeProp is changed:");
episodeProp.set(eps.get(0));
System.out.println("2, expecting invalidation as episodeProp->watched is changed:");
episodeProp.get().watched.set(false);
System.out.println("3, expecting invalidation as episodeProp is changed:");
episodeProp.set(eps.get(1));
System.out.println("4");
Thread.sleep(2000);
}
public static class Ep {
BooleanProperty watched = new SimpleBooleanProperty();
}
I have a Var used internally, and want to expose its value (read only) as a Val.
It seems that this should be pretty trivial, but there is no method on Var to accomplish this directly:
Var<Integer> var = Var.newSimpleVar(0);
Val<Integer> val = var.asVal();
// or:
Val<Integer> val = var.readOnly();
So for now I'm using:
Val<Integer> val = var.orElseConst(0);
Am I missing something obvious?
I'm not sure if a global toggle is the right approach, but starting in Java 8u40 some of the restrictions that require nodes be created on the application thread are being loosened. See here:
https://javafx-jira.kenai.com/browse/RT-17716
I want to take advantage of the above to build my entire UI on the JavaFX-Launcher thread. However, ReactFX has a handful of thread checks that bubble an IllegalStateException
when I try this. For example:
Caused by: java.lang.IllegalStateException: Not on FX application thread
at org.reactfx.EventStream.reduceCloseSuccessions(EventStream.java:125) ~[reactfx-1.0.0.jar:na]
at org.reactfx.EventStream.reduceCloseSuccessions(EventStream.java:98) ~[reactfx-1.0.0.jar:na]
Is it possible for ReactFX to accommodate building components on a non-application thread?
When combining an EventStream
that has a dependency on an EventStream
that emits InputEvents
, the combined EventStream
will not emit a value (and thus anything that depends upon it will not work) until that that InputEvent
is fired:
EventStream<Boolean> controlPressed = EventStreams
.eventsOf(scene, KeyEvent.KEY_PRESSED)
.filter(key -> key.getCode().is(KeyCode.CONTROL))
.map(key -> key.isControlDown());
EventStream<?> other = // code...
EventStream<Tuple2<Boolean, ?>> combination = EventStreams
.combine(controlPressed, other);
// this will not run immediately upon program start; it will once user presses a key once.
combination.subscribe(tuple2 -> System.out.println("Tuple2: " + tuple2.toString());
The only workaround is to merge such an EventStream
with an EventSource
:
EventSource<Boolean> initialValue = new EventSource();
EventStream<Boolean> controlKeys = EventStreams
.eventsOf(scene, KeyEvent.KEY_PRESSED)
.filter(key -> key.getCode().is(KeyCode.CONTROL))
.map(key -> key.isControlDown());
EventStream<Boolean> controlPressed = EventStreams.merge(initialValue, controlKeys);
EventStream<Tuple2<Boolean, ?>> combination = EventStreams
.combine(controlPressed, other);
initialValue.push(false);
The following code could be a better workaround:
EventStream<Boolean> controlPressed = EventStreams
.eventsOf(scene, KeyEvent.KEY_PRESSED)
.filter(key -> key.getCode().is(KeyCode.CONTROL))
.map(key -> key.isControlDown())
// since a value won't be emitted until user presses control key,
// force the stream to emit an initial value when subscribed to
.prepend(false);
Although there's this approach to making images linkable in a wiki, this approach is faster.
If one wants to be able to edit this image, please download Freeplane and copy/paste the save file's text (below) into an empty file and save as "ReactFX - Ecosystem.mm"
Save File Text
<map version="freeplane 1.3.0">
<!--To view this file, download free mind mapping software Freeplane from http://freeplane.sourceforge.net -->
<node TEXT="ReactFX" ID="ID_1723255651" CREATED="1283093380553" MODIFIED="1445967632760"><hook NAME="MapStyle" zoom="1.1">
<map_styles>
<stylenode LOCALIZED_TEXT="styles.root_node">
<stylenode LOCALIZED_TEXT="styles.predefined" POSITION="right">
<stylenode LOCALIZED_TEXT="default" MAX_WIDTH="600" COLOR="#000000" STYLE="as_parent">
<font NAME="SansSerif" SIZE="10" BOLD="false" ITALIC="false"/>
</stylenode>
<stylenode LOCALIZED_TEXT="defaultstyle.details"/>
<stylenode LOCALIZED_TEXT="defaultstyle.note"/>
<stylenode LOCALIZED_TEXT="defaultstyle.floating">
<edge STYLE="hide_edge"/>
<cloud COLOR="#f0f0f0" SHAPE="ROUND_RECT"/>
</stylenode>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.user-defined" POSITION="right">
<stylenode LOCALIZED_TEXT="styles.topic" COLOR="#18898b" STYLE="fork">
<font NAME="Liberation Sans" SIZE="10" BOLD="true"/>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.subtopic" COLOR="#cc3300" STYLE="fork">
<font NAME="Liberation Sans" SIZE="10" BOLD="true"/>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.subsubtopic" COLOR="#669900">
<font NAME="Liberation Sans" SIZE="10" BOLD="true"/>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.important">
<icon BUILTIN="yes"/>
</stylenode>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.AutomaticLayout" POSITION="right">
<stylenode LOCALIZED_TEXT="AutomaticLayout.level.root" COLOR="#000000">
<font SIZE="18"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,1" COLOR="#0033ff">
<font SIZE="16"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,2" COLOR="#00b439">
<font SIZE="14"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,3" COLOR="#990000">
<font SIZE="12"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,4" COLOR="#111111">
<font SIZE="10"/>
</stylenode>
</stylenode>
</stylenode>
</map_styles>
</hook>
<hook NAME="AutomaticEdgeColor" COUNTER="9"/>
<node TEXT="Ecosystem" POSITION="left" ID="ID_956871798" CREATED="1447990190342" MODIFIED="1447994714816">
<edge STYLE="hide_edge" COLOR="#007c00"/>
<node TEXT="Creation" LOCALIZED_STYLE_REF="AutomaticLayout.level,1" ID="ID_1656444366" CREATED="1447990199025" MODIFIED="1447994687649" HGAP="508" VSHIFT="-358">
<edge STYLE="hide_edge"/>
<cloud COLOR="#f0f0f0" SHAPE="ARC"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_801039055" MIDDLE_LABEL="(Optional)" STARTINCLINATION="-50;73;" ENDINCLINATION="-38;-30;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_199892113" STARTINCLINATION="-211;273;" ENDINCLINATION="-41;-153;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_751662814" MIDDLE_LABEL="(optional)" STARTINCLINATION="-73;14;" ENDINCLINATION="-72;-111;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<node TEXT="EventSource" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1695262203" CREATED="1447990248438" MODIFIED="1447994862314" HGAP="51" VSHIFT="-140">
<hook NAME="FreeNode"/>
<node TEXT="new EventSource()" ID="ID_1507429926" CREATED="1447990253127" MODIFIED="1447991016339">
<edge STYLE="bezier"/>
</node>
</node>
<node TEXT="Val / Var" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_244595518" CREATED="1447990235081" MODIFIED="1447994862315" HGAP="-74" VSHIFT="-75">
<hook NAME="FreeNode"/>
<node TEXT="changes" ID="ID_592004289" CREATED="1447990237876" MODIFIED="1447994394772">
<edge STYLE="bezier"/>
</node>
<node TEXT="values" ID="ID_1427903886" CREATED="1447990239944" MODIFIED="1447994397199">
<edge STYLE="bezier"/>
</node>
<node TEXT="invalidations" ID="ID_940442032" CREATED="1447990241909" MODIFIED="1447994399626">
<edge STYLE="bezier"/>
</node>
</node>
<node TEXT="EventStreams" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1475374352" CREATED="1447990210006" MODIFIED="1447994862312" HGAP="134" VSHIFT="-29">
<hook NAME="FreeNode"/>
<node TEXT="eventsOf" ID="ID_290199428" CREATED="1447990212497" MODIFIED="1447991016336">
<edge STYLE="bezier"/>
</node>
<node TEXT="valuesOf" ID="ID_1539311778" CREATED="1447990217376" MODIFIED="1447991016337">
<edge STYLE="bezier"/>
</node>
<node TEXT="nonNullValuesOf" ID="ID_1784220558" CREATED="1447990225554" MODIFIED="1447991016337">
<edge STYLE="bezier"/>
</node>
<node TEXT="invalidationsOf" ID="ID_1366474000" CREATED="1447990231641" MODIFIED="1447991016338">
<edge STYLE="bezier"/>
</node>
<node TEXT="changesOf" ID="ID_1739854836" CREATED="1447990221639" MODIFIED="1447991016338">
<edge STYLE="bezier"/>
</node>
<node TEXT="sizesOf" ID="ID_1424920048" CREATED="1447990223224" MODIFIED="1447991016334">
<edge STYLE="bezier"/>
</node>
</node>
</node>
<node TEXT="Composition" LOCALIZED_STYLE_REF="AutomaticLayout.level,1" ID="ID_801039055" CREATED="1447990270103" MODIFIED="1447994714815" HGAP="734" VSHIFT="-135">
<cloud COLOR="#f0f0f0" SHAPE="ARC"/>
<hook NAME="FreeNode"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#ff0000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_199892113" STARTINCLINATION="7;49;" ENDINCLINATION="51;-86;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#ff0000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_751662814" MIDDLE_LABEL="(optional)" STARTINCLINATION="-2;31;" ENDINCLINATION="48;-1;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<node TEXT="EventStream<Either<?, ?>>" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_389179999" CREATED="1447993597596" MODIFIED="1447994848271" HGAP="776" VSHIFT="-402">
<hook NAME="FreeNode"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#ff0000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_97132340" MIDDLE_LABEL="unify" STARTINCLINATION="-72;57;" ENDINCLINATION="39;-62;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
</node>
<node TEXT="TaskStream" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1395358890" CREATED="1447991713823" MODIFIED="1447994848271" HGAP="648" VSHIFT="-352">
<hook NAME="FreeNode"/>
</node>
<node TEXT="CompletionStageStream" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_938073560" CREATED="1447991651724" MODIFIED="1447994848271" HGAP="454" VSHIFT="-339">
<hook NAME="FreeNode"/>
</node>
<node TEXT="Tuple2<EventStream, EventStream>" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1826488728" CREATED="1447991555326" MODIFIED="1447994848272" HGAP="242" VSHIFT="-211">
<hook NAME="FreeNode"/>
</node>
<node TEXT="AwaitingEventStream" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1461645592" CREATED="1447991866452" MODIFIED="1447994848272" HGAP="138" VSHIFT="-73">
<hook NAME="FreeNode"/>
</node>
<node TEXT="EventStream" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_97132340" CREATED="1447990278506" MODIFIED="1447994848271" HGAP="701" VSHIFT="-31">
<hook NAME="FreeNode"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1941293977" MIDDLE_LABEL="accumulative
forgetful
pausable
reducible
successionEnds
suppressible" STARTINCLINATION="-151;82;" ENDINCLINATION="14;-48;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1826488728" MIDDLE_LABEL="fork" STARTINCLINATION="-81;-5;" ENDINCLINATION="89;36;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_938073560" MIDDLE_LABEL="mapToCompetionStage
supplyCompletionStage" STARTINCLINATION="-209;-104;" ENDINCLINATION="16;27;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1395358890" MIDDLE_LABEL="mapToTask
supplyTask" STARTINCLINATION="-17;-94;" ENDINCLINATION="16;69;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1461645592" MIDDLE_LABEL="reduceSuccessions
thenAccumulateFor
thenIgnoreFor
thenReduceFor
thenRetainLatestFor" STARTINCLINATION="-291;0;" ENDINCLINATION="205;-19;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1606981411" MIDDLE_LABEL="suspenderOf" STARTINCLINATION="-12;111;" ENDINCLINATION="100;-100;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_310260200" MIDDLE_LABEL="toBinding" STARTINCLINATION="-145;105;" ENDINCLINATION="86;-69;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_389179999" MIDDLE_LABEL="or
splitBy" STARTINCLINATION="50;-11;" ENDINCLINATION="5;17;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<node TEXT="Basic" ID="ID_255991212" CREATED="1447992678941" MODIFIED="1447993678446" HGAP="80">
<edge STYLE="bezier"/>
<node TEXT="cast" ID="ID_444008011" CREATED="1447990804730" MODIFIED="1447991199117">
<edge STYLE="bezier"/>
</node>
<node TEXT="conditionOn" ID="ID_1747385380" CREATED="1447990285492" MODIFIED="1447991199116">
<edge STYLE="bezier"/>
<node TEXT="conditionOnShowing" ID="ID_961460209" CREATED="1447991480209" MODIFIED="1447991482354"/>
</node>
<node TEXT="distinct" ID="ID_1001587261" CREATED="1447990814972" MODIFIED="1447991199118">
<edge STYLE="bezier"/>
</node>
<node TEXT="emitOn" ID="ID_1519741257" CREATED="1447991501415" MODIFIED="1447991502478">
<node TEXT="emitOnEach" ID="ID_570761946" CREATED="1447991502996" MODIFIED="1447991504619"/>
<node TEXT="emitBothOnEach" ID="ID_204982288" CREATED="1447991497592" MODIFIED="1447991501072"/>
</node>
<node TEXT="filter" ID="ID_391121211" CREATED="1447990288199" MODIFIED="1447991199117">
<edge STYLE="bezier"/>
</node>
<node TEXT="filterMap" ID="ID_545431987" CREATED="1447990289562" MODIFIED="1447991199117">
<edge STYLE="bezier"/>
</node>
<node TEXT="flatMap" ID="ID_69332464" CREATED="1447990294752" MODIFIED="1447991199118">
<edge STYLE="bezier"/>
</node>
<node TEXT="hook" ID="ID_141218508" CREATED="1447990292547" MODIFIED="1447991199117">
<edge STYLE="bezier"/>
</node>
<node TEXT="latestN" ID="ID_862581645" CREATED="1447991636516" MODIFIED="1447991638964"/>
<node TEXT="map" ID="ID_1857243115" CREATED="1447990291483" MODIFIED="1447991199117">
<edge STYLE="bezier"/>
</node>
<node TEXT="repeatOn" ID="ID_1232314083" CREATED="1447992006105" MODIFIED="1447992008500"/>
<node TEXT="retainLatestBetween" ID="ID_649044072" CREATED="1447992009422" MODIFIED="1447992012516"/>
<node TEXT="retainLatestUntilLater" ID="ID_1865821695" CREATED="1447992013365" MODIFIED="1447992017210"/>
<node TEXT="retainLatestWhen" ID="ID_577934226" CREATED="1447992022621" MODIFIED="1447992031489"/>
<node TEXT="queueBetween" ID="ID_360780057" CREATED="1447991807360" MODIFIED="1447991809482"/>
<node TEXT="queueUntilLater" ID="ID_685890339" CREATED="1447991809789" MODIFIED="1447991812319"/>
<node TEXT="supply" ID="ID_1271104031" CREATED="1447992071343" MODIFIED="1447992072874"/>
<node TEXT="threadBridge" ID="ID_275566541" CREATED="1447992270680" MODIFIED="1447992277083">
<node TEXT="threadBridgeFromFX" ID="ID_740406186" CREATED="1447992277433" MODIFIED="1447992282080"/>
<node TEXT="threadBridgeToFX" ID="ID_1981360670" CREATED="1447992282600" MODIFIED="1447992286351"/>
</node>
</node>
<node TEXT="suspendable-related" ID="ID_469007239" CREATED="1447992762045" MODIFIED="1447993155954" HGAP="56">
<edge STYLE="bezier"/>
<node TEXT="accumulate" ID="ID_45848307" CREATED="1447990751132" MODIFIED="1447991199117">
<edge STYLE="bezier"/>
<node TEXT="accumulateBetween" ID="ID_60854696" CREATED="1447991454312" MODIFIED="1447991457266"/>
<node TEXT="accumulateUntilLater" ID="ID_1416487198" CREATED="1447991458095" MODIFIED="1447991464044"/>
<node TEXT="accumulateWhen" ID="ID_108256930" CREATED="1447991467391" MODIFIED="1447991469371"/>
</node>
<node TEXT="pauseWhen" ID="ID_205893718" CREATED="1447991804564" MODIFIED="1447991806312"/>
<node TEXT="supressWhen" ID="ID_653403835" CREATED="1447992111911" MODIFIED="1447992116307"/>
<node TEXT="reduceBetween" ID="ID_1301074690" CREATED="1447991820454" MODIFIED="1447991823158"/>
<node TEXT="reduceUntilLater" ID="ID_1153022761" CREATED="1447991965622" MODIFIED="1447991968414"/>
<node TEXT="reduceWhen" ID="ID_1446326163" CREATED="1447991968730" MODIFIED="1447991970796"/>
</node>
<node TEXT="onRecurse..." ID="ID_1236939545" CREATED="1447993020831" MODIFIED="1447993158555" HGAP="68">
<edge STYLE="bezier"/>
<node TEXT="onRecurseAccumulate" ID="ID_1043643710" CREATED="1447991760162" MODIFIED="1447991763665"/>
<node TEXT="onRecurseQueue" ID="ID_1994327287" CREATED="1447991764060" MODIFIED="1447991767429"/>
<node TEXT="onRecurseReduce" ID="ID_960529983" CREATED="1447991767747" MODIFIED="1447991770635"/>
<node TEXT="onRecurseRetainLatest" ID="ID_242352220" CREATED="1447991770970" MODIFIED="1447991774982"/>
</node>
</node>
<node TEXT="SuspendableEventStream" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1941293977" CREATED="1447990768440" MODIFIED="1447994848272" HGAP="189" VSHIFT="157">
<hook NAME="FreeNode"/>
</node>
<node TEXT="Binding" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_310260200" CREATED="1447992295918" MODIFIED="1447994848272" HGAP="448" VSHIFT="326">
<hook NAME="FreeNode"/>
</node>
<node TEXT="SuspenderStream" LOCALIZED_STYLE_REF="styles.subtopic" ID="ID_1606981411" CREATED="1447992134049" MODIFIED="1447994848272" HGAP="584" VSHIFT="363">
<hook NAME="FreeNode"/>
</node>
</node>
<node TEXT="Error Handling" LOCALIZED_STYLE_REF="AutomaticLayout.level,1" ID="ID_751662814" CREATED="1447994090391" MODIFIED="1447994631569" HGAP="398" VSHIFT="-26">
<hook NAME="FreeNode"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#29b501" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_199892113" STARTINCLINATION="10;21;" ENDINCLINATION="-116;0;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
</node>
<node TEXT="Subscribe" LOCALIZED_STYLE_REF="AutomaticLayout.level,1" ID="ID_199892113" CREATED="1447990309385" MODIFIED="1447994609292" HGAP="618" VSHIFT="79">
<cloud COLOR="#f0f0f0" SHAPE="ARC"/>
<hook NAME="FreeNode"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#1b02dd" WIDTH="2" TRANSPARENCY="80" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1803011927" STARTINCLINATION="-1;60;" ENDINCLINATION="-18;-22;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<node TEXT="subscribe" ID="ID_1530590359" CREATED="1447990312253" MODIFIED="1447991184385">
<edge STYLE="bezier"/>
</node>
<node TEXT="subscribeFor" ID="ID_1057172675" CREATED="1447990317442" MODIFIED="1447991184386">
<edge STYLE="bezier"/>
</node>
<node TEXT="subscribeForOne" ID="ID_413670360" CREATED="1447990320236" MODIFIED="1447991184386">
<edge STYLE="bezier"/>
</node>
<node TEXT="feedTo" ID="ID_600048489" CREATED="1447990322593" MODIFIED="1447991184386">
<edge STYLE="bezier"/>
</node>
<node TEXT="pin" ID="ID_920179664" CREATED="1447990324192" MODIFIED="1447991184386">
<edge STYLE="bezier"/>
</node>
</node>
<node TEXT="Unsubscribe" LOCALIZED_STYLE_REF="AutomaticLayout.level,1" ID="ID_1803011927" CREATED="1447994197404" MODIFIED="1447994635865" HGAP="586" VSHIFT="176"/>
</node>
</node>
</map>
So is there a way to lets say extend from a BorderPane?
For example create a custom element containing a label and a image and textfield etc...
Then add this custom element to a GridPane (or whatever)
As far as i see my class has to be a View or Fragment but those i can't add to a Pane because their children have to be a Node.
Am I right that for now i would have to write in plain Javafx to get such a custom element?
Val<T>
extends javafx.beans.value.ObservableValue
. However, "javafx-8.0.jar" is using another version of javafx.beans.value.ObservableValue
. So, There is a conflict happens whenever we use both jars in the same project.
Like in the MonadicObservableValue<T>
from EasyBind extending ObservableObjectValue makes Val compatible with some methods of javafx.beans.binding.Bindings
.
Now default monitor is Throwable::printStackTrace
. The alternative one could be
hi Tomas , i implemented a basic command line functionality using a text field in my project. it thought it might be handy to make a codeFiled for use in command lines where you highlight the keywords of a command. one could use the code area to do this, but a code field makes more sense. i am not sure how much more work it is to make this, so it's just a suggestion!
best,
Maher
It's a bit unclear what's relation between EasyBind and ReactFX. Now I'm using both of them in my project, and only recently I've discovered that ReactFX contains Val/Var in addition to EventStream. Is ReactFX aiming to replace EasyBind?
hi Tomas, does reactFX support or enable detecting mouse shake, and press-and-shake events on FX nodes ? I haven't made myself well aquanted with the library as of yet, but wanted to check if this is doable. if so, where should I start-- how can one go about describing such an event.
Hi,
I encountered an issue while using UndoFX, which makes use of ReactFX.
I created an EventStream
of Change
instances, thanks to EventStreams.changesOf
method, that I gave to UndoFX. However, the library is unable to process it correctly because Change
does not override equals
.
I managed to overcome this limitation by using the map
method to turn the Stream <Change>
into a Stream <ComparableChange>
(where ComparableChange
is a new class I created).
It would be far easier if Change
redefined directly equals
and hashCode
. What I propose is to consider two Change
instances equal if both their old values and new values are equal.
If you agree I can submit a PR to fix the problem.
Hello,
I have a scene graph-like data structure that heavily relies on observable properties to keep the components mutually updated. I would like to use listeners to prevent/veto invalid changes of properties. Using a Change(Performed)Listener to change back values is not satisfactory for two reasons:
Is there any way to improve Val and Var in the ReactFX library in a way that also allows for vetoable listeners? I understand that this would not work in interaction with FX properties as they do not support VetoListeners. But in my application the data-stucture is separate from the JavaFX Views so I would like to use the ReactFX properties as "standalone".
I have written my own little property library that has an additional listener that is listening to events before changes are performed (ChangeProposedListener). The problem is my library is non-lazy, will create memory leaks left and right and is over all not nearly as awesome and powerful as the ReactFX library (It was created in 2 hours....).
In addition to that I would also require both a vetoable LiveSet and LiveMap as they are used in the model as well.
I feel like this is too much to ask for. A the same time I believe many other people could use vetoability as well. Just look at the horrible abomination of a VetoableListDecorator that can be found in the JavaFX library.
cheers
Dirk
In GroovyFX, they have the @FXBindable annotation that turns this:
@FXBindable
String myString = "hello"
into this:
private SimpleStringProperty myString = new SimpleStringProperty("hello")
public void setMyString(String value) { myString.setValue(value) }
public String getMyString() { myString.getValue() }
public SimpleStringProperty myStringProperty() { myString }
Could something be done for Val and Var? Something like:
@ReactableVal
Double someDouble;
@ReactableVar
Integer someInteger = 4;
into
private Val<Double> someDouble;
public double getSomeDouble() { return someDouble.getValue); }
public Val<Double> someDoubleProperty() { return someDouble; }
private Var<Integer> someInteger =Var.newSimpleVar(4);
public int getSomeInteger() { return someInteger.getValue(); }
public void setSomeInteger(int value) { someInteger.setValue(value); }
public Var<Integer> someIntegerProperty() { return someInteger; }
or even
@AsFXProperty
private Var<Double> someDouble = Var.newSimpleVar(4.5);
that generates the setter/getter/property method
public int getSomeDouble() { return someDouble.getValue(); }
public void setSomeDouble(int value) { someDouble.setValue(value); }
public Var<Integer> someDoubleProperty() { return someDouble; }
The use of examples, the crisp explanations, zero bloat, zero confusion, everything about it. Bravo!
It would be nice to see a DistinctMappedList<R>
that allows you to take a source ObservableList<T>
, and map each T
item to R
and produce an ObservableList<R>
that only holds distinct instances.
ObservableList<String> values =
FXCollections.observableArrayList("Alpha","Beta","Gamma","Delta","Epsilon");
DistinctMappedList<Integer> distinctLengths = new DistinctMappedList<>(values,v -> v.length());
distinctLengths
would then only contain elements 5, 4, and 7 until more elements are added to values
. A use case this would have been helpful is an Excel-like table filter control I contributed to ControlsFX.
I thought about adding this to the RxJavaFX project. But I think ReactFX would be a better home for something like this. RxJavaFX is not seeking to improve JavaFX but rather simply enable interoperability between RxJava and JavaFX.
Hi there, this is just to document a bug that affects this project in the hope it saves someone some work (and not have to deal with the Oracle bug tracker - damn that thing is annoying). Feel free to close if not useful.
Trying to compile the project I get the attached exception, which I think is triggered by the linked bug. HTH.
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8062253
(if link just loads the search page use http://webcache.googleusercontent.com/search?q=cache:Q2wOgDJBmZEJ:bugs.java.com/bugdatabase/view_bug.do%3Fbug_id%3D8062253+&cd=1&hl=de&ct=clnk&gl=de)
Code at b369264
JDK 1.8.0_31-b13 on Linux x86.
:reactfx:compileJava
An exception has occurred in the compiler (1.8.0_31). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.NullPointerException
at com.sun.tools.javac.code.Types.isConvertible(Types.java:290)
at com.sun.tools.javac.comp.Check.assertConvertible(Check.java:922)
at com.sun.tools.javac.comp.Check.checkMethod(Check.java:876)
at com.sun.tools.javac.comp.Attr.checkMethod(Attr.java:3838)
at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3615)
at com.sun.tools.javac.comp.Attr.checkMethodIdInternal(Attr.java:3522)
at com.sun.tools.javac.comp.Attr.checkMethodId(Attr.java:3501)
at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3488)
at com.sun.tools.javac.comp.Attr.visitIdent(Attr.java:3237)
at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:2011)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1843)
at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.visitReturn(Attr.java:1704)
at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1384)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:692)
at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1142)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1035)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4342)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4252)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4181)
at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4156)
at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:42)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:35)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:97)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:50)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:36)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:34)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:25)
at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:158)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:138)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:235)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:222)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
at org.gradle.launcher.Main.doAction(Main.java:33)
at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
Coming from FXMisc/RichTextFX#189, provide additional ticks
EventStream that emits its values at the start of its interval rather than the end of it.
I wanted to add more documentation to EventStream
that explains a few things:
EventStream
object: creation, subscribe, unsubscribeSubscription
and how and why to use it to prevent memory leaksEventStream
objectWhen I first looked at this library, the Readme file helped show the usefulness of EventStream
objects in general. Since EventStream
, as opposed to Val
/Var
or LiveList
, was demonstrated in the Readme file, I looked at that first. However, I didn't immediately know where to go from there, much less how to use the code in my program. My guess is that others who wish to know more about how to use this library would follow a similar path, hence why I think the documentation should be added to EventStream
.
I've used the simulated recursive binding idea you once suggested.
VirtualizedScrollPane vsPane = ...;
ScrollPane pane = new ScrollPane();
Val.wrap(pane.vvalueProperty()).values().feedTo(vsPane.estimatedScrollYProperty());
vsPane.estimatedScrollYProperty().values().feedTo(pane.vvalueProperty());
98% of the time, it works fine. There is one situation in my code, however, where the underlying ScrollPane will change it's vvalue
to 1.0 (I have no idea why this only occurs in one specific case but never any time else). Additionally, this incorrect value, although fed to the VirtualizedScrollPane
's property, does not actually update vsPane's scrollY value (I also have no idea why that doesn't occur).
So, I propose adding a custom ScrollPane to this library that uses Var instead of DoubleProperty for its properties. To limit the scope to this specific need (where others can add more features to it later), it wouldn't account for touch-based scrolling.
I am currently using Version 2.0M5 because of the withDefaultEvent for multiple streams.
However I cannot handle exceptions with this version since the mentioned methods are gone and the new subscriber interface is not available.
I think I am missing on something but the current https://github.com/TomasMikula/ReactFX/wiki/Error-Handling wiki page doesn't give me much feedback :(
It seems I've found a nasty bug in 2.0-M5. When setValue(newVal)
is called on SimpleVar
, it updates the field value
on SimpleVar
, then calls invalidate()
from its super class ValBase
. This in turn notifies all Observers
using its own field value
. But the later only gets updated on getValue()
, which was never called.
Maybe I'm missing something here. I don't get that AccuMap
thing (yet). I'll try to come up with a test case later.
Hey guys, I have found a problem in using reactive programming with JavaFX. The TableView TableColumn setCellValueFactory does not like being mapped to an EventStream binding. I noticed I can get an Observable in RxJava to work sometimes, but the moment any threads, schedulers, RxJava to ReactFX conversions, or Platform.runLater() calls are introduced chaos ensues. There is no way to effectively bring the subscription to the JavaFX thread without more complications. In many of these scenarios, the TableView keeps calling the cellValueFactory infinitely and re-emitting the values each time, but the values never make it to the table. Other times, no emissions make it at all.
I've spammed SO with a few questions on the odd reactive behaviors I've been finding with TableView. TableColumn setCellValueFactory. Is there an easy solution for this?
http://stackoverflow.com/questions/30931384/rxjava-javafx-property
Such useful method was present in the Guardian
interface :)
Hi Mikula,
There is a compiler warning in eclipse at util/Lists.java because of jdt.
a type cast added.
Is this OK?
diff --git a/reactfx/src/main/java/org/reactfx/util/Lists.java b/reactfx/src/main/java/org/reactfx/util/Lists.java
index 2140a23..5761204 100644
--- a/reactfx/src/main/java/org/reactfx/util/Lists.java
+++ b/reactfx/src/main/java/org/reactfx/util/Lists.java
@@ -299,7 +299,7 @@ class ListConcatenation<E> extends AbstractList<E> {
static <E> List<E> create(List<List<? extends E>> lists) {
return lists.stream()
.filter(l -> !l.isEmpty())
- .map(l -> {
+ .<FingerTree>map(l -> {
@SuppressWarnings("unchecked") // cast safe because l is unmodifiable
List<E> lst = (List<E>) l;
return lst instanceof ListConcatenation
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.