
org.autogui.swing.mapping.GuiReprEmbeddedComponent Maven / Gradle / Ivy
package org.autogui.swing.mapping;
import org.autogui.base.mapping.GuiMappingContext;
import org.autogui.base.mapping.GuiReprValue;
import org.autogui.base.type.GuiUpdatedValue;
import org.autogui.swing.util.SwingDeferredRunner;
import javax.swing.*;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* a GUI component for a property holding a {@link JComponent}
*
* private JComponent comp;
* @GuiIncluded public JComponent getComp() {
* if (comp == null) {
* comp = new JLabel("hello");
* }
* return comp;
* }
*
*
* the class executes obtaining and updating a target value under the event dispatching thread
* via {@link SwingDeferredRunner}.
*
* For the case of updating from GUI,
* an UI event (in the event thread) ->
* executeContextTask
* and it observes that {@link #isTaskRunnerUsedFor(Supplier)} returns false and directly invoke the given task
* ->
* updateFromGui -> update ->
* {@link SwingDeferredRunner#run(SwingDeferredRunner.Task)} with super.update (it directly invoke the task as in the event thread)
* -> the method of the target object is invoked under the event thread.
*/
public class GuiReprEmbeddedComponent extends GuiReprValue {
@Override
public boolean matchValueType(Class> cls) {
return JComponent.class.isAssignableFrom(cls);
}
@Override
public boolean isTaskRunnerUsedFor(Supplier> task) {
return false;
}
@Override
public GuiUpdatedValue getValue(GuiMappingContext context, GuiMappingContext.GuiSourceValue parentSource,
ObjectSpecifier specifier, GuiMappingContext.GuiSourceValue prev) throws Throwable {
Object v = SwingDeferredRunner.run(() -> super.getValue(context, parentSource, specifier, prev));
if (v instanceof GuiUpdatedValue) {
return (GuiUpdatedValue) v;
} else {
return GuiUpdatedValue.of(v);
}
}
@Override
public Object update(GuiMappingContext context, GuiMappingContext.GuiSourceValue parentSource,
Object newValue, ObjectSpecifier specifier) {
try {
return SwingDeferredRunner.run(() -> super.update(context, parentSource, newValue, specifier));
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
}
/**
* @param context the context of the repr.
* @param value the current value
* @return obtains a {@link JComponent} value, or if the value is a deferred future,
* then get the done value or null if it is not completed.
* To support the delayed completion, use {@link #toUpdateValue(GuiMappingContext, Object, Consumer)} instead.
*/
@Override
public JComponent toUpdateValue(GuiMappingContext context, Object value) {
return toUpdateValue(context, value, null);
}
public JComponent toUpdateValue(GuiMappingContext context, Object value, Consumer delayed) {
if (value instanceof SwingDeferredRunner.TaskResultFuture) {
Future