runehalberd 7 Posted March 8 (edited) I wanted to make a simple Paint utility that is customizable and easy to use. This tool will create a grid structure full of cells, each of which can contain text such as script run time, xp gained, script status, etc. You define the layout of the grid, set the style of the cells, and can update them as your script runs. Note that this was originally written in Kotlin and the Java code is untested and auto-generated so you may have to do some work converting it to Java 🙂. Usage Kotlin Spoiler import org.dreambot.api.script.AbstractScript import util.gridpainter.GridPainter import java.awt.Graphics2D class Main : AbstractScript() { private val gridPainter = GridPainter() override fun onStart() { // Create a cell named Status on row 1 that spans 2 columns gridPainter.addCell( Cell( name = "Status", rowNum = 1, span = 2, data = "Logging in..." ) ) // Create a cell named Time on row 2 that spans 1 column gridPainter.addCell( Cell( name = "Time", rowNum = 2, data = timer.getTime(), span = 1, prefixWithName = false, font = Font("Arial", Font.PLAIN, 10) ) ) } override fun onLoop(): Int { // Update the Status cell gridPainter.updateCell("Status", "Script has started.") } override fun onPaint(graphics: Graphics2D?) { // Do any regular cell updating gridPainter.updateCell("Time", data = timer.getTime()) // Call draw() to render the grid gridPainter.draw(graphics!!) } } Java Spoiler import java.awt.Font; import java.awt.Graphics2D; public class Main extends AbstractScript { private GridPainter gridPainter = new GridPainter(); @Override public void onStart() { // Create a cell named Status on row 1 that spans 2 columns gridPainter.addCell( new Cell( "Status", 2, "Logging in..." ) ); // Create a cell named Time on row 2 that spans 1 column gridPainter.addCell( new Cell( "Time", 2, timer.getTime(), 1, false, new Font("Arial", Font.PLAIN, 10) ) ); } @Override public int onLoop() { // Update the Status cell gridPainter.updateCell("Status", "Script has started."); return 0; } @Override public void onPaint(Graphics2D graphics) { // Do any regular cell updating gridPainter.updateCell("Time", timer.getTime()); // Call draw() to render the grid gridPainter.draw(graphics); } } These are the customizable properties: GridPainter: show - toggle display on/off x - left position of the grid y - top position of the grid cellWidth cellHeight cellBorderColor - color of the lines that border each cell Cell: name - name of the cell used for indexing and updating/removing data - the string to display in the cell prefixWithName - if true, will prefix the display string with "$name: " bgColor - background color of the cell textColor font - text Font() object span - int for how many columns this cell will span Sources GridPainter.kt Spoiler package util.gridpainter import java.awt.Color import java.awt.Font import java.awt.Graphics2D import java.util.LinkedList class GridPainter( var show: Boolean = true, var x: Double = 20.0, var y: Double = 20.0, var cellWidth: Double = 110.0, var cellHeight: Double = 25.0, var cellBorderColor: Color = Color.WHITE, private val grid: MutableList<LinkedList<Cell>> = mutableListOf() ) { companion object { val GRAY = Color(70, 61, 50, 156) val RED = Color(255, 61, 50, 156) val GREEN = Color(70, 255, 50, 156) val WHITE = Color(255, 255, 255, 156) val font = Font("Arial", Font.PLAIN, 14) } fun draw(g: Graphics2D) { if (show) { var x = this.x var y = this.y for (row in grid) { for (cell in row) { cell.draw(g, x, y, cellWidth, cellHeight, cellBorderColor) x += cellWidth } x = this.x y += cellHeight } } } fun addCell(cell: Cell) { // Create rows up to rowNum if they don't exist yet if (grid.size < cell.rowNum) { grid.addAll(List(cell.rowNum - grid.size) { LinkedList() }) } grid[cell.rowNum - 1].add(cell) } fun updateCell( name: String, data: String? = null, prefixWithName: Boolean? = null, bgColor: Color? = null, textColor: Color? = null, font: Font? = null, span: Int? = null ) { val cell = findCell(name) if (cell != null) { if (data != null) { cell.data = data } if (prefixWithName != null) { cell.prefixWithName = prefixWithName } if (bgColor != null) { cell.bgColor = bgColor } if (textColor != null) { cell.textColor = textColor } if (font != null) { cell.font = font } if (span != null) { cell.span = span } } } fun removeCell(name: String) { for (row in grid) { row.remove(findCell(name)) } } private fun findCell(name: String): Cell? { for (row in grid) { val cell = row.find { it.name == name } if (cell != null) { return cell } } return null } } Cell.kt Spoiler package util.gridpainter import util.gridpainter.GridPainter.Companion.GRAY import util.gridpainter.GridPainter.Companion.WHITE import java.awt.Color import java.awt.Font import java.awt.Graphics2D import java.awt.geom.Rectangle2D data class Cell( val name: String, val rowNum: Int, var data: String, var span: Int = 1, var prefixWithName: Boolean = true, var bgColor: Color = GRAY, var textColor: Color = WHITE, var font: Font = Font("Arial", Font.PLAIN, 10) ) { fun draw(g: Graphics2D, x: Double, y: Double, cellWidth: Double, cellHeight: Double, cellBorderColor: Color) { val w = cellWidth * span val text = if (prefixWithName) "$name: $data" else data val rect = Rectangle2D.Double(x, y, w, cellHeight) g.color = bgColor g.fill(rect) g.color = cellBorderColor g.draw(rect) g.font = font val fm = g.fontMetrics val textx = x + ((w - fm.stringWidth(text)) / 2) val texty = y + (((cellHeight - fm.height) / 2) + fm.ascent) g.drawString(text, textx.toFloat(), texty.toFloat()) } } GridPainter.java Spoiler package util.gridpainter; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.util.LinkedList; import java.util.List; public class GridPainter { private boolean show; private double x; private double y; private double cellWidth; private double cellHeight; private Color cellBorderColor; private List<LinkedList<Cell>> grid; public static final Color GRAY = new Color(70, 61, 50, 156); public static final Color RED = new Color(255, 61, 50, 156); public static final Color GREEN = new Color(70, 255, 50, 156); public static final Color WHITE = new Color(255, 255, 255, 156); public static final Font font = new Font("Arial", Font.PLAIN, 14); public GridPainter(boolean show, double x, double y, double cellWidth, double cellHeight, Color cellBorderColor) { this.show = show; this.x = x; this.y = y; this.cellWidth = cellWidth; this.cellHeight = cellHeight; this.cellBorderColor = cellBorderColor; this.grid = new LinkedList<>(); } public void draw(Graphics2D g) { if (show) { double x = this.x; double y = this.y; for (LinkedList<Cell> row : grid) { for (Cell cell : row) { cell.draw(g, x, y, cellWidth, cellHeight, cellBorderColor); x += cellWidth; } x = this.x; y += cellHeight; } } } public void addCell(Cell cell) { // Create rows up to rowNum if they don't exist yet if (grid.size() < cell.getRowNum()) { grid.addAll(new ArrayList<>(cell.getRowNum() - grid.size())); } grid.get(cell.getRowNum() - 1).add(cell); } public void updateCell(String name, String data, Boolean prefixWithName, Color bgColor, Color textColor, Font font, Integer span) { Cell cell = findCell(name); if (cell != null) { if (data != null) { cell.setData(data); } if (prefixWithName != null) { cell.setPrefixWithName(prefixWithName); } if (bgColor != null) { cell.setBgColor(bgColor); } if (textColor != null) { cell.setTextColor(textColor); } if (font != null) { cell.setFont(font); } if (span != null) { cell.setSpan(span); } } } public void removeCell(String name) { for (LinkedList<Cell> row : grid) { row.remove(findCell(name)); } } private Cell findCell(String name) { for (LinkedList<Cell> row : grid) { for (Cell cell : row) { if (cell.getName().equals(name)) { return cell; } } } return null; } } Cell.java Spoiler package util.gridpainter; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; public class Cell { private String name; private int rowNum; private String data; private int span; private boolean prefixWithName; private Color bgColor; private Color textColor; private Font font; public Cell(String name, int rowNum, String data, int span, boolean prefixWithName, Color bgColor, Color textColor, Font font) { this.name = name; this.rowNum = rowNum; this.data = data; this.span = span; this.prefixWithName = prefixWithName; this.bgColor = bgColor; this.textColor = textColor; this.font = font; } public void draw(Graphics2D g, double x, double y, double cellWidth, double cellHeight, Color cellBorderColor) { double w = cellWidth * span; String text = prefixWithName ? name + ": " + data : data; Rectangle2D rect = new Rectangle2D.Double(x, y, w, cellHeight); g.setColor(bgColor); g.fill(rect); g.setColor(cellBorderColor); g.draw(rect); g.setFont(font); java.awt.FontMetrics fm = g.getFontMetrics(); double textx = x + ((w - fm.stringWidth(text)) / 2); double texty = y + (((cellHeight - fm.getHeight()) / 2) + fm.getAscent()); g.drawString(text, (float) textx, (float) texty); } } Edited March 14 by runehalberd KCBot, MaximusPrimo and Luxe 1 2
Luxe 81 Posted April 9 (edited) Great initiative! Was not working straight out of the box on java, but I made some modifications: Main.Java public class Main extends TreeScript { private Timer timer; private long startTime; private GridPainter gridPainter = new GridPainter(true, 5, 5, 100, 35, new Color(255, 255, 255, 225)); public static String formatElapsedTime(long milliseconds) { long seconds = milliseconds / 1000; long hours = seconds / 3600; long minutes = (seconds % 3600) / 60; long remainingSeconds = seconds % 60; return String.format("%02d:%02d:%02d", hours, minutes, remainingSeconds); } @Override public void onPause() { if (timer != null) { timer.pause(); } } @Override public void onStart() { timer = new Timer(); startTime = System.currentTimeMillis(); timer.start(); gridPainter.addCell( new Cell( "Time", 1, "52", 1, false, new Color(255, 255, 255, 255), new Color(255, 255, 255, 255) ) ); gridPainter.addCell( new Cell( "Woodcutting EXP", 2, "0", 2, false, new Color(255, 255, 255, 255), new Color(255, 255, 255, 255) ) ); gridPainter.addCell( new Cell( "Fletching EXP", 3, "0", 2, false, new Color(255, 255, 255, 255), new Color(255, 255, 255, 255) ) ); } @Override public int onLoop() { if (timer != null && timer.isPaused()) { timer.resume(); } return this.getRoot().onLoop(); } @Override public void onPaint(Graphics2D graphics) { gridPainter.updateCell("Time", formatElapsedTime(timer.elapsed())); gridPainter.updateCell("Woodcutting EXP", String.valueOf(SkillTracker.getGainedExperience(Skill.WOODCUTTING)) + "exp"); gridPainter.updateCell("Fletching EXP", String.valueOf(SkillTracker.getGainedExperience(Skill.FLETCHING)) + "exp"); gridPainter.draw(graphics); } } ScriptPaint.Cell.java package ScriptPaint; import java.awt.*; import java.awt.geom.Rectangle2D; public class Cell { public static final Font font = new Font("Arial", Font.PLAIN, 14); private String name; private int rowNum; private String data; private int span; private boolean prefixWithName; private Color bgColor; private Color textColor; public Cell(String name, int rowNum, String data, int span, boolean prefixWithName, Color bgColor, Color textColor) { this.name = name; this.rowNum = rowNum; this.data = data; this.span = span; this.prefixWithName = prefixWithName; this.bgColor = bgColor; this.textColor = textColor; } public void draw(Graphics2D g, double x, double y, double cellWidth, double cellHeight, Color cellBorderColor) { double w = cellWidth * span; String text = prefixWithName ? name + ": " + data : data; Rectangle2D.Double rect = new Rectangle2D.Double(x, y, w, cellHeight); g.setColor(new Color(0, 0, 0, 100)); g.fill(rect); g.setColor(cellBorderColor); g.draw(rect); g.setFont(font); FontMetrics fm = g.getFontMetrics(); float textX = (float) (x + ((w - fm.stringWidth(text)) / 2)); float textY = (float) (y + (((cellHeight - fm.getHeight()) / 2) + fm.getAscent())); g.setColor(Color.WHITE); //text color g.drawString(text, textX, textY); } public String getName() { return name; } public int getRowNum() { return rowNum; } public void setData(String data) { this.data = data; } public void setPrefixWithName(boolean prefixWithName) { this.prefixWithName = prefixWithName; } public void setBgColor(Color bgColor) { this.bgColor = bgColor; } public void setTextColor(Color textColor) { this.textColor = textColor; } } ScriptPaint.GridPainter.java package ScriptPaint; import org.dreambot.api.utilities.Logger; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.util.LinkedList; import java.util.List; public class GridPainter { public static final Color GRAY = new Color(70, 61, 50, 156); public static final Color RED = new Color(255, 61, 50, 156); public static final Color GREEN = new Color(70, 255, 50, 156); public static final Color WHITE = new Color(255, 255, 255, 156); public static final Font font = new Font("Arial", Font.PLAIN, 14); private boolean show; private double x; private double y; private double cellWidth; private double cellHeight; private Color cellBorderColor; private List<LinkedList<Cell>> grid; public GridPainter(boolean show, double x, double y, double cellWidth, double cellHeight, Color cellBorderColor) { this.show = show; this.x = x; this.y = y; this.cellWidth = cellWidth; this.cellHeight = cellHeight; this.cellBorderColor = cellBorderColor; this.grid = new LinkedList<>(); } public void draw(Graphics2D g) { if (show) { double x = this.x; double y = this.y; for (LinkedList<Cell> row : grid) { for (Cell cell : row) { cell.draw(g, x, y, cellWidth, cellHeight, cellBorderColor); x += cellWidth; } x = this.x; y += cellHeight; } } } public void addCell(Cell cell) { int targetRowIndex = cell.getRowNum() - 1; // Ensure the grid has enough rows while (grid.size() <= targetRowIndex) { grid.add(new LinkedList<>()); } // Add the cell to the appropriate row grid.get(targetRowIndex).add(cell); } public void updateCell(String name, String data) { Cell cell = findCell(name); if (cell != null) { if (data != null) { cell.setData(data); cell.setPrefixWithName(true); cell.setBgColor(new Color(70, 61, 50, 156)); cell.setTextColor(new Color(255, 0, 0, 255)); } } } public void removeCell(String name) { for (LinkedList<Cell> row : grid) { row.remove(findCell(name)); } } private Cell findCell(String name) { for (LinkedList<Cell> row : grid) { for (Cell cell : row) { if (cell.getName().equals(name)) { return cell; } else { Logger.log("UABLE TO FIND CELL " + name); } } } return null; } } The updated code is arguably less clean and worse than originally proposed. but it works Edited April 9 by ImLife added formatting to java code
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now