Why cant I draw a rectangle with fillPolygon() - java

I am learning Java graphics. I am trying to draw simple figures. However I noticed that the following code won't draw properly:
public class Draw extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
int[] xpoints = new int[] { 20, 50, 80 };
int[] ypoints = new int[] { 40, 10, 40 };
g.fillPolygon(xpoints, ypoints, 3);
int[] recXp = new int[] { 20, 80, 20, 80 };
int[] recYp = new int[] { 50, 60, 50, 60 };
g.fillPolygon(recXp, recYp, 4);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Draw panel = new Draw();
frame.add(panel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
}
}
In order to achieve what I want I have to use
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Draw extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
int[] xpoints = new int[] { 20, 50, 80 };
int[] ypoints = new int[] { 40, 10, 40 };
g.fillPolygon(xpoints, ypoints, 3);
g.fillRect(20, 50, 60, 10);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Draw panel = new Draw();
frame.add(panel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
}
}
Why is this happening? Am I missing something? Sorry if this is a trivial question, I am just trying to understand Java better.

int[] recXp = new int[] { 20, 80, 20, 80 };
int[] recYp = new int[] { 50, 60, 50, 60 };
You only have two sets of points.
You need 4 different sets of point. One for each corner of the Rectangle.
Something like:
top/left (20, 50)
top/right (x is different from above, y is the same)
bottom/right (x is same as above, y is different.
bottom/left (x is same as first, y is save as above)

Related

Blink boxes in sequence

I changed a program (see below) I nabbed and have managed to get it to do some of what I want. I need a number of rows/bands/stripes of 3 to blink in sequence. If you could imagine three sets of three vertical bars/bands and each bar numbered 1-3. I want to get each band/bar numbered 1 of each group to blink. So all bands numbered 1 blinks for a finite time, then bands numbered 2, then 3 then repeat. So when looking at it it looks like vertical stripes blinking 1,2,3,1,2,3 etc.
What's set out below and what I have described as boxes below refers to the bands I am talking about
class BelishN {
private Timer timer;
public class Drawing extends JPanel {
private int x = 125;// Not required - it was for the ball!
private int y = 80;
private boolean changeColors = false;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//creating the shapes
Rectangle box1 = new Rectangle(1, 1, 10, 770);
//Rectangle box2 = new Rectangle(165, 225, 20, 45);
Rectangle box3 = new Rectangle(10, 1, 10, 770);
//Rectangle box4 = new Rectangle(165, 315, 20, 45);
Rectangle box5 = new Rectangle(20, 1, 10, 770);
// Rectangle box6 = new Rectangle(165, 405, 20, 45);
//drawing the shapes
//Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 100, 100);
//g2.draw(ball);
g2.draw(box1);
//g2.draw(box2);
//g2.draw(box3);
//g2.draw(box4);
//g2.draw(box5);
//g2.draw(box6);
//coloring the shapes
g2.setColor(Color.BLACK);
g2.fill(box1);
g2.fill(box3);
g2.fill(box5);
g2.setColor(Color.ORANGE);
//g2.fill(ball);
changeColors = !changeColors;
if (changeColors) {
g2.setColor(Color.white);
//g2.fill(new Ellipse2D.Double(x, y, 100, 100));
g2.fill(box1 = new Rectangle(1, 1, 10, 770));//3 vertical bands are flashing together
g2.fill(box3 = new Rectangle(10, 1, 10, 770));
g2.fill(box5 = new Rectangle(20, 1, 10, 770));
}
}
public void changeColors() {
changeColors = true;
repaint();
}
}
public BelishN() {
//Creation of frame
JFrame frame = new JFrame();
frame.setSize(800, 770); //Screen size
frame.setTitle("Belisha Beacon");
frame.setLayout(new BorderLayout(0, 0));
final Drawing shapes = new Drawing();
timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
shapes.repaint();
}
});
JButton jbtFlash = new JButton("Flash");
jbtFlash.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
final JButton jbtSteady = new JButton("Steady");
jbtSteady.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
//Positioning
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new GridLayout(1, 2, 0, 0));
controlPanel.add(jbtFlash);
controlPanel.add(jbtSteady);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.add(shapes);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// in last line here, start the timer:
timer.start();
}
public static void main(String[] args) {
new BelishN();
}
}

AffineTransform: how to scale only one shape Triangle

I have this code:
import javax.swing.*;
import java.awt.*;
public class Test {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
class MyCanvas extends JComponent {
public void paint(Graphics g) {
g.drawRect (10, 10, 100, 100);
Polygon triangle = new Polygon(new int[] {100, 150, 200}, new int[] {200, 100, 200}, 3);
g.drawPolygon(triangle);
}
}
It draws this:
I want to scale only Triangle, so it becomes thrice is big:
I understand that I need to use AffiniteTransform, but I don't understand how.
I only know that I need the scaling instance:
AffineTransform at = AffineTransform.getScaleInstance(3, 3);
All answers I've seen were very confusing or just used g2d.setTransform(at) which doesn't seem to be what I need, seeing as the square is supposed to stay the same size.
EDIT: And how do I scale a Triagle, while keeping its leftmost coordinate at the same location? (leftmost (x,y) stays the same)
New code:
public class Test {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
class MyCanvas extends JComponent {
public void paint(Graphics g) {
g.drawRect (10, 10, 100, 100);
Polygon triangle = new Polygon(new int[] {100, 150, 200}, new int[] {200, 100, 200}, 3);
AffineTransform at = AffineTransform.getScaleInstance(1.5, 1.5);
((Graphics2D) g).setTransform(at);
g.drawPolygon(triangle);
((Graphics2D) g).setTransform(AffineTransform.getScaleInstance(1,1));
validate();
}
}
gives this:
The triangle shifts as it gets scaled.
Is it possible to keep the triangle at the same spot - that is to keep its leftmost bottom corner at the same spot?

Drawing a Triangle Component using pen operation

How to do it? I mean, I can do it for Ellipse, but not sure about triangle.
You can use a Polygon.
int[] xPoints = {0, 0, 30};
int[] yPoints = {0, 30, 30};
Shape s = new Polygon(xPoints, yPoints, 3);
g2d.fill(s);
This doesn't answer your current question.
It demonstrates why you should NOT use panel.getGraphics() to do your painting. Painting done with the getGraphics() method is not permanent.
Try minimizing or maximizing the frame and see what happens to the painting:
import java.awt.*;
import javax.swing.*;
public class SSCCE2
{
private static void createAndShowGUI()
{
final JPanel panel = new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillOval(0, 0, 50, 50);
}
};
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setLocationByPlatform( true );
frame.setSize(300, 300);
frame.setVisible( true );
Graphics g = panel.getGraphics();
g.setColor(Color.RED);
g.fillOval(100, 100, 50, 50);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Graphics g = panel.getGraphics();
g.setColor(Color.RED);
g.fillOval(100, 100, 50, 50);
}
});
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

Java battleship game starting point trouble

Im making a fully graphical battleship game that will eventually allow 2 players to play over a network, but im having trouble figuring out how to assign coordinates to each square on the grid, and how to let the players select where they want to place a ship. Ive made ships as .PNG's all being the corresponding length in pixels to match the 100x100 squares. (ie) carrier would take 5 squares. Lastly, can i make a small popup window that asks where the want to place a ship for each turn? The code i have is pretty small for now, Its just starting but i need a bit of help getting it going. Any help is appreciated.
package Battleshiponline;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Board extends JPanel implements ActionListener {
private Timer timer;
public Board() {
//addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.BLUE);
setDoubleBuffered(true);
timer = new Timer(5, this);
timer.start();
String[] rowA = new String[] {"A1","A2","A3","A4","A5","A6","A7","A8","A9","A10"};
String[] rowB = new String[] {"B1","B2","B3","B4","B5","B6","B7","B8","B9","B10"};
String[] rowC = new String[] {"C1","C2","C3","C4","C5","C6","C7","C8","C9","C10"};
String[] rowD = new String[] {"D1","D2","D3","D4","D5","D6","D7","D8","D9","D10"};
String[] rowE = new String[] {"E1","E2","E3","E4","E5","E6","E7","E8","E9","E10"};
String[] rowF = new String[] {"F1","F2","F3","F4","F5","F6","F7","F8","F9","F10"};
String[] rowG = new String[] {"G1","G2","G3","G4","G5","G6","G7","G8","G9","G10"};
String[] rowH = new String[] {"H1","H2","H3","H4","H5","H6","H7","H8","H9","H10"};
String[] rowI = new String[] {"I1","I2","I3","I4","I5","I6","I7","I8","I9","I10"};
String[] rowJ = new String[] {"J1","J2","J3","J4","J5","J6","J7","J8","J9","J10"};
}
boolean inGame;
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
//vert lines(1-10)
g2d.drawLine(100, 1000, 100, 0);
g2d.drawLine(200, 1000, 200, 0);
g2d.drawLine(300, 1000, 300, 0);
g2d.drawLine(400, 1000, 400, 0);
g2d.drawLine(500, 1000, 500, 0);
g2d.drawLine(600, 1000, 600, 0);
g2d.drawLine(700, 1000, 700, 0);
g2d.drawLine(800, 1000, 800, 0);
g2d.drawLine(900, 1000, 900, 0);
g2d.drawLine(1000, 1000, 1000, 0);
// horizontal lines(A-J)
g2d.drawLine(0, 100, 1100,100);
g2d.drawLine(0, 200, 1100, 200);
g2d.drawLine(0, 300, 1100, 300);
g2d.drawLine(0, 400, 1100, 400);
g2d.drawLine(0, 500, 1100, 500);
g2d.drawLine(0, 600, 1100, 600);
g2d.drawLine(0, 700, 1100, 700);
g2d.drawLine(0, 800, 1100, 800);
g2d.drawLine(0, 900, 1100, 900);
Toolkit.getDefaultToolkit().sync();
}
public void actionPerformed(ActionEvent e) {
repaint();
}
/* private class TAdapter extends KeyAdapter {
public void keyReleased(KeyEvent e) {
.keyReleased(e);
}
public void keyPressed(KeyEvent e) {
.keyPressed(e);
}
*/
Firstly, I would advise against making your grid squares 100x100 pixels, as that would result in a grid that is 1000 x 1000, which is too tall for many screens. For your gid, consider using a GridLayout which each cell a JButton. Here is a demo to see how it may look:
public class GridTest extends JPanel implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("Grid Test");
frame.add(new GridTest());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private void init() {
GridLayout layout = new GridLayout(10, 10);
setLayout(layout);
for (char row = 'A'; row <= 'J'; row++) {
for (int col = 1; col <= 10; col++) {
JButton button = new JButton("" + row + col);
button.setMargin(new Insets(0, 0, 0, 0));
button.setPreferredSize(new Dimension(50, 50));
button.addActionListener(this);
add(button);
}
}
}
public GridTest() {
init();
}
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, String.format("You pressed %s!", e.getActionCommand()),
"You Pressed a Button", JOptionPane.INFORMATION_MESSAGE);
((JButton) e.getSource()).setEnabled(false);
}
}
I would recommend looking up Swing and looking to all the components to get an understanding of what each can do. Oracle's Tutorial is a good place to start

Rectangle object using two-dimensional array

If i have a two-dimensional array, is it possible to print out the result as a rectangle?
Here is what i have come up with;
int[][] anArrayRectangle = {{0,0},{-2,0},{1,-2},
{0,1},{2,1},{2,0}};
Each point represents one out of six points which together create a rectangle in the unit circle.
The question is if it is possible to display the rectangle in lines, not exclusively using the print method. Perhaps in an applet?
All tips are welcome.
Maybe you could use drawPolygon
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rectangle extends JPanel {
private int xPos[] = {100, 150, 200, 200, 150, 100};
private int yPos[] = {100, 100, 100, 150, 150, 150};
public void paint(Graphics g) {
super.paint(g);
int length = xPos.length;
g.drawPolygon(xPos, yPos, length);
}
private static JFrame frame = null;
public static void main(String[] args) {
frame = new JFrame("Graphics");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
Rectangle obj = new Rectangle();
frame.add(obj);
}
}

Categories

Resources