diff --git a/megamek/src/megamek/client/ui/WrapLayout.java b/megamek/src/megamek/client/ui/WrapLayout.java index d0dbc930686..5428ff5d213 100644 --- a/megamek/src/megamek/client/ui/WrapLayout.java +++ b/megamek/src/megamek/client/ui/WrapLayout.java @@ -16,9 +16,9 @@ */ package megamek.client.ui; +import javax.swing.*; import java.awt.*; -import javax.swing.JScrollPane; -import javax.swing.SwingUtilities; +import java.util.StringTokenizer; /** * This class has been downloaded from a third-party source: @@ -102,14 +102,13 @@ private Dimension layoutSize(Container target, boolean preferred) { // When the container width = 0, the preferred width of the container // has not yet been calculated so lets ask for the maximum. - int targetWidth; Container container = target; while ((container.getSize().width == 0) && (container.getParent() != null)) { container = container.getParent(); } - targetWidth = container.getSize().width; + int targetWidth = container.getSize().width; if (targetWidth == 0) { targetWidth = Integer.MAX_VALUE; @@ -191,4 +190,31 @@ private void addRow(Dimension dim, int rowWidth, int rowHeight) { dim.height += rowHeight; } + + /** + * Inserts line breaks into a given input string to ensure that no line exceeds a maximum length. + * + * @param input The input string to be wrapped. + * @param maxLineLength The maximum length of each line. + * @return The string with line breaks inserted. + */ + public static String wordWrap(String input, int maxLineLength) { + StringTokenizer token = new StringTokenizer(input, " "); + StringBuilder output = new StringBuilder(input.length()); + + int lineLen = 0; + + while (token.hasMoreTokens()) { + String word = token.nextToken(); + + if (lineLen + word.length() > maxLineLength) { + output.append('\n'); + lineLen = 0; + } + output.append(word).append(' '); + lineLen += word.length(); + } + + return output.toString(); + } } diff --git a/megamek/src/megamek/common/templates/TROView.java b/megamek/src/megamek/common/templates/TROView.java index 58d4d411a0f..b95c2f4b88d 100644 --- a/megamek/src/megamek/common/templates/TROView.java +++ b/megamek/src/megamek/common/templates/TROView.java @@ -32,10 +32,13 @@ import java.io.Writer; import java.text.NumberFormat; import java.util.*; +import java.util.Map.Entry; import java.util.function.BiFunction; import java.util.function.Supplier; import java.util.stream.Collectors; +import static megamek.client.ui.WrapLayout.wordWrap; + /** * Fills in a template to produce a unit summary in TRO format. * @@ -160,27 +163,27 @@ protected void addEntityFluff(Entity entity) { model.put("year", String.valueOf(entity.getYear())); model.put("techRating", entity.getFullRatingName()); if (!entity.getFluff().getOverview().isBlank()) { - model.put("fluffOverview", entity.getFluff().getOverview()); + model.put("fluffOverview", wordWrap(entity.getFluff().getOverview(), 200)); } if (!entity.getFluff().getCapabilities().isBlank()) { - model.put("fluffCapabilities", entity.getFluff().getCapabilities()); + model.put("fluffCapabilities", wordWrap(entity.getFluff().getCapabilities(), 200)); } if (!entity.getFluff().getDeployment().isBlank()) { - model.put("fluffDeployment", entity.getFluff().getDeployment()); + model.put("fluffDeployment", wordWrap(entity.getFluff().getDeployment(), 200)); } if (!entity.getFluff().getHistory().isBlank()) { - model.put("fluffHistory", entity.getFluff().getHistory()); + model.put("fluffHistory", wordWrap(entity.getFluff().getHistory(), 200)); } if (!entity.getFluff().getManufacturer().isBlank()) { - model.put("manufacturerDesc", entity.getFluff().getManufacturer()); + model.put("manufacturerDesc", wordWrap(entity.getFluff().getManufacturer(), 200)); } if (!entity.getFluff().getPrimaryFactory().isBlank()) { - model.put("factoryDesc", entity.getFluff().getPrimaryFactory()); + model.put("factoryDesc", wordWrap(entity.getFluff().getPrimaryFactory(), 200)); } } @@ -239,7 +242,7 @@ protected void addMechVeeAeroFluff(Entity entity) { } } final List armaments = new ArrayList<>(); - for (final Map.Entry entry : weaponCount.entrySet()) { + for (final Entry entry : weaponCount.entrySet()) { armaments.add(String.format("%d %s", entry.getValue(), entry.getKey())); } if (podSpace > 0) { @@ -261,7 +264,7 @@ private String formatTechBase(Entity entity) { } else { sb.append(Messages.getString("TROView.InnerSphere")); } - sb.append(" (").append(entity.getStaticTechLevel().toString()).append(")"); + sb.append(" (").append(entity.getStaticTechLevel().toString()).append(')'); return sb.toString(); } @@ -429,7 +432,7 @@ protected int addEquipment(Entity entity, boolean includeAmmo) { } final List> eqList = new ArrayList<>(); for (final String loc : equipment.keySet()) { - for (final Map.Entry entry : equipment.get(loc).entrySet()) { + for (final Entry entry : equipment.get(loc).entrySet()) { final EquipmentType eq = entry.getKey().getType(); final int count = equipment.get(loc).get(entry.getKey()); String name = stripNotes(entry.getKey().name()); @@ -539,7 +542,7 @@ && showFixedSystem(entity, crit.getIndex(), loc)) { fixedList.add(row); } else { boolean firstLine = true; - for (final Map.Entry entry : fixedCount.entrySet()) { + for (final Entry entry : fixedCount.entrySet()) { row = new HashMap<>(); if (firstLine) { row.put("location", entity.getLocationName(loc)); @@ -686,16 +689,16 @@ protected String formatLocationTableEntry(Entity entity, Mounted mounted) { } protected enum Justification { - LEFT((str, w) -> String.format("%-" + w + "s", str)), CENTER((str, w) -> { + LEFT((str, w) -> String.format("%-" + w + 's', str)), CENTER((str, w) -> { if (w > str.length()) { final int rightPadding = Math.max(0, (w - str.length()) / 2); if (rightPadding > 0) { - str = String.format("%-" + (w - rightPadding) + "s", str); + str = String.format("%-" + (w - rightPadding) + 's', str); } - return String.format("%" + w + "s", str); + return String.format("%" + w + 's', str); } return str; - }), RIGHT((str, w) -> String.format("%" + w + "s", str)); + }), RIGHT((str, w) -> String.format("%" + w + 's', str)); final private BiFunction pad;