How to use different fill colour for specific rectangles - java

Based on the code I've used for my canvas drawing and the screenshot regarding that, I'm trying to fill a specific rectangle with a different colour but instead this unexpected behaviour occurs where other rectangles change stroke colour also. Does anyone know what can be done fix this issue?
I only want the 2nd rectangle from the the left on the top row to be filled black & stroked red whilst the other rectangles remain with a red stroke
public class Car extends View {
public Car(Context context) {
super(context);
init();
}
public Car(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Car(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
Paint paint;
private void init() {
paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(4);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int w = canvas.getWidth();
int h = canvas.getHeight();
int rectWidth = w / 5;
int space = w / 15;
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
paint.setStyle(Paint.Style.STROKE); //add this
for (int i = 0; i < 4; i++) {
int left = i * (rectWidth + space);
int right = left + rectWidth;
if (i == 1){
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
}
else{
paint.setColor(Color.RED);
}
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, paint);
paint.setStyle(Paint.Style.STROKE);//add this
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, paint);
}
}
}

I only want the 2nd rectangle from the the left on the top row to be
filled black & stroked red whilst the other rectangles remain with a
red stroke
For this in the if Case when i=1 you need to do two things
setStyle to fill and setColor to black and draw the rectangle.
Then again set back the setStyle to stroke and setColor to red and draw rect2 of yours.
Code:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int w = canvas.getWidth();
int h = canvas.getHeight();
int rectWidth = w / 5;
int space = w / 15;
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
paint.setStyle(Paint.Style.STROKE); //add this
for (int i = 0; i < 4; i++) {
int left = i * (rectWidth + space);
int right = left + rectWidth;
if (i == 1){
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, paint);
//again set back the style here
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
Rect rect2 = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect2, paint);
//this will draw the lower rectangle! Using extra variable rect3 just for safer side.
Rect rect3 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect3, paint);
}else{
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, paint);
paint.setStyle(Paint.Style.STROKE);//add this
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, paint);
}
}
}

Related

Java OpenCV Layer small image onto larger image with transparency

I am trying to write a function that overlays an image at a rectangle with transparency over top of another image, However it doesn't layer the images it just erases the section that I overlay and the transparency cuts through the entire image. Here is my code.
public static void overlayImage(String imagePath, String overlayPath, int x, int y, int width, int height) {
Mat overlay = Imgcodecs.imread(overlayPath, Imgcodecs.IMREAD_UNCHANGED);
Mat image = Imgcodecs.imread(imagePath, Imgcodecs.IMREAD_UNCHANGED);
Rectangle rect = new Rectangle(x, y, width, height);
Imgproc.resize(overlay, overlay, rect.size());
Mat submat = image.submat(new Rect(rect.x, rect.y, overlay.cols(), overlay.rows()));
overlay.copyTo(submat);
Imgcodecs.imwrite(imagePath, image);
}
EDIT: Here are some example pictures:
Before:
After:
Found this function that does exactly what I needed.
public static void overlayImage(Mat background,Mat foreground,Mat output, Point location){
background.copyTo(output);
for(int y = (int) Math.max(location.y , 0); y < background.rows(); ++y){
int fY = (int) (y - location.y);
if(fY >= foreground.rows())
break;
for(int x = (int) Math.max(location.x, 0); x < background.cols(); ++x){
int fX = (int) (x - location.x);
if(fX >= foreground.cols()){
break;
}
double opacity;
double[] finalPixelValue = new double[4];
opacity = foreground.get(fY , fX)[3];
finalPixelValue[0] = background.get(y, x)[0];
finalPixelValue[1] = background.get(y, x)[1];
finalPixelValue[2] = background.get(y, x)[2];
finalPixelValue[3] = background.get(y, x)[3];
for(int c = 0; c < output.channels(); ++c){
if(opacity > 0){
double foregroundPx = foreground.get(fY, fX)[c];
double backgroundPx = background.get(y, x)[c];
float fOpacity = (float) (opacity / 255);
finalPixelValue[c] = ((backgroundPx * ( 1.0 - fOpacity)) + (foregroundPx * fOpacity));
if(c==3){
finalPixelValue[c] = foreground.get(fY,fX)[3];
}
}
}
output.put(y, x,finalPixelValue);
}
}
}

How to add rectangles on top of existing rectangle in canvas

I'm trying to add some red rectangles within my existing canvas on top of specific boxes exactly like the expected result image but they don't appear at all as my code shows the current undesired outcome when I deploy my app. My code is to create 4 rectangles on the top row and 4 rectangles on the bottom row but I only want this to be added on top of boxes 2-6 but I know extra code needs to be added for the red rectangles on top of boxes 1 & 7. Does anyone know what I'm doing wrong and how to fix this? All help would be appreciated.
public class RectangleTextView extends View {
private final Paint mBlackPaint = new Paint();
private final Paint mRedPaint = new Paint();
private final TextPaint mTextPaint;
public RectangleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
mRedPaint.setColor(Color.parseColor("#CC3333"));
mBlackPaint.setAntiAlias(false);
mBlackPaint.setColor(Color.BLACK);
mBlackPaint.setStrokeWidth(valueInDp);
mBlackPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextSize(valueInSp);
mWindowPaint = new Paint();
mWindowPaint.setColor(Color.parseColor("#CC3333"));
mWindowPaint.setStrokeWidth(valueInDp);
}
private Paint mWindowPaint;
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (getWidth() == 0)
return;
//initialise red rectangles
int w = canvas.getWidth();
int h = canvas.getHeight();
int rectWidth = w / 5;
int space = w / 15;
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
//draw end rectangles
int mSideRectWidth = 10;
canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle
//draw grey boxes
setBackgroundColor(Color.parseColor("#808080"));
int boxWidth = (getWidth() - mSideRectWidth) / 7;
//draw text views
for (int i = 0; i < 7; i++) {
canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
}
//draw black lines
for (int i = 1; i < 7; i++) {
canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBlackPaint);
}
//draw red windows
for (int i = 0; i < 4; i++) {
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
int left = i * (rectWidth + space);
int right = left + rectWidth;
if (i == 1){
mWindowPaint.setStyle(Paint.Style.FILL); // change to this
}
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, mWindowPaint);
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mWindowPaint);
}
}
}
expected result
current undesired outcome
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.apptacularapps.car.RectangleTextView
android:layout_width="100dp"
android:layout_height="45dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:background="#808080"
android:gravity="center"/>
</RelativeLayout>
MainActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Try this:
public class RectangleTextView extends View {
private final Paint mBlackPaint = new Paint();
private final Paint mRedPaint = new Paint();
private final TextPaint mTextPaint;
public RectangleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
mRedPaint.setColor(Color.parseColor("#CC3333"));
mBlackPaint.setAntiAlias(false);
mBlackPaint.setColor(Color.BLACK);
mBlackPaint.setStrokeWidth(valueInDp);
mBlackPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextSize(valueInSp);
mWindowPaint = new Paint();
mWindowPaint.setColor(Color.parseColor("#CC3333"));
mWindowPaint.setStrokeWidth(valueInDp);
}
private Paint mWindowPaint;
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (getWidth() == 0)
return;
//initialise red rectangles
int h = canvas.getHeight();
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
//draw end rectangles
int mSideRectWidth = 10;
canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle
//draw grey boxes
setBackgroundColor(Color.parseColor("#808080"));
int boxWidth = (getWidth() - mSideRectWidth) / 7;
int redRectWidth = boxWidth / 5;
int redRectSpace = redRectWidth / 3;
//draw text views
for (int i = 0; i < 7; i++) {
canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
int baseStartX = i * boxWidth;
//draw red windows
for (int j = 0; j < 4; j++) {
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
int left = mSideRectWidth + baseStartX + (j * (redRectWidth + redRectSpace));
int right = left + redRectWidth;
if (j == 1) {
mWindowPaint.setStyle(Paint.Style.FILL); // change to this
}
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, mWindowPaint);
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mWindowPaint);
}
}
//draw black lines
for (int i = 1; i < 7; i++) {
int startX = mSideRectWidth + boxWidth * i;
int startY = 0;
int stopX = mSideRectWidth + boxWidth * i;
int stopY = getHeight();
canvas.drawLine(startX, startY, stopX, stopY, mBlackPaint);
}
}
}
the problem was that you created only 4 rectangles in the screen witdh size, not in the number cell size.
here is the code:
public class RectangleTextView extends View {
private final Paint mBlackPaint = new Paint();
private final Paint mRedPaint = new Paint();
private final TextPaint mTextPaint;
public RectangleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
mRedPaint.setColor(Color.parseColor("#CC3333"));
mBlackPaint.setAntiAlias(false);
mBlackPaint.setColor(Color.BLACK);
mBlackPaint.setStrokeWidth(valueInDp);
mBlackPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextSize(valueInSp);
mWindowPaint = new Paint();
mWindowPaint.setColor(Color.parseColor("#CC3333"));
mWindowPaint.setStrokeWidth(valueInDp);
}
private Paint mWindowPaint;
Rect rect = new Rect();
Rect rect2 = new Rect();
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (getWidth() == 0)
return;
//initialise red rectangles
int w = canvas.getWidth();
int h = canvas.getHeight();
int rectWidth = ((w - 20) / 7) / 5;
int space = ((w - 20) / 7) / 15;
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
//draw end rectangles
int mSideRectWidth = 10;
canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle
//draw grey boxes
setBackgroundColor(Color.parseColor("#808080"));
int boxWidth = (getWidth() - mSideRectWidth) / 7;
//draw text views
for (int i = 0; i < 7; i++) {
canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
}
//draw black lines
for (int i = 1; i < 7; i++) {
canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBlackPaint);
}
//draw red windows
for (int index = 0; index < 7; index++) {
if (index == 0 || index == 6) {
for (int i = 0; i < 3; i++) {
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
int left = (i * (rectWidth + space)) + (index * boxWidth) + 13 + rectWidth/2 + space/2;
int right = left + rectWidth;
rect.set(left, 0, right, topRectHeight);
canvas.drawRect(rect, mWindowPaint);
if (index == 0 && i == 1) {
mWindowPaint.setStyle(Paint.Style.FILL); // change to this
}
rect2.set(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mWindowPaint);
}
} else {
for (int i = 0; i < 4; i++) {
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
int left = (i * (rectWidth + space)) + (index * boxWidth) + 13;
int right = left + rectWidth;
rect.set(left, 0, right, topRectHeight);
canvas.drawRect(rect, mWindowPaint);
rect2.set(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mWindowPaint);
}
}
}
}
}
this is the full code perfectly working for me. if you have any question or doubt feel free to post it :)
this is how i see them:
You are drawing all of the rectangles, but it looks like you want to skip all of the "odd" rectangles - or every second rectangle... and be sure to change the color to "red" - something like this:
//draw red windows
for (int i = 0; i < 4; i++) {
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
int left = i * rectWidth;
int right = left + rectWidth;
if (i == 1){
mWindowPaint.setStyle(Paint.Style.FILL); // change to this
}
if (i % 2 == 0) {
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, mRedPaint);
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mRedPaint);
}
}
}
EDIT:
I think the "filled" rectangle on the bottom is supposed to be more like:
//draw red windows
for (int i = 0; i < 4; i++) {
int left = i * rectWidth;
int right = left + rectWidth;
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
if (i % 2 == 0) {
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, mRedPaint);
if (i == 1){
mWindowPaint.setStyle(Paint.Style.FILL); // change to this
}
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mRedPaint);
}
}
}

Drawing graphics in Java

I am trying to draw a circle in side a square and having multiple square circles in java. I am almost done but my output isn't coming out as I wanted to. The picture is what I am trying to do but it's not working out.
Here is my code:
a.awt.*;
public class SquaredCircles {
public static final int WIDTH=400;
public static final int HEIGHT=400;
public static void main (String[] args) {
DrawingPanel panel = new DrawingPanel(WIDTH,HEIGHT);
Graphics g = panel.getGraphics ();
panel.setBackground(new Color(0, 255, 255 ) );
int x = 0;
int y = 0;
int size = 100;
int rows = 5;
int numSquares = 1;
drawManySquares ( g, numSquares, x, y, size, rows );
x = 10;
y = 120;
size = 24;
rows = 4;
numSquares = 4;
drawManySquares( g, numSquares, x, y, size, rows );
x = 150;
y = 20;
size = 40;
rows = 6;
numSquares = 5;
drawManySquares( g, numSquares, x, y, size, rows );
x = 130;
y = 275;
size = 36;
rows = 3;
numSquares = 3;
drawManySquares( g, numSquares, x, y, size, rows );
}
public static void drawManySquares( Graphics g, int numSquares, int x, int y, int size, int rows ) {
for ( int i = 0; i < numSquares; i++ ) {
for ( int j = 0; j < numSquares; j++ ) {
drawOneSquare( g, x + i size, y + j size, size, rows );
}
}
}
public static void drawOneSquare( Graphics g, int x, int y, int size, int rows ) {
g.setColor ( Color.GREEN);
g.fillRect(x , y, size, size);
g.setColor ( Color.YELLOW);
g.fillOval ( x, y, size, size);
g.setColor ( Color.BLACK);
g.drawLine(size / 2, x, size / 2, size);
g.setColor ( Color.BLACK);
g.drawLine(x, size / 2, size, size / 2);
for (int i = 0; i <= rows; i = i + 1) {
g.setColor ( Color.BLACK);
g.drawOval(x + (i* (size/rows)), y+ (i*(size/rows)), size - (i*(size/rows +10 )) , size - (i*(size/rows +10)));
}
}
}
Start by having a look at Painting in AWT and Swing and Performing Custom Painting to see how painting should be done in Swing
Break down your problem into manageable chunks. The first thing you need to be able to do is paint a circle of a given size at a specific location, something like
public void paintCircleAt(Graphics2D g2d, int radius, int centerX, int centerY, Color stroke, Color fill) {
Ellipse2D.Double circle = new Ellipse2D.Double(centerX - radius, centerY - radius, radius * 2, radius * 2);
g2d.setColor(fill);
g2d.fill(circle);
g2d.setColor(stroke);
g2d.draw(circle);
}
So, this allows you to paint a circle of a given radius around the center points of x/y filled and outlined with the specified color, pretty simple.
Now, you need someway to paint a series of circles around the same center point, something like...
public void paintCirclesIn(Graphics2D g2d, int count, int radius, int centerX, int centerY, Color stroke, Color fill) {
System.out.println(radius + "; " + centerX + "; " + centerY);
int delta = radius / count;
int innerRadius = radius;
for (int index = 0; index < count; index++, innerRadius -= delta) {
paintCircleAt(g2d, innerRadius, centerX, centerY, stroke, fill);
}
}
Okay, this basically calculates the difference (delta) between each circle and the paints that many circles with that much difference in their radius from the previous one. Because of the way the painting is done, we start with the outer circle and paint in.
And finally, we need someway to paint a square and circles, something like...
public void paintCirclesInSquare(Graphics2D g2d, int count, int x, int y, int width, int height, Color squareStroke, Color squareFill, Color circleStroke, Color circleFill) {
int centerX = x + (width / 2);
int centerY = y + (height / 2);
int radius = Math.min(centerX, centerY);
Rectangle2D box = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(squareFill);
g2d.fill(box);
g2d.setColor(squareStroke);
g2d.draw(box);
paintCirclesIn(g2d, count, radius, centerX, centerY, circleStroke, circleFill);
g2d.drawLine(centerX, y, centerX, y + height);
g2d.drawLine(x, centerY, x + width, centerY);
}
This, again, simply reuses the existing code we already have and adds to it, painting the square, the circles in the square and finally the lines.
Now, from here, you could write a method which took the number of columns/rows you wanted, the x/y position to start from, the size of each of square, the number of circles you need and the colors and reuse this functionality, but I'll leave that up to you ;)
Runnable example for you to play with...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CirclesAndSquares {
public static void main(String[] args) {
new CirclesAndSquares();
}
public CirclesAndSquares() {
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 {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
int x = getWidth() / 2;
int y = getHeight() / 2;
// paintCircleAt(g2d, Math.min(x, y), y, y, Color.BLACK, Color.YELLOW);
// paintCirclesIn(g2d, 5, Math.min(x, y), x, y, Color.BLACK, Color.YELLOW);
paintCirclesInSquare(g2d, 5, 0, 0, getWidth() - 1, getHeight() - 1, Color.BLACK, Color.GREEN, Color.BLACK, Color.YELLOW);
g2d.dispose();
}
public void paintCirclesInSquare(Graphics2D g2d, int count, int x, int y, int width, int height, Color squareStroke, Color squareFill, Color circleStroke, Color circleFill) {
int centerX = x + (width / 2);
int centerY = y + (height / 2);
int radius = Math.min(centerX, centerY);
Rectangle2D box = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(squareFill);
g2d.fill(box);
g2d.setColor(squareStroke);
g2d.draw(box);
paintCirclesIn(g2d, count, radius, centerX, centerY, circleStroke, circleFill);
g2d.drawLine(centerX, y, centerX, y + height);
g2d.drawLine(x, centerY, x + width, centerY);
}
public void paintCirclesIn(Graphics2D g2d, int count, int radius, int centerX, int centerY, Color stroke, Color fill) {
System.out.println(radius + "; " + centerX + "; " + centerY);
int delta = radius / count;
int innerRadius = radius;
for (int index = 0; index < count; index++, innerRadius -= delta) {
paintCircleAt(g2d, innerRadius, centerX, centerY, stroke, fill);
}
}
public void paintCircleAt(Graphics2D g2d, int radius, int centerX, int centerY, Color stroke, Color fill) {
Ellipse2D.Double circle = new Ellipse2D.Double(centerX - radius, centerY - radius, radius * 2, radius * 2);
g2d.setColor(fill);
g2d.fill(circle);
g2d.setColor(stroke);
g2d.draw(circle);
}
}
}

Rotating Wheel with rotating icons

Now these days i am working on Rotating wheel likely attached screenshot.
I've found code from github https://github.com/R4md4c/AndroidRotaryWheelView
The difficulty is that i am not able to keep icons in vertical position during rotation of the wheel. Icons being rotated in form of its Wheel's Segment While it is required to keep them in vertical position as they are being displayed initially (as per screenshot-1).
I have to customize the following code where i need to change the Bounds for particular drawable's rect.
I find myself unable to achieve the exact calculation in the reference.
Any help would be highly appreciated.
#Override
public void onDraw(Canvas canvas) {
// set the height of Wheel childs items
canvas.scale(getWidth() / mViewRect.width(), getHeight() / 2
/ mViewRect.width(), xPosition, yPosition);
canvas.save(Canvas.MATRIX_SAVE_FLAG); // Saving the canvas and later
// restoring it so only this
// image will be rotated.
canvas.rotate((float) mRotationAngle, xPosition, yPosition);
for (int i = 0; i < mWedges.length; i++) {
Wedge f = mWedges[i];
mPaint.setColor(SEGMENT_COLOR);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(f, mPaint);
Rect rf = iconRect[i];
if ((mMenuEntries.get(i).getIcon() != 0)
&& (mMenuEntries.get(i).getLabel() != null)) {
System.out.println("the canvasd drawn ........");
// This will look for a "new line" and split into multiple lines
String menuItemName = mMenuEntries.get(i).getLabel();
String[] stringArray = menuItemName.split("\n");
mPaint.setColor(textColor);
mPaint.setStyle(Paint.Style.FILL);
// mPaint.setTextSize(textSize);
Rect rect = new Rect();
float textHeight = 0;
for (int j = 0; j < stringArray.length; j++) {
mPaint.getTextBounds(stringArray[j], 0,
stringArray[j].length(), rect);
textHeight = textHeight + (rect.height() + 3);
}
Rect rf2 = new Rect();
rf2.set(rf.left, rf.top - ((int) textHeight / 2), rf.right,
rf.bottom - ((int) textHeight / 2));
float textBottom = rf2.bottom;
for (int j = 0; j < stringArray.length; j++) {
mPaint.getTextBounds(stringArray[j], 0,
stringArray[j].length(), rect);
float textLeft = rf.centerX() - rect.width() / 2;
textBottom = textBottom + (rect.height() + 3);
mPaint.setTextSize(scalePX(8));
canvas.drawText(stringArray[j], textLeft - rect.left,
textBottom - rect.bottom, mPaint);
}
// canvas.rotate((float)mRotationAngle,
// rf.top-((int)textHeight/2), rf.bottom-((int)textHeight/2));
int index = checkSelection(canvas);
rf2 = rotaionRf(rf2, mRotationAngle);
if (i == index) {
// Puts in the Icon
Drawable drawable = getResources().getDrawable(
mMenuEntries.get(i).getIconSelected());
drawable.setBounds(rf2);
drawable.draw(canvas);
} else {
// Puts in the Icon
Drawable drawable = getResources().getDrawable(
mMenuEntries.get(i).getIcon());
drawable.setBounds(rf2);
drawable.draw(canvas);
}
// Icon Only
} else if (mMenuEntries.get(i).getIcon() != 0) {
System.out.println("the canvasd drawn ELSE........");
// Puts in the Icon
Drawable drawable = getResources().getDrawable(
mMenuEntries.get(i).getIconSelected());
drawable.setBounds(rf);
drawable.draw(canvas);
// Text Only
} else {
// Puts in the Text if no Icon
mPaint.setColor(this.textColor);
/*
* if (f != enabled && Wedge2Shown == true) {
* mPaint.setAlpha(disabledAlpha); } else {
* mPaint.setAlpha(textAlpha); }
*/
// mPaint.setAlpha(textAlpha);
mPaint.setStyle(Paint.Style.FILL);
// mPaint.setTextSize(textSize);
// This will look for a "new line" and split into multiple lines
String menuItemName = mMenuEntries.get(i).getLabel();
String[] stringArray = menuItemName.split("\n");
// gets total height
Rect rect = new Rect();
float textHeight = 0;
for (int j = 0; j < stringArray.length; j++) {
mPaint.getTextBounds(stringArray[j], 0,
stringArray[j].length(), rect);
textHeight = textHeight + (rect.height() + 3);
}
float textBottom = rf.centerY() - (textHeight / 2);
for (int j = 0; j < stringArray.length; j++) {
mPaint.getTextBounds(stringArray[j], 0,
stringArray[j].length(), rect);
float textLeft = rf.centerX() - rect.width() / 2;
textBottom = textBottom + (rect.height() + 3);
canvas.drawText(stringArray[j], textLeft - rect.left,
textBottom - rect.bottom, mPaint);
}
// canvas.drawTextOnPath(text, path, hOffset, vOffset, paint)
// canvas.rotate((float)mRotationAngle, xPosition, yPosition );
// canvas.drawRect(rf, mPaint);
}
// canvas.restore();
}
// canvas.restore();
canvas.restore();
// System.out.println()
canvas.save();
canvas.restore();
mPaint.setShader(mShader);
// mPaint.setAlpha(0x66);
// Draw the Selection Segment
if (mSelectionWedge != null) {
canvas.drawPath(mSelectionWedge, mPaint);
// canvas.drawRect(mSelectionWedge.getWedgeRegion().getBounds(),
// mPaint);
}
mPaint.setShader(null);
int index = checkSelection(canvas);
System.out.println("the index=====" + index);
if (checkSelection(canvas) != -1) {
}
}
on using canvas.rotate u have to make sure the x&y values u give it are the MAIN wheel center.

Cannot draw canvas with desired Bitmap after OnTouchEvent

I am making a tictactoe android application . After making on customview called TicTacToeGFX I tried to make an onTouchEvent which (after taking into account) the coordinates of the touch , it would fill the corresponding rectangle with the bitmap circle or cross. The Problem is that in the onTouchEvent I cannot redraw the canvas with the desired Bitmap. So my question is How to I re-draw a canvas after an onTouchEvent?
public class NewGame extends Activity {
TicTacToeGFX Game;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Game = new TicTacToeGFX(this);
setContentView(Game);
}
}
public class TicTacToeGFX extends View {
int x, y;
int rectanglescounter = 0;
public Rect[] rectangles = new Rect[9];
// BitMap
Bitmap cross = BitmapFactory.decodeResource(getResources(),
R.drawable.cross1);
Bitmap circle = BitmapFactory.decodeResource(getResources(),
R.drawable.circle1);
Bitmap empty = BitmapFactory.decodeResource(getResources(),
R.drawable.empty1);
Paint paint = new Paint();
Canvas canvas = new Canvas();
public TicTacToeGFX(Context context) {
super(context);
setFocusable(true);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// -------------------------------------------calculate
// screen------------------------------------------------------
x = (int) ((getWidth()) / 3);
y = (int) ((getHeight()) / 3);
// //------------------------------------------- calculate rectangle
// positions on
// screen------------------------------------------------------
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rectangles[rectanglescounter] = new Rect((x * j), (y * i),
((x * j) + x), ((y * i) + y));
if (rectanglescounter < 8)
rectanglescounter++;
else
break;
}
}
// ------------------------------------------- draw the canvas with
// empty Bitmap
// ------------------------------------------------------
int counter = 0;
canvas.drawRGB(0, 0, 0);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
canvas.drawBitmap(empty, null, rectangles[counter], null);
counter++;
}
}
// ------------------------------------------- draw
// LinesS------------------------------------------------------
paint.setColor(Color.WHITE);
canvas.drawLine(x, 0, x, 3 * y, paint);// 1h
canvas.drawLine(2 * x, 0, 2 * x, 3 * y, paint);// 2h
canvas.drawLine(0, y, 3 * x, y, paint);// 3h
canvas.drawLine(0, 2 * y, 3 * x, 2 * y, paint);// 4h
}
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
x = (int) event.getX();
y = (int) event.getY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getContext(), "Hello", 1).show();
canvas.drawRGB(0, 0, 0);
invalidate();
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
// move the balls the same as the finger
break;
}
return true;
}
}

Categories