Merge pull request #1604 from pklite/pls-work

Player Indicators: fixes
This commit is contained in:
ST0NEWALL
2019-09-13 09:11:52 -04:00
committed by GitHub
6 changed files with 181 additions and 177 deletions

View File

@@ -1283,9 +1283,8 @@ public class ConfigPanel extends PluginPanel
Class<?extends Enum> enumType = cid.getItem().enumClass(); Class<?extends Enum> enumType = cid.getItem().enumClass();
EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(),
cid.getItem().keyName(), EnumSet.class) != null ? configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), EnumSet.class);
cid.getItem().keyName(), EnumSet.class) : EnumSet.noneOf(enumType); if (enumSet == null)
if (enumSet == null || enumSet.contains(null))
{ {
enumSet = EnumSet.noneOf(enumType); enumSet = EnumSet.noneOf(enumType);
} }

View File

@@ -35,6 +35,8 @@ import net.runelite.client.config.Stub;
@ConfigGroup("playerindicators") @ConfigGroup("playerindicators")
public interface PlayerIndicatorsConfig extends Config public interface PlayerIndicatorsConfig extends Config
{ {
EnumSet<PlayerIndicationLocation> defaultPlayerIndicatorMode = EnumSet.complementOf(EnumSet.of(PlayerIndicationLocation.HULL));
@ConfigItem( @ConfigItem(
position = 0, position = 0,
keyName = "drawOwnName", keyName = "drawOwnName",
@@ -69,7 +71,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> selfIndicatorModes() default EnumSet<PlayerIndicationLocation> selfIndicatorModes()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@ConfigItem( @ConfigItem(
@@ -107,7 +109,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> friendIndicatorMode() default EnumSet<PlayerIndicationLocation> friendIndicatorMode()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@ConfigItem( @ConfigItem(
@@ -145,7 +147,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> clanIndicatorModes() default EnumSet<PlayerIndicationLocation> clanIndicatorModes()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@ConfigItem( @ConfigItem(
@@ -195,7 +197,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> teamIndicatorModes() default EnumSet<PlayerIndicationLocation> teamIndicatorModes()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@ConfigItem( @ConfigItem(
@@ -233,7 +235,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> targetsIndicatorModes() default EnumSet<PlayerIndicationLocation> targetsIndicatorModes()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@ConfigItem( @ConfigItem(
@@ -367,7 +369,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> otherIndicatorModes() default EnumSet<PlayerIndicationLocation> otherIndicatorModes()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@@ -484,7 +486,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> callerHighlightOptions() default EnumSet<PlayerIndicationLocation> callerHighlightOptions()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }
@ConfigItem( @ConfigItem(
@@ -536,7 +538,7 @@ public interface PlayerIndicatorsConfig extends Config
) )
default EnumSet<PlayerIndicationLocation> callerTargetHighlightOptions() default EnumSet<PlayerIndicationLocation> callerTargetHighlightOptions()
{ {
return EnumSet.allOf(PlayerIndicationLocation.class); return defaultPlayerIndicatorMode;
} }

View File

@@ -28,10 +28,10 @@ package net.runelite.client.plugins.playerindicators;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -42,6 +42,7 @@ import net.runelite.api.Point;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.WorldType; import net.runelite.api.WorldType;
import net.runelite.api.kit.KitType; import net.runelite.api.kit.KitType;
import net.runelite.client.game.ClanManager;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.OverlayPriority;
@@ -65,6 +66,8 @@ public class PlayerIndicatorsOverlay extends Overlay
private PlayerIndicatorsService playerIndicatorsService; private PlayerIndicatorsService playerIndicatorsService;
@Inject @Inject
private Client client; private Client client;
@Inject
private ClanManager clanManager;
@Inject @Inject
public PlayerIndicatorsOverlay(PlayerIndicatorsPlugin plugin, PlayerIndicatorsService playerIndicatorsService) public PlayerIndicatorsOverlay(PlayerIndicatorsPlugin plugin, PlayerIndicatorsService playerIndicatorsService)
@@ -114,98 +117,105 @@ public class PlayerIndicatorsOverlay extends Overlay
} }
final String builtString = nameSb.toString(); final String builtString = nameSb.toString();
final int x = graphics.getFontMetrics().stringWidth(builtString);
final int y = graphics.getFontMetrics().getHeight();
if (skulls && actor.getSkullIcon() != null) if (plugin.isHighlightClan() && actor.isClanMember() && plugin.isShowClanRanks() && relation == PlayerRelation.CLAN)
{ {
final int x = graphics.getFontMetrics().stringWidth(builtString); if (clanManager.getRank(actor.getName()) != null)
final int y = graphics.getFontMetrics().getHeight(); {
OverlayUtil.renderActorTextAndImage(graphics, actor, builtString, color, OverlayUtil.renderActorTextAndImage(graphics, actor, builtString, color,
ImageUtil.resizeImage(skullIcon, y, y), 0, x); ImageUtil.resizeImage(Objects.requireNonNull(clanManager
.getClanImage(clanManager.getRank(actor.getName()))), y, y), 0, ACTOR_HORIZONTAL_TEXT_MARGIN);
return;
}
} }
if (skulls && actor.getSkullIcon() != null && relation.equals(PlayerRelation.TARGET))
{
OverlayUtil.renderActorTextAndImage(graphics, actor, builtString, color,
ImageUtil.resizeImage(skullIcon, y, y), ACTOR_OVERHEAD_TEXT_MARGIN, ACTOR_HORIZONTAL_TEXT_MARGIN);
}
else else
{ {
OverlayUtil.renderActorTextOverlay(graphics, actor, builtString, color); OverlayUtil.renderActorTextOverlay(graphics, actor, builtString, color);
} }
} }
if (Arrays.asList(plugin.getLocationHashMap() if (actor.getConvexHull() != null && indicationLocations.contains(PlayerIndicationLocation.HULL))
.getOrDefault(relation, NULL_OBJ))
.contains(PlayerIndicationLocation.HULL))
{ {
if (actor.getConvexHull() == null)
{
return;
}
OverlayUtil.renderPolygon(graphics, actor.getConvexHull(), color); OverlayUtil.renderPolygon(graphics, actor.getConvexHull(), color);
} }
if (Arrays.asList(plugin.getLocationHashMap() if (indicationLocations.contains(PlayerIndicationLocation.TILE))
.getOrDefault(relation, NULL_OBJ))
.contains(PlayerIndicationLocation.TILE))
{ {
final Polygon poly = actor.getCanvasTilePoly(); if (actor.getCanvasTilePoly() != null)
if (poly != null)
{ {
OverlayUtil.renderPolygon(graphics, poly, color); OverlayUtil.renderPolygon(graphics, actor.getCanvasTilePoly(), color);
} }
} }
if (plugin.isShowAgilityLevel() && checkWildy() && plugin.getResultCache().containsKey(actor.getName())) if (relation.equals(PlayerRelation.TARGET))
{ {
if (textLocation == null) if (plugin.isShowAgilityLevel() && checkWildy() && plugin.getResultCache().containsKey(actor.getName()))
{ {
return; if (textLocation == null)
}
final int level = plugin.getResultCache().get(actor.getName()).getAgility().getLevel();
if (plugin.getAgilityFormat() == PlayerIndicatorsPlugin.AgilityFormats.ICONS)
{
final int width = plugin.isShowCombatLevel() ? graphics.getFontMetrics().stringWidth(name)
+ ACTOR_HORIZONTAL_TEXT_MARGIN : graphics.getFontMetrics().stringWidth(name);
final int height = graphics.getFontMetrics().getHeight();
if (level >= plugin.getAgilityFirstThreshold())
{ {
OverlayUtil.renderImageLocation(graphics, return;
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
if (level >= plugin.getAgilitySecondThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + agilityIcon.getWidth() + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
if (level < plugin.getAgilityFirstThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(noAgilityIcon, height, height));
}
}
else
{
Color agiColor = Color.WHITE;
if (level >= plugin.getAgilityFirstThreshold())
{
agiColor = Color.CYAN;
}
else if (level >= plugin.getAgilitySecondThreshold())
{
agiColor = Color.GREEN;
}
else if (level < plugin.getAgilityFirstThreshold())
{
agiColor = Color.RED;
} }
final String n = level + " " + "Agility"; final int level = plugin.getResultCache().get(actor.getName()).getAgility().getLevel();
OverlayUtil.renderActorTextOverlay(graphics, actor, n, agiColor, 60);
if (plugin.getAgilityFormat() == PlayerIndicatorsPlugin.AgilityFormats.ICONS)
{
final int width = plugin.isShowCombatLevel() ? graphics.getFontMetrics().stringWidth(name)
+ ACTOR_HORIZONTAL_TEXT_MARGIN : graphics.getFontMetrics().stringWidth(name);
final int height = graphics.getFontMetrics().getHeight();
if (level >= plugin.getAgilityFirstThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
else if (level >= plugin.getAgilitySecondThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + agilityIcon.getWidth() + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
else if (level < plugin.getAgilityFirstThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(noAgilityIcon, height, height));
}
}
else
{
Color agiColor = Color.WHITE;
if (level >= plugin.getAgilityFirstThreshold())
{
agiColor = Color.CYAN;
}
else if (level >= plugin.getAgilitySecondThreshold())
{
agiColor = Color.GREEN;
}
else if (level < plugin.getAgilityFirstThreshold())
{
agiColor = Color.RED;
}
final String n = level + " " + "Agility";
OverlayUtil.renderActorTextOverlay(graphics, actor, n, agiColor, 60);
}
} }
} }
} }

View File

@@ -78,7 +78,14 @@ import net.runelite.http.api.hiscore.HiscoreResult;
public class PlayerIndicatorsPlugin extends Plugin public class PlayerIndicatorsPlugin extends Plugin
{ {
private static final HiscoreClient HISCORE_CLIENT = new HiscoreClient(); private static final HiscoreClient HISCORE_CLIENT = new HiscoreClient();
private final List<String> callers = new ArrayList<>();
private final Map<Player, PlayerRelation> colorizedMenus = new ConcurrentHashMap<>();
private final Map<PlayerRelation, Color> relationColorHashMap = new ConcurrentHashMap<>();
private final Map<PlayerRelation, Object[]> locationHashMap = new ConcurrentHashMap<>();
private final Map<String, Actor> callerPiles = new ConcurrentHashMap<>();
@Getter(AccessLevel.PACKAGE)
private final Map<String, HiscoreResult> resultCache = new HashMap<>();
private final ExecutorService executorService = Executors.newFixedThreadPool(100);
@Inject @Inject
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE)
private OverlayManager overlayManager; private OverlayManager overlayManager;
@@ -100,16 +107,7 @@ public class PlayerIndicatorsPlugin extends Plugin
@Inject @Inject
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE)
private EventBus eventBus; private EventBus eventBus;
private ClanMemberRank callerRank; private ClanMemberRank callerRank;
private final List<String> callers = new ArrayList<>();
private final Map<Player, PlayerRelation> colorizedMenus = new ConcurrentHashMap<>();
private final Map<PlayerRelation, Color> relationColorHashMap = new ConcurrentHashMap<>();
private final Map<PlayerRelation, Object[]> locationHashMap = new ConcurrentHashMap<>();
private final Map<String, Actor> callerPiles = new ConcurrentHashMap<>();
@Getter(AccessLevel.PACKAGE)
private final Map<String, HiscoreResult> resultCache = new HashMap<>();
private final ExecutorService executorService = Executors.newFixedThreadPool(100);
private PlayerIndicatorsPlugin.AgilityFormats agilityFormat; private PlayerIndicatorsPlugin.AgilityFormats agilityFormat;
private PlayerIndicatorsPlugin.MinimapSkullLocations skullLocation; private PlayerIndicatorsPlugin.MinimapSkullLocations skullLocation;
private String configCallers; private String configCallers;
@@ -368,6 +366,10 @@ public class PlayerIndicatorsPlugin extends Plugin
lastEntry.setTarget(ColorUtil.prependColorTag(target, color)); lastEntry.setTarget(ColorUtil.prependColorTag(target, color));
} }
if (image != -1)
{
lastEntry.setTarget("<img=" + image + ">" + lastEntry.getTarget());
}
if (image2 != -1 && this.playerSkull) if (image2 != -1 && this.playerSkull)
{ {
@@ -379,6 +381,7 @@ public class PlayerIndicatorsPlugin extends Plugin
} }
} }
private void getCallerList() private void getCallerList()
{ {
if (!this.highlightCallers) if (!this.highlightCallers)
@@ -445,7 +448,7 @@ public class PlayerIndicatorsPlugin extends Plugin
* @param actor The player to check * @param actor The player to check
* @return true if they are a target, false otherwise * @return true if they are a target, false otherwise
*/ */
private boolean isPile(Actor actor) public boolean isPile(Actor actor)
{ {
if (!(actor instanceof Player)) if (!(actor instanceof Player))
{ {

View File

@@ -24,14 +24,12 @@
*/ */
package net.runelite.client.plugins.playerindicators; package net.runelite.client.plugins.playerindicators;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import net.runelite.api.Actor;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.client.util.PvPUtil; import net.runelite.client.util.PvPUtil;
@@ -50,7 +48,6 @@ public class PlayerIndicatorsService
private final Predicate<Player> other; private final Predicate<Player> other;
private final Predicate<Player> caller; private final Predicate<Player> caller;
private final Predicate<Player> callerTarget; private final Predicate<Player> callerTarget;
private final List<Actor> piles = new ArrayList<>();
@Inject @Inject
private PlayerIndicatorsService(final Client client, final PlayerIndicatorsPlugin plugin) private PlayerIndicatorsService(final Client client, final PlayerIndicatorsPlugin plugin)
@@ -58,29 +55,34 @@ public class PlayerIndicatorsService
this.client = client; this.client = client;
this.plugin = plugin; this.plugin = plugin;
self = (player) -> Objects.equals(client.getLocalPlayer(), player); self = (player) -> (client.getLocalPlayer().equals(player)
friend = (player) -> (!player.equals(client.getLocalPlayer()) && client.isFriended(player.getName(), false)); && plugin.getLocationHashMap().containsKey(PlayerRelation.SELF));
clan = (player) -> (player.isClanMember() && !client.isFriended(player.getName(), false));
team = (player) -> (Objects.requireNonNull(client.getLocalPlayer()).getTeam() != 0 && friend = (player) -> (!player.equals(client.getLocalPlayer())
client.getLocalPlayer().getTeam() == player.getTeam()); && client.isFriended(player.getName(), false)
target = (player -> && plugin.getLocationHashMap().containsKey(PlayerRelation.FRIEND));
{
if (nonFriendly(player)) clan = (player) -> (player.isClanMember() && !client.getLocalPlayer().equals(player) && !client.isFriended(player.getName(), false)
{ && plugin.getLocationHashMap().containsKey(PlayerRelation.CLAN));
return false;
} team = (player) -> (Objects.requireNonNull(client.getLocalPlayer()).getTeam() != 0 && !player.isClanMember()
return plugin.isHighlightTargets() && PvPUtil.isAttackable(client, player); && !client.isFriended(player.getName(), false)
}); && client.getLocalPlayer().getTeam() == player.getTeam()
caller = plugin::isCaller; && plugin.getLocationHashMap().containsKey(PlayerRelation.TEAM));
callerTarget = piles::contains;
other = (player -> target = (player) -> (!team.test(player) && !clan.test(player)
{ && !client.isFriended(player.getName(), false) && PvPUtil.isAttackable(client, player)
if (nonFriendly(player)) && !client.getLocalPlayer().equals(player) && plugin.getLocationHashMap().containsKey(PlayerRelation.TARGET));
{
return false; caller = (player) -> (plugin.isCaller(player) && plugin.getLocationHashMap().containsKey(PlayerRelation.CALLER));
}
return true; callerTarget = (player) -> (plugin.isPile(player) && plugin.getLocationHashMap().containsKey(PlayerRelation.CALLER_TARGET));
});
other = (player) ->
(!PvPUtil.isAttackable(client, player) && !client.getLocalPlayer().equals(player)
&& !team.test(player) && !player.isClanMember() && !client.isFriended(player.getName(), false)
&& plugin.getLocationHashMap().containsKey(PlayerRelation.OTHER));
} }
public void forEachPlayer(final BiConsumer<Player, PlayerRelation> consumer) public void forEachPlayer(final BiConsumer<Player, PlayerRelation> consumer)
@@ -90,51 +92,50 @@ public class PlayerIndicatorsService
return; return;
} }
piles.clear();
final List<Player> players = client.getPlayers(); final List<Player> players = client.getPlayers();
for (Player p : players)
if (plugin.isHighlightOwnPlayer())
{ {
players.stream().filter(self).forEach(p -> consumer.accept(p, PlayerRelation.SELF)); if (self.test(p))
} {
if (plugin.isHighlightFriends()) consumer.accept(p, PlayerRelation.SELF);
{ continue;
players.stream().filter(friend.and(self.negate())).forEach(p -> consumer.accept(p, PlayerRelation.FRIEND)); }
} if (friend.test(p))
if (plugin.isHighlightClan()) {
{ consumer.accept(p, PlayerRelation.FRIEND);
players.stream().filter(clan.and(self.negate())).forEach(p -> consumer.accept(p, PlayerRelation.CLAN)); continue;
} }
if (plugin.isHighlightTeam()) if (clan.test(p))
{ {
players.stream().filter(team.and(self.negate())).forEach(p -> consumer.accept(p, PlayerRelation.TEAM)); consumer.accept(p, PlayerRelation.CLAN);
} continue;
if (plugin.isHighlightTargets()) }
{ if (team.test(p))
players.stream().filter(target.and(self.negate())).forEach(p -> consumer.accept(p, PlayerRelation.TARGET)); {
} consumer.accept(p, PlayerRelation.TEAM);
if (plugin.isHighlightOther()) continue;
{ }
players.stream().filter(other.and(self.negate())).forEach(p -> consumer.accept(p, PlayerRelation.OTHER)); if (target.test(p))
} {
if (plugin.isHighlightCallers()) consumer.accept(p, PlayerRelation.TARGET);
{ continue;
players.stream().filter(caller).forEach(p -> }
if (caller.test(p))
{ {
consumer.accept(p, PlayerRelation.CALLER); consumer.accept(p, PlayerRelation.CALLER);
if (p.getInteracting() != null) continue;
{ }
piles.add(p.getInteracting()); if (callerTarget.test(p) )
} {
}); consumer.accept(p, PlayerRelation.CALLER_TARGET);
continue;
}
if (other.test(p))
{
consumer.accept(p, PlayerRelation.OTHER);
}
} }
if (plugin.isHighlightCallerTargets()) }
{
players.stream().filter(callerTarget).forEach(p ->
consumer.accept(p, PlayerRelation.CALLER_TARGET));
}
}
private boolean highlight() private boolean highlight()
{ {
@@ -142,15 +143,4 @@ public class PlayerIndicatorsService
|| plugin.isHighlightFriends() || plugin.isHighlightOther() || plugin.isHighlightTargets() || plugin.isHighlightFriends() || plugin.isHighlightOther() || plugin.isHighlightTargets()
|| plugin.isHighlightCallers() || plugin.isHighlightTeam() || plugin.isHighlightCallerTargets(); || plugin.isHighlightCallers() || plugin.isHighlightTeam() || plugin.isHighlightCallerTargets();
} }
private boolean nonFriendly(Player player)
{
return player == null
|| (plugin.isHighlightClan() && player.isClanMember())
|| (plugin.isHighlightFriends() && client.isFriended(player.getName(), false))
|| (plugin.isHighlightCallers() && plugin.isCaller(player))
|| (plugin.isHighlightCallerTargets() && piles.contains(player))
|| (plugin.isHighlightTeam() && Objects.requireNonNull(client.getLocalPlayer()).getTeam() != 0
&& client.getLocalPlayer().getTeam() == player.getTeam());
}
} }

View File

@@ -286,14 +286,14 @@ public class OverlayUtil
public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color, BufferedImage image, int yOffset, int xOffset) public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color, BufferedImage image, int yOffset, int xOffset)
{ {
Point textLocation = new Point(actor.getConvexHull().getBounds().x + xOffset, Point textLocation = actor.getCanvasTextLocation(graphics, text, actor.getLogicalHeight() + yOffset);
actor.getConvexHull().getBounds().y + yOffset);
renderImageLocation(graphics, textLocation, image); if (textLocation != null)
xOffset = image.getWidth() + 1; {
yOffset = (image.getHeight() - (int) graphics.getFontMetrics().getStringBounds(text, graphics).getHeight()); renderImageLocation(graphics, textLocation, image);
textLocation = new Point(textLocation.getX() + xOffset, textLocation.getY() + image.getHeight() - yOffset); textLocation = new Point(textLocation.getX() + xOffset , textLocation.getY());
renderTextLocation(graphics, textLocation, text, color); renderTextLocation(graphics, textLocation, text, color);
}
} }
public static void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows, int yOffset) public static void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows, int yOffset)