支持纯色背景 (#4184)
This commit is contained in:
@@ -29,6 +29,7 @@ import javafx.collections.FXCollections;
|
|||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.collections.ObservableMap;
|
import javafx.collections.ObservableMap;
|
||||||
import javafx.collections.ObservableSet;
|
import javafx.collections.ObservableSet;
|
||||||
|
import javafx.scene.paint.Paint;
|
||||||
import org.hildan.fxgson.creators.ObservableListCreator;
|
import org.hildan.fxgson.creators.ObservableListCreator;
|
||||||
import org.hildan.fxgson.creators.ObservableMapCreator;
|
import org.hildan.fxgson.creators.ObservableMapCreator;
|
||||||
import org.hildan.fxgson.creators.ObservableSetCreator;
|
import org.hildan.fxgson.creators.ObservableSetCreator;
|
||||||
@@ -37,6 +38,7 @@ import org.jackhuang.hmcl.Metadata;
|
|||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
|
||||||
import org.jackhuang.hmcl.util.gson.EnumOrdinalDeserializer;
|
import org.jackhuang.hmcl.util.gson.EnumOrdinalDeserializer;
|
||||||
import org.jackhuang.hmcl.util.gson.FileTypeAdapter;
|
import org.jackhuang.hmcl.util.gson.FileTypeAdapter;
|
||||||
|
import org.jackhuang.hmcl.util.gson.PaintAdapter;
|
||||||
import org.jackhuang.hmcl.util.i18n.Locales;
|
import org.jackhuang.hmcl.util.i18n.Locales;
|
||||||
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
|
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
|
||||||
import org.jackhuang.hmcl.util.javafx.ObservableHelper;
|
import org.jackhuang.hmcl.util.javafx.ObservableHelper;
|
||||||
@@ -60,6 +62,7 @@ public final class Config implements Observable {
|
|||||||
.registerTypeAdapterFactory(new JavaFxPropertyTypeAdapterFactory(true, true))
|
.registerTypeAdapterFactory(new JavaFxPropertyTypeAdapterFactory(true, true))
|
||||||
.registerTypeAdapter(EnumBackgroundImage.class, new EnumOrdinalDeserializer<>(EnumBackgroundImage.class)) // backward compatibility for backgroundType
|
.registerTypeAdapter(EnumBackgroundImage.class, new EnumOrdinalDeserializer<>(EnumBackgroundImage.class)) // backward compatibility for backgroundType
|
||||||
.registerTypeAdapter(Proxy.Type.class, new EnumOrdinalDeserializer<>(Proxy.Type.class)) // backward compatibility for hasProxy
|
.registerTypeAdapter(Proxy.Type.class, new EnumOrdinalDeserializer<>(Proxy.Type.class)) // backward compatibility for hasProxy
|
||||||
|
.registerTypeAdapter(Paint.class, new PaintAdapter())
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
|
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
|
||||||
.create();
|
.create();
|
||||||
@@ -87,6 +90,9 @@ public final class Config implements Observable {
|
|||||||
@SerializedName("bgurl")
|
@SerializedName("bgurl")
|
||||||
private StringProperty backgroundImageUrl = new SimpleStringProperty();
|
private StringProperty backgroundImageUrl = new SimpleStringProperty();
|
||||||
|
|
||||||
|
@SerializedName("bgpaint")
|
||||||
|
private ObjectProperty<Paint> backgroundPaint = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
@SerializedName("commonDirType")
|
@SerializedName("commonDirType")
|
||||||
private ObjectProperty<EnumCommonDirectory> commonDirType = new SimpleObjectProperty<>(EnumCommonDirectory.DEFAULT);
|
private ObjectProperty<EnumCommonDirectory> commonDirType = new SimpleObjectProperty<>(EnumCommonDirectory.DEFAULT);
|
||||||
|
|
||||||
@@ -172,7 +178,7 @@ public final class Config implements Observable {
|
|||||||
private BooleanProperty titleTransparent = new SimpleBooleanProperty(false);
|
private BooleanProperty titleTransparent = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
@SerializedName("authlibInjectorServers")
|
@SerializedName("authlibInjectorServers")
|
||||||
private ObservableList<AuthlibInjectorServer> authlibInjectorServers = FXCollections.observableArrayList(server -> new Observable[] { server });
|
private ObservableList<AuthlibInjectorServer> authlibInjectorServers = FXCollections.observableArrayList(server -> new Observable[]{server});
|
||||||
|
|
||||||
@SerializedName("addedLittleSkin")
|
@SerializedName("addedLittleSkin")
|
||||||
private BooleanProperty addedLittleSkin = new SimpleBooleanProperty(false);
|
private BooleanProperty addedLittleSkin = new SimpleBooleanProperty(false);
|
||||||
@@ -274,6 +280,18 @@ public final class Config implements Observable {
|
|||||||
this.backgroundImageUrl.set(backgroundImageUrl);
|
this.backgroundImageUrl.set(backgroundImageUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Paint getBackgroundPaint() {
|
||||||
|
return backgroundPaint.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectProperty<Paint> backgroundPaintProperty() {
|
||||||
|
return backgroundPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundPaint(Paint backgroundPaint) {
|
||||||
|
this.backgroundPaint.set(backgroundPaint);
|
||||||
|
}
|
||||||
|
|
||||||
public EnumCommonDirectory getCommonDirType() {
|
public EnumCommonDirectory getCommonDirType() {
|
||||||
return commonDirType.get();
|
return commonDirType.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,6 @@ public enum EnumBackgroundImage {
|
|||||||
CUSTOM,
|
CUSTOM,
|
||||||
CLASSIC,
|
CLASSIC,
|
||||||
NETWORK,
|
NETWORK,
|
||||||
TRANSLUCENT
|
TRANSLUCENT,
|
||||||
|
PAINT
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.*;
|
import javafx.scene.input.*;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.scene.text.TextFlow;
|
import javafx.scene.text.TextFlow;
|
||||||
@@ -745,6 +746,106 @@ public final class FXUtils {
|
|||||||
property.removeListener(binding);
|
property.removeListener(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class PaintBidirectionalBinding implements InvalidationListener, WeakListener {
|
||||||
|
private final WeakReference<ColorPicker> colorPickerRef;
|
||||||
|
private final WeakReference<Property<Paint>> propertyRef;
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
private boolean updating = false;
|
||||||
|
|
||||||
|
private PaintBidirectionalBinding(ColorPicker colorPicker, Property<Paint> property) {
|
||||||
|
this.colorPickerRef = new WeakReference<>(colorPicker);
|
||||||
|
this.propertyRef = new WeakReference<>(property);
|
||||||
|
this.hashCode = System.identityHashCode(colorPicker) ^ System.identityHashCode(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidated(Observable sourceProperty) {
|
||||||
|
if (!updating) {
|
||||||
|
final ColorPicker colorPicker = colorPickerRef.get();
|
||||||
|
final Property<Paint> property = propertyRef.get();
|
||||||
|
|
||||||
|
if (colorPicker == null || property == null) {
|
||||||
|
if (colorPicker != null) {
|
||||||
|
colorPicker.valueProperty().removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (property != null) {
|
||||||
|
property.removeListener(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updating = true;
|
||||||
|
try {
|
||||||
|
if (property == sourceProperty) {
|
||||||
|
Paint newValue = property.getValue();
|
||||||
|
if (newValue instanceof Color)
|
||||||
|
colorPicker.setValue((Color) newValue);
|
||||||
|
else
|
||||||
|
colorPicker.setValue(null);
|
||||||
|
} else {
|
||||||
|
Paint newValue = colorPicker.getValue();
|
||||||
|
property.setValue(newValue);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
updating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wasGarbageCollected() {
|
||||||
|
return colorPickerRef.get() == null || propertyRef.get() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (!(o instanceof FXUtils.PaintBidirectionalBinding))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var that = (FXUtils.PaintBidirectionalBinding) o;
|
||||||
|
|
||||||
|
final ColorPicker colorPicker = this.colorPickerRef.get();
|
||||||
|
final Property<Paint> property = this.propertyRef.get();
|
||||||
|
|
||||||
|
final ColorPicker thatColorPicker = that.colorPickerRef.get();
|
||||||
|
final Property<?> thatProperty = that.propertyRef.get();
|
||||||
|
|
||||||
|
if (colorPicker == null || property == null || thatColorPicker == null || thatProperty == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return colorPicker == thatColorPicker && property == thatProperty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindPaint(ColorPicker colorPicker, Property<Paint> property) {
|
||||||
|
PaintBidirectionalBinding binding = new PaintBidirectionalBinding(colorPicker, property);
|
||||||
|
|
||||||
|
colorPicker.valueProperty().removeListener(binding);
|
||||||
|
property.removeListener(binding);
|
||||||
|
|
||||||
|
if (property.getValue() instanceof Color)
|
||||||
|
colorPicker.setValue((Color) property.getValue());
|
||||||
|
else
|
||||||
|
colorPicker.setValue(null);
|
||||||
|
|
||||||
|
colorPicker.valueProperty().addListener(binding);
|
||||||
|
property.addListener(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unbindColorPicker(ColorPicker colorPicker, Property<Paint> property) {
|
||||||
|
PaintBidirectionalBinding binding = new PaintBidirectionalBinding(colorPicker, property);
|
||||||
|
colorPicker.valueProperty().removeListener(binding);
|
||||||
|
property.removeListener(binding);
|
||||||
|
}
|
||||||
|
|
||||||
public static void bindAllEnabled(BooleanProperty allEnabled, BooleanProperty... children) {
|
public static void bindAllEnabled(BooleanProperty allEnabled, BooleanProperty... children) {
|
||||||
int itemCount = children.length;
|
int itemCount = children.length;
|
||||||
int childSelectedCount = 0;
|
int childSelectedCount = 0;
|
||||||
|
|||||||
@@ -24,11 +24,13 @@ import javafx.beans.property.*;
|
|||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.ColorPicker;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Toggle;
|
import javafx.scene.control.Toggle;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
@@ -297,4 +299,35 @@ public final class MultiFileItem<T> extends VBox {
|
|||||||
return pane;
|
return pane;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class PaintOption<T> extends Option<T> {
|
||||||
|
private final ColorPicker colorPicker = new ColorPicker();
|
||||||
|
|
||||||
|
public PaintOption(String title, T data) {
|
||||||
|
super(title, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaintOption<T> bindBidirectional(Property<Paint> property) {
|
||||||
|
FXUtils.bindPaint(colorPicker, property);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Node createItem(ToggleGroup group) {
|
||||||
|
BorderPane pane = new BorderPane();
|
||||||
|
pane.setPadding(new Insets(3));
|
||||||
|
FXUtils.setLimitHeight(pane, 30);
|
||||||
|
|
||||||
|
left.setText(title);
|
||||||
|
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
|
||||||
|
left.setToggleGroup(group);
|
||||||
|
left.setUserData(data);
|
||||||
|
pane.setLeft(left);
|
||||||
|
|
||||||
|
colorPicker.disableProperty().bind(left.selectedProperty().not());
|
||||||
|
BorderPane.setAlignment(colorPicker, Pos.CENTER_RIGHT);
|
||||||
|
pane.setRight(colorPicker);
|
||||||
|
return pane;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,10 +61,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -135,6 +132,7 @@ public class DecoratorController {
|
|||||||
config().backgroundImageTypeProperty().addListener(weakListener);
|
config().backgroundImageTypeProperty().addListener(weakListener);
|
||||||
config().backgroundImageProperty().addListener(weakListener);
|
config().backgroundImageProperty().addListener(weakListener);
|
||||||
config().backgroundImageUrlProperty().addListener(weakListener);
|
config().backgroundImageUrlProperty().addListener(weakListener);
|
||||||
|
config().backgroundPaintProperty().addListener(weakListener);
|
||||||
|
|
||||||
// pass key events to current dialog / current page
|
// pass key events to current dialog / current page
|
||||||
decorator.addEventFilter(KeyEvent.ANY, e -> {
|
decorator.addEventFilter(KeyEvent.ANY, e -> {
|
||||||
@@ -224,6 +222,8 @@ public class DecoratorController {
|
|||||||
break;
|
break;
|
||||||
case TRANSLUCENT:
|
case TRANSLUCENT:
|
||||||
return new Background(new BackgroundFill(new Color(1, 1, 1, 0.5), CornerRadii.EMPTY, Insets.EMPTY));
|
return new Background(new BackgroundFill(new Color(1, 1, 1, 0.5), CornerRadii.EMPTY, Insets.EMPTY));
|
||||||
|
case PAINT:
|
||||||
|
return new Background(new BackgroundFill(Objects.requireNonNullElse(config().getBackgroundPaint(), Color.WHITE), CornerRadii.EMPTY, Insets.EMPTY));
|
||||||
}
|
}
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
image = loadDefaultBackgroundImage();
|
image = loadDefaultBackgroundImage();
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ public class PersonalizationPage extends StackPane {
|
|||||||
.bindBidirectional(config().backgroundImageProperty()),
|
.bindBidirectional(config().backgroundImageProperty()),
|
||||||
new MultiFileItem.StringOption<>(i18n("launcher.background.network"), EnumBackgroundImage.NETWORK)
|
new MultiFileItem.StringOption<>(i18n("launcher.background.network"), EnumBackgroundImage.NETWORK)
|
||||||
.setValidators(new URLValidator(true))
|
.setValidators(new URLValidator(true))
|
||||||
.bindBidirectional(config().backgroundImageUrlProperty())
|
.bindBidirectional(config().backgroundImageUrlProperty()),
|
||||||
|
new MultiFileItem.PaintOption<>(i18n("launcher.background.paint"), EnumBackgroundImage.PAINT)
|
||||||
|
.bindBidirectional(config().backgroundPaintProperty())
|
||||||
));
|
));
|
||||||
backgroundItem.selectedDataProperty().bindBidirectional(config().backgroundImageTypeProperty());
|
backgroundItem.selectedDataProperty().bindBidirectional(config().backgroundImageTypeProperty());
|
||||||
backgroundSublist.subtitleProperty().bind(
|
backgroundSublist.subtitleProperty().bind(
|
||||||
|
|||||||
@@ -812,6 +812,7 @@ launcher.background.classic=Classic
|
|||||||
launcher.background.default=Default
|
launcher.background.default=Default
|
||||||
launcher.background.default.tooltip=Or "background.png/.jpg/.gif/.webp" and the images in the "bg" directory
|
launcher.background.default.tooltip=Or "background.png/.jpg/.gif/.webp" and the images in the "bg" directory
|
||||||
launcher.background.network=From URL
|
launcher.background.network=From URL
|
||||||
|
launcher.background.paint=Solid Color
|
||||||
launcher.background.translucent=Translucent
|
launcher.background.translucent=Translucent
|
||||||
launcher.cache_directory=Cache Directory
|
launcher.cache_directory=Cache Directory
|
||||||
launcher.cache_directory.clean=Clear Cache
|
launcher.cache_directory.clean=Clear Cache
|
||||||
|
|||||||
@@ -628,6 +628,7 @@ launcher.background.classic=經典
|
|||||||
launcher.background.default=預設
|
launcher.background.default=預設
|
||||||
launcher.background.default.tooltip=自動尋找啟動器同目錄下的「background.png/.jpg/.gif/.webp」及「bg」目錄內的圖片
|
launcher.background.default.tooltip=自動尋找啟動器同目錄下的「background.png/.jpg/.gif/.webp」及「bg」目錄內的圖片
|
||||||
launcher.background.network=網路
|
launcher.background.network=網路
|
||||||
|
launcher.background.paint=純色
|
||||||
launcher.background.translucent=半透明
|
launcher.background.translucent=半透明
|
||||||
launcher.cache_directory=檔案下載快取目錄
|
launcher.cache_directory=檔案下載快取目錄
|
||||||
launcher.cache_directory.clean=清理
|
launcher.cache_directory.clean=清理
|
||||||
|
|||||||
@@ -638,6 +638,7 @@ launcher.background.classic=经典
|
|||||||
launcher.background.default=默认
|
launcher.background.default=默认
|
||||||
launcher.background.default.tooltip=自动检索启动器同文件夹下的“background.png/.jpg/.gif/.webp”及“bg”文件夹内的图片
|
launcher.background.default.tooltip=自动检索启动器同文件夹下的“background.png/.jpg/.gif/.webp”及“bg”文件夹内的图片
|
||||||
launcher.background.network=网络
|
launcher.background.network=网络
|
||||||
|
launcher.background.paint=纯色
|
||||||
launcher.background.translucent=半透明
|
launcher.background.translucent=半透明
|
||||||
launcher.cache_directory=文件下载缓存文件夹
|
launcher.cache_directory=文件下载缓存文件夹
|
||||||
launcher.cache_directory.clean=清理缓存
|
launcher.cache_directory.clean=清理缓存
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.util.gson;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import javafx.scene.paint.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public final class PaintAdapter extends TypeAdapter<Paint> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, Paint value) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
out.nullValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof Color) {
|
||||||
|
Color color = (Color) value;
|
||||||
|
int red = (int) Math.round(color.getRed() * 255.);
|
||||||
|
int green = (int) Math.round(color.getGreen() * 255.);
|
||||||
|
int blue = (int) Math.round(color.getBlue() * 255.);
|
||||||
|
int opacity = (int) Math.round(color.getOpacity() * 255.);
|
||||||
|
out.value(String.format("#%02x%02x%02x%02x", red, green, blue, opacity));
|
||||||
|
} else if (value instanceof LinearGradient
|
||||||
|
|| value instanceof RadialGradient) {
|
||||||
|
out.value(value.toString());
|
||||||
|
} else {
|
||||||
|
throw new JsonParseException("Unsupported Paint type: " + value.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Paint read(JsonReader in) throws IOException {
|
||||||
|
if (in.peek() == JsonToken.NULL) {
|
||||||
|
in.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String value = in.nextString();
|
||||||
|
return Paint.valueOf(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user