Region Building with Position Integration
Create regions using flexible positioning with the RegionBuilder and Position integration for precise placement.
Overviewโ
The RegionBuilder class provides a fluent API for creating regions with precise positioning. By integrating with the Position class and Positions.Name enum, it offers both absolute pixel positioning and percentage-based placement options.
Key Featuresโ
- Absolute Positioning: Define regions using exact pixel coordinates
- Position Integration: Leverage the Position class for percentage-based placement
- Named Positions: Use semantic positions like TOPLEFT, MIDDLEMIDDLE, BOTTOMRIGHT
- Relative Positioning: Position regions relative to other regions
- Percentage-Based Sizing: Define regions as percentages of screen size
- Fluent API: Chain methods for readable region construction
Related Documentationโ
- Search Regions and Fixed Locations - Understand search regions vs fixed locations
- Declarative Region Definition - Define regions relative to other objects
- States Guide - Integrating regions in state definitions
- ActionConfig Overview - Using regions with actions
Basic Usageโ
Creating a RegionBuilderโ
import io.github.jspinak.brobot.model.element.Region;
import io.github.jspinak.brobot.model.element.RegionBuilder;
import io.github.jspinak.brobot.model.element.Position;
import static io.github.jspinak.brobot.model.element.Positions.Name.*;
// Access the builder through Region's static method
Region region = Region.builder()
.withSize(200, 150)
.build();
Absolute Positioningโ
// Simple region with absolute coordinates
Region absolute = Region.builder()
.withRegion(100, 100, 200, 150) // x, y, width, height
.build();
// Position and size separately
Region separate = Region.builder()
.withPosition(50, 75)
.withSize(300, 200)
.build();
Position-Based Placementโ
Using Position Objectsโ
The Position class provides percentage-based coordinates (typically 0.0 to 1.0, though values outside this range are allowed for off-screen positioning) for resolution-independent placement:
// Place region at 70% width, 30% height of screen
Region customPos = Region.builder()
.withSize(200, 150)
.withPosition(new Position(0.7, 0.3))
.build();
// Center of screen using Position
Region centered = Region.builder()
.withSize(400, 300)
.withPosition(new Position(0.5, 0.5))
.build();
Named Positionsโ
Use the Positions.Name enum for semantic positioning:
// Quick placement using named positions
Region topRight = Region.builder()
.withSize(300, 200)
.withPosition(TOPRIGHT)
.build();
Region bottomCenter = Region.builder()
.withSize(250, 100)
.withPosition(BOTTOMMIDDLE)
.build();
// All available named positions:
// TOPLEFT, TOPMIDDLE, TOPRIGHT
// MIDDLELEFT, MIDDLEMIDDLE, MIDDLERIGHT
// BOTTOMLEFT, BOTTOMMIDDLE, BOTTOMRIGHT
Convenience Methodsโ
RegionBuilder provides helper methods for common positions:
// Center on screen
Region dialog = Region.builder()
.withSize(600, 400)
.centerOnScreen()
.build();
// Corner positions
Region topLeft = Region.builder()
.withSize(100, 100)
.topLeft()
.build();
Region bottomRight = Region.builder()
.withSize(120, 80)
.bottomRight()
.build();
// Edge positions
Region topBar = Region.builder()
.withScreenPercentageSize(1.0, 0.1) // Full width, 10% height
.topCenter()
.build();
Region sidebar = Region.builder()
.withScreenPercentageSize(0.2, 1.0) // 20% width, full height
.leftCenter()
.build();
Screen Percentage Sizingโ
Define regions as percentages of screen dimensions:
// Size as percentage of screen
Region halfScreen = Region.builder()
.withScreenPercentageSize(0.5, 0.5) // 50% width, 50% height
.centerOnScreen()
.build();
// Position and size using percentages
Region searchArea = Region.builder()
.withScreenPercentage(0.1, 0.1, 0.8, 0.3) // x%, y%, width%, height%
.build();
// Just percentage size (position separately)
Region percentSized = Region.builder()
.withScreenPercentageSize(0.3, 0.4)
.topRight()
.build();
Relative Positioningโ
Position regions relative to other regions:
Region mainWindow = Region.builder()
.withSize(800, 600)
.centerOnScreen()
.build();
// Position tooltip above the main window
Region tooltip = Region.builder()
.withSize(200, 50)
.positionRelativeTo(mainWindow, TOPMIDDLE)
.adjustY(-10) // 10px gap above
.build();
// Position button in bottom-right of window
Region button = Region.builder()
.withSize(100, 40)
.positionRelativeTo(mainWindow, BOTTOMRIGHT)
.adjustX(-10) // 10px margin from right
.adjustY(-10) // 10px margin from bottom
.build();
// Custom relative position (25% from left, 75% from top)
Region marker = Region.builder()
.withSize(20, 20)
.positionRelativeTo(mainWindow, new Position(0.25, 0.75))
.build();
Predefined Screen Regionsโ
Quick methods for common screen divisions:โ
// Full screen
Region fullScreen = Region.builder()
.fullScreen()
.build();
// Half regions
Region topHalf = Region.builder()
.topHalf()
.build();
Region bottomHalf = Region.builder()
.bottomHalf()
.build();
Region leftHalf = Region.builder()
.leftHalf()
.build();
Region rightHalf = Region.builder()
.rightHalf()
.build();
Adjustments and Modificationsโ
Fine-tuning Position and Sizeโ
// Adjust individual dimensions
Region adjusted = Region.builder()
.withRegion(100, 100, 200, 150)
.adjustX(10) // Move 10px right
.adjustY(-20) // Move 20px up
.adjustWidth(50) // Increase width by 50px
.adjustHeight(30) // Increase height by 30px
.build();
// Adjust all at once
Region bulkAdjusted = Region.builder()
.withRegion(100, 100, 200, 150)
.adjustBy(10, -5, 20, 20) // x, y, width, height adjustments
.build();
Expanding and Contractingโ
// Expand region by pixels on all sides
Region expanded = Region.builder()
.withRegion(100, 100, 200, 150)
.expand(20) // Grows by 20px on all sides
.build();
// Result: x=80, y=80, width=240, height=190
// Contract region (negative expansion)
Region contracted = Region.builder()
.withRegion(100, 100, 200, 150)
.expand(-10) // Shrinks by 10px on all sides
.build();
Working with Existing Regionsโ
Region original = new Region(100, 100, 200, 150);
// Modify existing region
Region modified = Region.builder()
.fromRegion(original)
.adjustWidth(50)
.adjustHeight(50)
.build();
// Create region relative to existing
Region adjacent = Region.builder()
.fromRegion(original)
.adjustX(original.getW() + 10) // Position to the right
.build();
Custom Anchoringโ
Control how regions are positioned using anchor points:
// Default behavior (no anchor set) - position specifies top-left corner
Region defaultAnchor = Region.builder()
.withSize(100, 100)
.withPosition(500, 300) // Top-left corner at (500, 300)
.build();
// Center anchor - positions region at screen center
Region centerAnchor = Region.builder()
.withSize(100, 100)
.withAnchor(MIDDLEMIDDLE) // Places at screen center
.build();
// Result: Region centered on screen at ((screenWidth-100)/2, (screenHeight-100)/2)
// Custom anchor for screen-relative positioning
Region customAnchor = Region.builder()
.withSize(100, 100)
.withAnchor(new Position(0.75, 0.25)) // 75% from left, 25% from top
.build();
// Result: Positioned at (screenWidth*0.75 - 50, screenHeight*0.25 - 25)
Constraintsโ
Screen Boundary Constraintsโ
// Constrain to screen boundaries (default: true)
Region constrained = Region.builder()
.withPosition(10000, 10000) // Way off screen
.withSize(200, 150)
.constrainToScreen(true)
.build();
// Will be repositioned to stay within screen bounds
// Allow off-screen positioning
Region offScreen = Region.builder()
.withPosition(-50, -50)
.withSize(200, 150)
.constrainToScreen(false)
.build();
// Maintains negative coordinates
Aspect Ratio Maintenanceโ
// Maintain aspect ratio when resizing
Region aspectLocked = Region.builder()
.withSize(400, 300) // 4:3 ratio
.maintainAspectRatio(true)
.withWidth(600) // Height automatically becomes 450
.build();
Complex Layout Examplesโ
Dashboard Layoutโ
// Create a dashboard with header, sidebar, and content area
Region header = Region.builder()
.withScreenPercentageSize(1.0, 0.1) // Full width, 10% height
.topCenter()
.build();
Region sidebar = Region.builder()
.withScreenPercentageSize(0.2, 0.9) // 20% width, 90% height
.positionRelativeTo(header, BOTTOMLEFT)
.build();
Region content = Region.builder()
.positionRelativeTo(sidebar, MIDDLERIGHT)
.withScreenPercentageSize(0.8, 0.9)
.build();
Region footer = Region.builder()
.withScreenPercentageSize(1.0, 0.05)
.bottomCenter()
.build();
Modal Dialog with Overlayโ
// Semi-transparent overlay
Region overlay = Region.builder()
.fullScreen()
.build();
// Centered modal dialog
Region modal = Region.builder()
.withScreenPercentageSize(0.5, 0.6) // 50% width, 60% height
.centerOnScreen()
.build();
// Close button in modal's top-right
Region closeButton = Region.builder()
.withSize(30, 30)
.positionRelativeTo(modal, TOPRIGHT)
.adjustX(-10)
.adjustY(10)
.build();
Grid Layoutโ
import java.util.List;
import java.util.ArrayList;
// Create a 3x3 grid of regions
List<Region> grid = new ArrayList<>();
double cellWidth = 0.33;
double cellHeight = 0.33;
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
Region cell = Region.builder()
.withScreenPercentage(
col * cellWidth, // x position
row * cellHeight, // y position
cellWidth * 0.9, // width with gap
cellHeight * 0.9 // height with gap
)
.build();
grid.add(cell);
}
}
Best Practicesโ
1. Use Percentages for Cross-Platform Compatibilityโ
// Good: Percentage-based, works on any screen
Region adaptive = Region.builder()
.withScreenPercentageSize(0.3, 0.4)
.centerOnScreen()
.build();
// Avoid: Fixed pixels may not work on different screens
Region fixed = Region.builder()
.withRegion(640, 360, 640, 480)
.build();
2. Use Direct Coordinates for Pixel-Perfect Placementโ
// Specify exact pixel coordinates when precision is needed
Region precise = Region.builder()
.withPosition(500, 300)
.withSize(400, 200)
.build();
3. Use Named Positions for Clarityโ
// Clear intent
Region notification = Region.builder()
.withSize(300, 100)
.topRight()
.adjustX(-20)
.adjustY(20)
.build();
// Less clear
Region notification2 = Region.builder()
.withSize(300, 100)
.withAnchor(new Position(1.0, 0.0))
.build();
4. Combine Relative and Absolute Positioningโ
// Start with relative, fine-tune with absolute
Region precise = Region.builder()
.withScreenPercentageSize(0.25, 0.2)
.centerOnScreen()
.adjustX(-10) // Fine adjustments
.adjustY(5)
.build();
5. Use Percentage-Based Sizing for Flexibilityโ
// Create regions that work well at any resolution
Region flexible = Region.builder()
.withScreenPercentage(0.1, 0.1, 0.8, 0.8) // 10% margins, 80% of screen
.build();
// Verify region is properly defined
assert flexible.isDefined();
assert flexible.getW() > 0 && flexible.getH() > 0;
Integration with Brobot Actionsโ
RegionBuilder-created regions work seamlessly with Brobot's Action API for clicking, typing, and pattern matching. For complete Action API documentation, see ActionConfig Overview and ActionConfig Examples.
For more on States and the @State annotation, see States Guide and Annotations Reference.
Using RegionBuilder in State Definitionsโ
import io.github.jspinak.brobot.actions.Action;
import io.github.jspinak.brobot.model.element.Region;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import static io.github.jspinak.brobot.model.element.Positions.Name.*;
@Component
public class LoginPageController {
@Autowired
private Action action;
private final Region usernameField = Region.builder()
.withScreenPercentage(0.4, 0.4, 0.2, 0.05)
.build();
private final Region passwordField = Region.builder()
.positionRelativeTo(usernameField, BOTTOMMIDDLE)
.withSize(usernameField.getW(), usernameField.getH())
.adjustY(20)
.build();
private final Region loginButton = Region.builder()
.positionRelativeTo(passwordField, BOTTOMMIDDLE)
.withSize(100, 40)
.adjustY(30)
.build();
// Use regions with Brobot actions
public void login(String username, String password) {
// Click and type in username field
action.click(usernameField);
action.type(username);
// Click and type in password field
action.click(passwordField);
action.type(password);
// Click login button
action.click(loginButton);
}
}
Dynamic Region Creationโ
import io.github.jspinak.brobot.actions.Action;
import io.github.jspinak.brobot.model.element.Region;
import io.github.jspinak.brobot.model.element.StateImage;
import io.github.jspinak.brobot.core.screen.ScreenDimensions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AdaptiveSearch {
@Autowired
private Action action;
public Region getSearchAreaForScreen() {
// Detect current screen size using Brobot's ScreenDimensions
int screenWidth = ScreenDimensions.getWidth();
if (screenWidth > 2000) {
// Large screen: search in center third
return Region.builder()
.withScreenPercentage(0.33, 0.33, 0.34, 0.34)
.build();
} else if (screenWidth > 1400) {
// Medium screen: search in center half
return Region.builder()
.withScreenPercentageSize(0.5, 0.5)
.centerOnScreen()
.build();
} else {
// Small screen: search most of screen
return Region.builder()
.withScreenPercentage(0.1, 0.1, 0.8, 0.8)
.build();
}
}
// Example usage with pattern matching
public void performAdaptiveSearch(StateImage pattern) {
Region searchArea = getSearchAreaForScreen();
action.find(pattern).inRegion(searchArea);
}
}
Troubleshootingโ
For visual debugging of regions, use the highlighting feature to see regions on screen. For complete configuration options, see the Properties Reference. For handling different screen resolutions and DPI settings, see the DPI Resolution Guide.
Region Outside Screen Boundsโ
// Problem: Region appears cut off
Region problem = Region.builder()
.withPosition(1800, 1000)
.withSize(300, 200)
.build();
// Solution: Enable screen constraints
Region solution = Region.builder()
.withPosition(1800, 1000)
.withSize(300, 200)
.constrainToScreen(true) // Ensures region stays on screen
.build();
Size Issuesโ
// Problem: Region too small for reliable clicking
Region tooSmall = Region.builder()
.withPosition(100, 100)
.withSize(5, 5) // Too small!
.build();
// Solution: Use appropriate minimum sizes
Region clickable = Region.builder()
.withPosition(100, 100)
.withSize(50, 30) // Reasonable click target
.build();
// Or use percentage-based sizing for flexibility
Region flexible = Region.builder()
.withScreenPercentage(0.1, 0.1, 0.05, 0.03) // 5% width, 3% height
.build();
Understanding Anchor Behaviorโ
// Important: Anchors are screen-relative, not position-relative
Region screenCentered = Region.builder()
.withSize(100, 100)
.withAnchor(MIDDLEMIDDLE) // Places region at screen center
.build();
// Result: Positioned at ((screenWidth-100)/2, (screenHeight-100)/2)
// Anchors ignore withPosition() - they use screen dimensions
Region alsoScreenCentered = Region.builder()
.withSize(100, 100)
.withAnchor(MIDDLEMIDDLE)
.withPosition(500, 300) // This is IGNORED when anchor is set!
.build();
// Result: Still positioned at screen center, NOT at (500, 300)
// Solution: For specific positioning, don't use anchors
Region specificPosition = Region.builder()
.withSize(100, 100)
.withPosition(500, 300) // Top-left at (500, 300)
.build();
Summaryโ
The enhanced RegionBuilder with Position integration provides:
- Resolution Independence: Define once, run anywhere
- Intuitive API: Named positions and percentage-based sizing
- Flexibility: Combine relative and absolute positioning
- Maintainability: Clear, readable region definitions
- Adaptability: Automatic scaling between resolutions
Use RegionBuilder to create robust, screen-adaptive automation that works consistently across different environments and display configurations.
Next Stepsโ
- Search Regions and Fixed Locations - Learn how regions are used for pattern matching
- Declarative Region Definition - Define regions dynamically relative to other objects
- States Guide - Integrate regions into state-based automation
- Quick Start Guide - Get started with Brobot
- ActionConfig Examples - Use regions with actions