Need to add Scroll Bar - java

I am an enthusiast rather than a programmer. I have thousands of pdf files to go through and extract some data. The data is in X inside boxes (I suspect a graphic within the pdf) there is no evidence of this data if I convert the PDF to text so...
I am converting the PDF to image then looking at the image in certain areas where I expect the X to be and counting black pixels, so far so good.
The PDF does not fit in the window height-wise so I need to add a scrollbar.
I don't understand how I can add a scrollbar to the main window.
Can someone just steer me in the right direction
Thank you
The code is incomplete but working:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class ImageViewer {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable()
{
public void run(){
ImageFrame frame = new ImageFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
);
}
}
class ImageFrame extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
public ImageFrame(){
setTitle("Image Viewer");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
ImageComponent component = new ImageComponent();
add(component);
}
public static final int DEFAULT_WIDTH = 860;
public static final int DEFAULT_HEIGHT = 1000;
}
class ImageComponent extends JComponent{
/**
*
*/
private static final long serialVersionUID = 1L;
private Image image;
public ImageComponent(){
try{
File image2 = new File("Files/4.jpg");
image = ImageIO.read(image2);
}
catch (IOException e){
e.printStackTrace();
}
}
public void paintComponent (Graphics g){
if(image == null) return;
int imageWidth = image.getWidth(this);
int imageHeight = image.getHeight(this);
g.drawImage(image, 0, 0, this);
// Draw on the BufferedImage via the graphics context.
g.setColor(Color.RED);
g.drawRect(445, 153, 20, 20);
g.drawRect(552, 153, 20, 20);
g.drawRect(661, 153, 20, 20);
g.drawRect(445, 182, 20, 20);
g.drawRect(552, 182, 20, 20);
g.drawRect(661, 182, 20, 20);
g.drawRect(445, 226, 20, 20);
g.drawRect(552, 226, 20, 20);
g.drawRect(661, 226, 20, 20);
g.drawRect(445, 271, 20, 20);
g.drawRect(552, 271, 20, 20);
g.drawRect(661, 271, 20, 20);
for (int i = 0; i*imageWidth <= getWidth(); i++)
for(int j = 0; j*imageHeight <= getHeight();j++)
if(i+j>0) g.copyArea(0, 0, imageWidth, imageHeight, i*imageWidth, j*imageHeight);
//Count black pixels to see if the box contains an X
int A1 = 0;
for (int y = 153; y < 173; y++)
{
for (int x = 445; x < 465; x++)
{
int c = ((BufferedImage) image).getRGB(x,y);
Color color = new Color(c);
if (c != -1)
{
A1++;
}
}
}
System.out.println("First box pixel count = " + A1);
//Count black pixels to see if the box contains an X
int A2 = 0;
for (int y = 153; y < 173; y++)
{
for (int x = 552; x < 572; x++)
{
int c = ((BufferedImage) image).getRGB(x,y);
if (c != -1)
{
A2++;
}
}
}
System.out.println("Second box pixel count = " + A2);
//Count black pixels to see if the box contains an X
int A3 = 0;
for (int y = 153; y < 173; y++)
{
for (int x = 661; x < 681; x++)
{
int c = ((BufferedImage) image).getRGB(x,y);
if (c != -1)
{
A3++;
}
}
}
System.out.println("Third box pixel count = " + A3);
}
}

Look for something like JScrollPane myPane = new JScrollPane();

Related

How to display Graphics2D object on JFrame

This is my first time trying to build a GUI and I've reached an impasse which I can't seem to find the solution to. Currently I have parts of my GUI set up but I want to insert a graph I've created on another class, however, I'm not sure how to link it with my current JFrame. I can get it to work as a separate entity, but not together.
MainDisplay Class:
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainDisplay().setVisible(true);
}
});
float LvBTC;
float LvLTC;
float LvETH;
float[] HBTC;
float[] HLTC;
float[] HETH;
float CurETH;
float CurBTC;
float CurLTC;
WebScraper WS1 = new WebScraper();
LvBTC = WS1.LvScrapeBTC();
LvLTC = WS1.LvScrapeLTC();
LvETH = WS1.LvScrapeETH();
HBTC = WS1.HScrapeBTC();
HLTC = WS1.HScrapeLTC();
HETH = WS1.HScrapeETH();
System.out.println("Bitcoin's Current Price is: $"+LvBTC);
System.out.println("Litecoin's Current Price is: $"+LvLTC);
System.out.println("Ethereum's Current Price is: $"+LvETH);
Graph G1 = new Graph();
G1.CurrentValues(HBTC);
for (int i = 0; 5 > i;) {
System.out.println("Day " + (i + 1) + ": $" + G1.CurValues[i]);
i++;
}
System.out.println("Index of largest value: " + G1.IndexLarge(G1.CurValues));
System.out.println("Index of smallest value: " + G1.IndexSmall(G1.CurValues));
Graph Graphing = new Graph();
}
Graph Class:
package comsci_ia;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JFrame;
public class Graph extends JFrame {
int IndexL;
int IndexS;
int DistanceDay1;
int DistanceDay2;
int DistanceDay3;
int DistanceDay4;
int DistanceDay5;
float[] CurValues = new float[5];
ArrayList<Point> points = new ArrayList<>();
public float[] CurrentValues(float[] array) {
DatabaseBrowser DB1 = new DatabaseBrowser();
WebScraper WS1 = new WebScraper();
float[] HBTC = WS1.HScrapeBTC();
float[] HETH = WS1.HScrapeETH();
float[] HLTC = WS1.HScrapeLTC();
float CurHold = 0;
boolean BTCCheck = false;
BTCCheck = Arrays.equals(HBTC, array);
boolean LTCCheck = false;
LTCCheck = Arrays.equals(HLTC, array);
boolean ETHCheck = false;
ETHCheck = Arrays.equals(HETH, array);
if (BTCCheck == true) {
CurHold = DB1.RetriveBTC();
}
if (LTCCheck == true) {
CurHold = DB1.RetriveLTC();
}
if (ETHCheck == true) {
CurHold = DB1.RetriveETH();
}
float pick;
for (int i = 0; 5 > i;) {
for (int z = 0; z < array.length; z++) {
pick = array[z];
pick = pick * CurHold;
CurValues[i] = pick;
i++;
}
}
return CurValues;
}
public int IndexLarge(float[] array) {
float temp = 0;
for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the Largest value
if (array[i] > temp) {
temp = array[i];
}
i++;
}
int IndexCheck = 0; //Searches and records the index of "temp" value (Largest value in array)
for (IndexCheck = 0; 5 > IndexCheck;) {
if (array[IndexCheck] == temp) {
break;
}
IndexCheck++;
}
IndexL = IndexCheck;
return IndexL;
}
public int IndexSmall(float[] array) {
float temp = 1000000;
for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the smallest value
if (array[i] < temp) {
temp = array[i];
}
i++;
}
int IndexCheck = 0; //Searches and records the index of "temp" value (smallest value in array)
for (IndexCheck = 0; 5 > IndexCheck;) {
if (array[IndexCheck] == temp) {
break;
}
IndexCheck++;
}
IndexS = IndexCheck;
return IndexS;
}
public void Plotter(float[] array) {
/* int DayRefL = IndexL + 1;
int DayRefS = IndexS + 1; */
float ValRange;
float ValPx;
points = null;
ValRange = array[IndexL] - array[IndexS];
ValPx = (300f/ ValRange); //Number is the pixel distance between highest and lowest values
DistanceDay1 = (int) ((int) 50 + ((array[IndexL] - array[0]) * ValPx));
DistanceDay2 = (int) ((int) 50 + ((array[IndexL] - array[1]) * ValPx));
DistanceDay3 = (int) ((int) 50 + ((array[IndexL] - array[2]) * ValPx));
DistanceDay4 = (int) ((int) 50 + ((array[IndexL] - array[3]) * ValPx));
DistanceDay5 = (int) ((int) 50 + ((array[IndexL] - array[4]) * ValPx));
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Today");
int middle = width / 2;
g2.setColor(Color.BLACK);
/* g2.drawLine(10, 10, 10, 410); //Frame Boundaries
g2.drawLine(410, 10, 10, 10); //Frame Boundaries
g2.drawLine(410, 10, 410, 410); //Frame Boundaries
g2.drawLine(410, 410, 10, 410); //Frame Boundaries */
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, DistanceDay1, DotSize);
g2.drawLine(98, DistanceDay1, 166, DistanceDay2);
PlotPoints(g2, 166, DistanceDay2, DotSize);
g2.drawLine(166, DistanceDay2, 234, DistanceDay3);
PlotPoints(g2, 234, DistanceDay3, DotSize);
g2.drawLine(234, DistanceDay3, 302, DistanceDay4);
PlotPoints(g2, 302, DistanceDay4, DotSize);
g2.drawLine(302, DistanceDay4, 370, DistanceDay5);
PlotPoints(g2, 370, DistanceDay5, DotSize);
//Labels
g2.drawString("Today", 370 - middle, 390);
/* g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25); */
}
private void PlotPoints(Graphics2D g, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g.fillOval(x, y, r, r);
}
}
If I run the Graph class as a separate entity it'll result in this: Graph pop-up
Here's a separate version of the Graph code in which a frame will pop up displaying the graph:
package graphing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Graphing extends JPanel {
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Test");
int middle = width / 2;
g2.setColor(Color.BLACK);
g2.drawLine(10, 10, 10, 390); //Frame Boundaries
g2.drawLine(390, 10, 10, 10); //Frame Boundaries
g2.drawLine(390, 10, 390, 390); //Frame Boundaries
g2.drawLine(390, 390, 10, 390); //Frame Boundaries
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, 55, DotSize);
g2.drawLine(98, 55, 166, 40);
PlotPoints(g2, 166, 40, DotSize);
g2.drawLine(166, 40, 234, 100);
PlotPoints(g2, 234, 100, DotSize);
g2.drawLine(234, 100, 302, 332);
PlotPoints(g2, 302, 332, DotSize);
g2.drawLine(302, 332, 370, 40);
PlotPoints(g2, 370, 40, DotSize);
//Labels
g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25);
}
private void PlotPoints(Graphics2D g, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g.fillOval(x, y, r, r);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(420, 420);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Graphing app = new Graphing();
frame.setContentPane(app);
frame.setVisible(true);
frame.invalidate();
}
}
So, my immediate issue is, you're extending from JFrame, which isn't a good, as this locks the UI into in a single use case (it's not easily re-usable)
My second issue is, you've created a method called paintComponent in JFrame, but since JFrame doesn't use this style of painting, it is never called
So, the first thing I would do is change Graph so it extends from JPanel instead...
public class Graph extends JPanel {
//...
I would then update your paintComponent so it supports the painting process properly...
#Overrride
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//...
Now, the next problem is, you're going to need to provide some sizing hints so that the layout manager of the container you add it to has some idea about how best to layout the component...
#Override
public Dimension getPreferredSize() {
// I've not been through your code in detail
// so I've not calculated what the actual
// preferred size might be and this is just an
// example you'll have to update
return new Dimension(200, 200);
}
Now, you can create an instance of Graph and add it to what ever container you want

Swing - Painting tree and Jfreechart in one window

I have a program that I am writing and I need it to both draw a tree and plot its points.
The issue:
My paint seems to go under my graph/plot even though they are in two panels. What can I do so that they do not overlap. Maybe even a scroll bar?
Here is an example Left is with the graph overlapping, right is showing what is underneath.
Bonus:
What is a better way to draw the tree, some of the nodes overlap.
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import org.jfree.chart.*;
import org.jfree.chart.axis.Axis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
public class ui extends JFrame {
JPanel tp,chartPanel;
Tree t;
Node root;
Parser p;
double x = 0, y = 0;
int generation = 0;
int timeSeconds = 0;
double fitness = Double.MIN_VALUE;
int sizeX = 1000;
int sizeY = 1000;
int depth = 10;
public ui() {
super("Simple Tree");
setSize(sizeX, sizeY);
setDefaultCloseOperation(EXIT_ON_CLOSE);
tp = new TPanel();
tp.setLayout(new BorderLayout());
chartPanel = new TPanel();
chartPanel.setLayout(new BorderLayout());
//JButton genButton = new JButton("Generate Tree");
//tp.add(genButton);
add(tp);
add(chartPanel);
}
public ChartPanel GraphTree(Node n){
XYSeriesCollection dataSet = new XYSeriesCollection();
XYSeries series = new XYSeries("Data");
XYSeries actual = new XYSeries("Actual");
Parser p = new Parser();
for(double index = -10; index < 10; index+=0.1){
series.add(index, p.TreeOutputAtPoint(n,index));
}
dataSet.addSeries(series);
JFreeChart jc = ChartFactory.createXYLineChart("Tree Graph", "Input", "Output",dataSet,
PlotOrientation.VERTICAL, true, true, false);
ChartPanel cp = new ChartPanel(jc);
cp.setPreferredSize(new java.awt.Dimension(200, 500));
cp.setVisible(true);
chartPanel.add(cp, BorderLayout.SOUTH);
chartPanel.validate();
chartPanel.removeAll();
chartPanel.revalidate();
//tp.repaint();
return cp;
}
public void drawTree(Node r, int gen, double fit, int timeSec){
root = r;
p = new Parser();
generation = gen;
timeSeconds = timeSec;
fitness = fit;
}
class TPanel extends JPanel {
public TPanel() {
setPreferredSize(new Dimension(sizeX, sizeY));// fill whole frame
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(root != null){
Eval(root, g, sizeX/2, 100);
g.drawString("Generation: " + generation, 15, 100);
g.drawString("Time it took: " + timeSeconds + " seconds", 15, 120);
g.drawString("Fitness: " + fitness, 15, 140);
}
}
}
public static void Eval(Node input, Graphics g, int x, int y) {
g.drawString(input.data, x, y);
if (!input.leaf) {
g.drawLine(x, y + 5, x - 20, y + 20);
Eval(input.left, g, x - 30, y + 30);
if (!Utility.isUnary(input.data)) {
g.drawLine(x, y + 5, x + 20, y + 20);
Eval(input.right, g, x + 30, y + 30);
}
}
}
}
https://github.com/kevkid/GeneticAlgorithmTest/blob/master/GeneticAlgorithmTest/src/ui.java
Any help would be appreciated.

Collision() not working properly

So when I collide into getBoundsBlock() it stops the player like it should but, it will not let me go up, only left and right. But, the main problem comes in when I collide into getBoundsBlock2(). When I collide into that one I can go threw the left and right sides of it. If I collide into the bottom or top of it my player gets stuck and can only go left or right.
player.java
package com.questkings.game;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
public class Player{
int x = 1; // Location of player
int y = 314; // location of player
int xa = 0; // Representation of where the player goes
int ya = 0; // Representation of where the player goes
private int speed = 2;
int[] playerPos = {x, y};
private static final int WIDTH = 30;
private static final int HEIGHT = 30;
private Game game;
public Player(Game game){
this.game=game;
}
public void move(){
if(x + xa < 0) // Left Bounds
xa = 0;
else if (x + xa > game.getWidth() - WIDTH) // Right Bounds
xa = 0;
else if (y + ya < 0) // Top Bounds
ya = 0;
else if(y + ya > game.getHeight() - WIDTH)
ya = 0;
else if (collision()) // Tile bounds
ya = 0;
else if (collision2())
ya = 0;
x = x + xa;
y = y + ya;
}
// Method to find where player is located
public int[] Playerposition(){
return playerPos;
}
public void paint(Graphics2D g2d){
//Draws player to screen
g2d.drawImage(getPlayerImg(), x, y, null);
}
public Image getPlayerImg(){
ImageIcon ic = new ImageIcon("C:/Users/AncientPandas/Desktop/KingsQuest/Misc/Images/Sprites/player.png");
return ic.getImage();
}
public void keyReleased(KeyEvent e){
xa = 0;
ya = 0;
}
public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_S)
xa = -speed;
if (e.getKeyCode() == KeyEvent.VK_F)
xa = speed;
if (e.getKeyCode() == KeyEvent.VK_E)
ya = -speed;
if (e.getKeyCode() == KeyEvent.VK_D)
ya = speed;
}
public Rectangle getBoundsPlayer(){
return new Rectangle(x, y, WIDTH, HEIGHT);
}
private boolean collision(){
return game.maplayout.getBoundsBlock().intersects(getBoundsPlayer());
}
private boolean collision2(){
return game.maplayout.getBoundsBlock2().intersects(getBoundsPlayer());
}
}
MapLayout.java
package com.questkings.game;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
public class MapLayout {
int[] blockPlacementX = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300,
330, 360, 390, 420, 450, 480, 510, 540, 570, 600, 630, 660, 690, 720,
750, 780, 810};
int[] blockPlacementY = {344, 254};
#SuppressWarnings("unused")
private Game game;
public MapLayout(Game game){
this.game=game;
}
//Map size 810(x), 420(y)
public void paint(Graphics2D g2d){
for(int i = 0; i < blockPlacementX.length; i++){
g2d.drawImage(getBlockIMG(), blockPlacementX[i], blockPlacementY[0], null);
}
for(int i = 13; i < blockPlacementX.length - 10; i++)
{
g2d.drawImage(getBlockIMG(), blockPlacementX[i], blockPlacementY[1], null);
}
}
public Image getBlockIMG(){
ImageIcon ic = new ImageIcon("C:/Users/AncientPandas/Desktop/KingsQuest/Misc/Images/Sprites/grassWall.png");
return ic.getImage();
}
// Bug: Bounds are making it so I can not go back up if I hit block 344
public Rectangle getBoundsBlock(){
return new Rectangle(0, 344, 810, 30);
}
public Rectangle getBoundsBlock2(){
return new Rectangle(390, 254, 150, 30);
}
}
On collision, you are setting the delta y as ya=0 which means no change in the vertical movement(up or down) when a collision occurs. You probably want to rethink what you want here.

Java Partition Surface into Little Squares

I would like to know if there is any algorithm that does something like this:
Given a specific surface it divides it into smaller rectangles of the same size.
Something like this example figure:
The grey area is the surface, and the red squares is the partition itself.
I am thinking if there is a optimized way to do this.
A very bad approach would be a for loop in all the pixels and check if there is a rectangle for that specific spot, if not, would create a rectangle, and so on..
Maybe someone knows a algorithm already done? or a better solution?
Thanks alot in advance ;)
Here's one way to go about it.
Create a mask of the image. (I just used Photoshop)
Steal AndrewThompson's code for Creating an Area from an Image and use it to create an Area of the image.
Area imageArea = getOutline(Color.BLACK, imageMask);
Create a grid Rectangle2D objects for the entirety of the image.
Rectangle2D[][] grid = new Rectangle2D[rows][cols];
for (int i = 0; i < grid.length; i++) {
int y = i * CELL_SIZE;
for (int j = 0; j < grid[i].length; j++) {
int x = j * CELL_SIZE;
grid[i][j] = new Rectangle2D.Double(x, y, cellSize, cellSize);
}
}
Once you have the grid, you can just traverse the Rectangle2D objects and check if the Area.contains each individual Rectangle2D in the grid, and you can just add it to a List<Rectangle2D>. Only rectangles contained in the area will be added, giving you your final grid of rectangles to draw. In the example below, I just painted to rectangles as a visual.
for (Rectangle2D[] rects : imageGrid) {
for (Rectangle2D rect : rects) {
if (imageArea.contains(rect)) {
g2.drawRect((int) rect.getX(), (int) rect.getY(),
(int) rect.getWidth(), (int) rect.getHeight());
}
}
}
Full example
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SquaresInArea extends JPanel {
private static final int CELL_SIZE = 30;
BufferedImage image;
BufferedImage imageMask;
Area imageArea;
Rectangle2D[][] imageGrid;
public SquaresInArea() {
try {
image = ImageIO.read(getClass().getResource("/resources/floorplan.png"));
imageMask = ImageIO.read(getClass().getResource("/resources/floorplan-black.png"));
} catch (IOException ex) {
Logger.getLogger(SquaresInArea.class.getName()).log(Level.SEVERE, null, ex);
}
imageArea = getOutline(Color.BLACK, imageMask);
imageGrid = createGrid();
}
private Rectangle2D[][] createGrid() {
int width = image.getWidth();
int height = image.getHeight();
int rows = height / CELL_SIZE;
int cols = width / CELL_SIZE;
Rectangle2D[][] grid = new Rectangle2D[rows][cols];
for (int i = 0; i < grid.length; i++) {
int y = i * CELL_SIZE;
for (int j = 0; j < grid[i].length; j++) {
int x = j * CELL_SIZE;
grid[i][j] = new Rectangle2D.Double(x, y, CELL_SIZE, CELL_SIZE);
}
}
return grid;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, this);
g2.setColor(Color.YELLOW);
g2.setStroke(new BasicStroke(3f));
for (Rectangle2D[] rects : imageGrid) {
for (Rectangle2D rect : rects) {
if (imageArea.contains(rect)) {
g2.drawRect((int) rect.getX(), (int) rect.getY(),
(int) rect.getWidth(), (int) rect.getHeight());
}
}
}
}
#Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(300, 300)
: new Dimension(image.getWidth(), image.getHeight());
}
private Area getOutline(Color target, BufferedImage bi) {
// construct the GeneralPath
GeneralPath gp = new GeneralPath();
boolean cont = false;
int targetRGB = target.getRGB();
for (int xx = 0; xx < bi.getWidth(); xx++) {
for (int yy = 0; yy < bi.getHeight(); yy++) {
if (bi.getRGB(xx, yy) == targetRGB) {
if (cont) {
gp.lineTo(xx, yy);
gp.lineTo(xx, yy + 1);
gp.lineTo(xx + 1, yy + 1);
gp.lineTo(xx + 1, yy);
gp.lineTo(xx, yy);
} else {
gp.moveTo(xx, yy);
}
cont = true;
} else {
cont = false;
}
}
cont = false;
}
gp.closePath();
// construct the Area from the GP & return it
return new Area(gp);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.add(new SquaresInArea());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
here's another view for clarity
private final BasicStroke thin = new BasicStroke(1f);
private final BasicStroke thick = new BasicStroke(4f);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, this);
for (Rectangle2D[] rects : imageGrid) {
for (Rectangle2D rect : rects) {
if (imageArea.contains(rect)) {
g2.setStroke(thick);
g2.setColor(Color.GREEN);
g2.draw(rect);
} else {
g2.setStroke(thin);
g2.setColor(Color.RED);
g2.draw(rect);
}
}
}
}
Do you just want to fill it with squares - or do you want to fill it with the optimal number of squares?
An algorithm for the second is harder.
For the first just step through the image a square-size at a time. If the pixel at that point is filled then scan the full square, if it's all filled in then draw the square. If not then step to the next point.
i.e. if squares are 10*10 pixels:
for (int x=0;x<width;x+=SQUARE_SIZE) {
for (int y=0;y<height;y+=SQUARE_SIZE) {
// Now check if you can put a valid square here, if so draw it
}
}

Java draw stairs using drawRect and using inputField for more stairs

I'm a beginner whit Java experience so I hope you can help me.
I want to read the number of steps from a JTextfield. But how can you make the stairs variable?
Graphics g = textP.getGraphics();
int x = 5;
int y = 20;
int width = 10;
int height = 10;
For loop 1 - whil give a drawRect of 6 pieces
for (int i = 0; i < 6; i++) {
g.drawRect(x, y * i, width, height);
}
For loop 2 - whil give a drawRect of 5 pieces
for (int i = 1; i < 6; i++) {
g.drawRect(x + 15, y * i, width, height);
}
For loop 3 - whil give a drawRect of 4 pieces
for (int i = 2; i < 6; i++) {
g.drawRect(x + 30, y * i, width, height);
}
For loop 4 - whil give a drawRect of 3 pieces
for (int i = 3; i < 6; i++) {
g.drawRect(x + 45, y * i, width, height);
}
For loop 5 - whil give a drawRect of 2 pieces
for (int i = 4; i < 6; i++) {
g.drawRect(x + 60, y * i, width, height);
}
For loop 6 - whil give a drawRect of 1 pieces
for (int i = 5; i < 6; i++) {
g.drawRect(x + 75, y * i, width, height);
}
Output (must by an rect ipv *):
*
**
***
****
*****
******
You can do it this way.
JTextField stairs = new JTextField("Enter no. of Stairs");
String noOfStairsStr = stairs.getText();
int noOfStairs = Integer.parseInt(noOfStairsStr);
...
for (int i = 0; i < noOfStairs; i++) { // Use that in the for loop.
Are you expecting something like this
for (int i = 0,k=15; i < 6; i++) {
g.drawRect( ( x+(i*k) ), y * i, width, height);
}
A Graphic environment is complex thing. No longer do you have the safety of fixed character width and heights, now you need to start dealing with a wider range of environmental factors (such as the width and height of the area you have to paint in...)
To get start I would suggest you take a look at
Creating a GUI with Swing
Performing custom painting
2D Graphics
To cover the basics.
In order to paint steps, we need to know (at least) three things.
The number of steps to be painted...
The width of each step
The height of each step.
This example calculates the width and height of the steps as a factor of the width and height of the container it's painting on.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SimpleSteps {
public static void main(String[] args) {
new SimpleSteps();
}
public SimpleSteps() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextField steps;
private StairPane stairPane;
public TestPane() {
setLayout(new BorderLayout());
JPanel options = new JPanel();
steps = new JTextField(10);
JButton create = new JButton("Create");
stairPane = new StairPane();
options.add(new JLabel("Step count: "));
options.add(steps);
options.add(create);
add(stairPane);
add(options, BorderLayout.SOUTH);
create.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String value = steps.getText();
try {
int stepCount = Integer.parseInt(value);
stairPane.setStepCount(stepCount);
} catch (NumberFormatException exp) {
JOptionPane.showMessageDialog(TestPane.this, value + " is not a valid step count", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
}
}
public class StairPane extends JPanel {
private int stepCount = 0;
public StairPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (stepCount > 0) {
Graphics g2d = (Graphics2D) g.create();
int stepHeight = getHeight() / stepCount;
int stepWidth = getWidth() / stepCount;
for (int step = stepCount; step != 0; step--) {
int width = stepWidth * step;
int y = (stepHeight * step) - stepHeight;
g2d.fillRect(0, y, width, stepHeight);
}
g2d.dispose();
}
}
private void setStepCount(int stepCount) {
this.stepCount = stepCount;
repaint();
}
}
}

Categories