Converting Point to Button - java

Is it possible to convert from point to JButton in java, just as you convert from int to string .. Any help is acceptable, please I need help on it. Thanks!
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
import java.awt.*;
#SuppressWarnings("serial")
public class Beginner extends JPanel {
static JButton quest;
Random rand = new Random();
int n = 10;
static List <Point> points = new ArrayList<Point> ();
public Beginner() {
int radius = 200;
Point center = new Point (250, 250);
double angle = Math.toRadians(360 / n);
points.add(center);
for (int i = 0; i < n; i++) {
double theta = i * angle;
int dx = (int) (radius * Math.sin(theta));
int dy = (int) (radius * Math.cos(theta));
Point p = new Point (center.x + dx , center.y + dy);
points.add(p);
}
draw (points);
}
public void draw (List<Point> points) {
JPanel panels = new JPanel();
SpringLayout spring = new SpringLayout();
int count = 1;
for (Point point: points) {
quest = new JButton("Question " + count);
quest.setForeground(Color.BLACK);
Font fonte = new Font("Script MT Bold", Font.PLAIN, 20);
quest.setFont(fonte);
add (quest);
count++;
spring.putConstraint(SpringLayout.WEST, quest, point.x, SpringLayout.WEST, panels );
spring.putConstraint(SpringLayout.NORTH, quest, point.y, SpringLayout.NORTH, panels );
setLayout(spring);
panels.setOpaque(false);
panels.setVisible(true);
panels.setLocation(5,5);
add(panels);
quest.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent p) {
JButton source = (JButton) p.getSource();
//where the problem lies
if (source.equals(points.get(0))) {
//some action....
}
}
});
}
}
public static void main(String [] args){
JFrame frame = new JFrame();
//set JFrame properties
JButton start = new JButton ("CLick here to start");
start.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent et) {
Beginner novice = new Beginner();
//set Beginner properties (remember it extends JPanel);
}
});
} }

Probbaly you will need to add the missing lines into your code just like this, I've just tested it and it works.
Import the Point class from awt package.
Use the main method to execute your code by creating a new instance of the class.
Also you need to extend the JFrame class to be able to call the setLayout and add methods.
package javaapplication6;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.SpringLayout;
import javax.swing.JFrame;
public class Beginner extends JFrame {
Random rand = new Random();
int n = 10;
static List<Point> points = new ArrayList<Point>();
public Beginner() {
int radius = 200;
Point center = new Point(250, 250);
double angle = Math.toRadians(360 / n);
points.add(center);
for (int i = 0; i < n; i++) {
double theta = i * angle;
int dx = (int) (radius * Math.sin(theta));
int dy = (int) (radius * Math.cos(theta));
Point p = new Point(center.x + dx, center.y + dy);
points.add(p);
}
draw(points);
}
public void draw(List<Point> points) {
JPanel panels = new JPanel();
SpringLayout spring = new SpringLayout();
int count = 1;
for (Point point : points) {
JButton quest = new JButton("Question " + count);
quest.setForeground(Color.BLACK);
Font fonte = new Font("Script MT Bold", Font.PLAIN, 20);
quest.setFont(fonte);
quest.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent et) {
System.out.println(quest.getText());
//do something else
}
});
add(quest);
spring.putConstraint(SpringLayout.WEST, quest, point.x, SpringLayout.WEST, panels);
spring.putConstraint(SpringLayout.NORTH, quest, point.y, SpringLayout.NORTH, panels);
setLayout(spring);
panels.setOpaque(false);
panels.setVisible(true);
panels.setLocation(5, 5);
add(panels);
count++;
}
setSize(700, 700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Beginner();
}
}

Related

Java AWT: JFrame SetLocation should not move outside the screen

Using the four buttons, the window should be moved in four directions (north, south, east, west) and the window should not leave the screen. This works smoothly to the north and west, but unfortunately not in the other directions. I guess that the error is in the getEffectiveScreenArea method, but I am not sure.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MoveWindowGUI extends JFrame {
private JButton moveUp, moveDown, moveLeft, moveRight;
private int x, y;
public MoveWindowGUI(String title) {
super(title);
this.initializeButtons();
this.prepareWindow();
this.addActionListener();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void initializeButtons() {
this.moveUp = new JButton("U");
this.moveDown = new JButton("D");
this.moveLeft = new JButton("L");
this.moveRight = new JButton("R");
}
private void prepareWindow() {
setLayout(new BorderLayout(25, 25));
this.addComponents();
this.centerWindow();
setSize(300, 300);
}
private void centerWindow() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension windowSize = getSize();
int centralWidth = (screenSize.width - windowSize.width) / 2;
int centralHeight = (screenSize.height - windowSize.height) / 2;
setLocation(centralWidth, centralHeight);
}
private void addComponents() {
add(this.moveUp, BorderLayout.NORTH);
add(this.moveDown, BorderLayout.SOUTH);
add(this.moveLeft, BorderLayout.WEST);
add(this.moveRight, BorderLayout.EAST);
}
private void addActionListener() {
ActionListener listener = new WindowActionListener();
moveUp.addActionListener(listener);
moveDown.addActionListener(listener);
moveLeft.addActionListener(listener);
moveRight.addActionListener(listener);
}
class WindowActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("U")) {
y -= 10;
} else if (command.equals("D")) {
y += 10;
} else if (command.equals("L")) {
x -= 10;
} else if (command.equals("R")) {
x += 10;
}
this.refreshWindow();
}
private void refreshWindow() {
Point lastLocation = getLocation();
Rectangle effectiveScreenArea = getEffectiveScreenArea();
int newX = lastLocation.x + x;
int newY = lastLocation.y + y;
if (newX < effectiveScreenArea.x) {
newX = effectiveScreenArea.x;
} else if (newY < effectiveScreenArea.y) {
newY = effectiveScreenArea.y;
} else if (newX >= effectiveScreenArea.width) {
newX = effectiveScreenArea.width;
} else if (newY >= effectiveScreenArea.height) {
newY = effectiveScreenArea.height;
}
setLocation(newX, newY);
this.resetHeightAndWitdhLocally();
pack();
}
public Rectangle getEffectiveScreenArea() {
int minX = 0, minY = 0, maxX = 0, maxY = 0;
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
int screenDevices = environment.getScreenDevices().length;
for(GraphicsDevice device : environment.getScreenDevices()) {
Rectangle bounds = device.getDefaultConfiguration().getBounds();
minX = Math.min(minX, bounds.x);
minY = Math.min(minY, bounds.y);
maxX = Math.max(maxX, bounds.x + bounds.width);
maxY = Math.max(maxY, bounds.y + bounds.height);
}
return new Rectangle(minX, minY, (maxX - minX) / screenDevices, (maxY - minY) / screenDevices);
}
/*
private Rectangle getEffectiveScreenArea() {
GraphicsConfiguration graphicsConfiguration = getGraphicsConfiguration();
Rectangle bounds = graphicsConfiguration.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfiguration);
Rectangle effectiveScreenArea = new Rectangle();
effectiveScreenArea.x = bounds.x + screenInsets.left;
effectiveScreenArea.y = bounds.y + screenInsets.top;
effectiveScreenArea.height = bounds.height + screenInsets.top - screenInsets.bottom;
effectiveScreenArea.width = bounds.width - screenInsets.left - screenInsets.right;
return effectiveScreenArea;
}
*/
private void resetHeightAndWitdhLocally() {
x = 0;
y = 0;
}
}
}
I took your code and modified it somewhat. Here's the GUI I created.
I placed the JButtons on a JPanel. Then I placed the JPanel on the JFrame. Generally, it's a good idea to put Swing components on a JPanel, rather than directly on the JFrame.
I cleaned up the WindowActionListener class.
Here's the complete runnable code. I made the WindowActionListener class an inner class so I could post this code as one block.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MoveWindowGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MoveWindowGUI());
}
private JFrame frame;
#Override
public void run() {
frame = new JFrame("Move Window GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
WindowActionListener listener = new WindowActionListener(this);
JButton upButton = new JButton("Up");
upButton.addActionListener(listener);
panel.add(upButton, BorderLayout.NORTH);
JButton downButton = new JButton("Down");
downButton.addActionListener(listener);
panel.add(downButton, BorderLayout.SOUTH);
JButton leftButton = new JButton("Left");
leftButton.addActionListener(listener);
panel.add(leftButton, BorderLayout.WEST);
JButton rightButton = new JButton("Right");
rightButton.addActionListener(listener);
panel.add(rightButton, BorderLayout.EAST);
Dimension d = panel.getPreferredSize();
d.width = 300;
panel.setPreferredSize(d);
return panel;
}
public JFrame getFrame() {
return frame;
}
public class WindowActionListener implements ActionListener {
private final MoveWindowGUI view;
public WindowActionListener(MoveWindowGUI view) {
this.view = view;
}
#Override
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
int increment = 100;
switch (command) {
case "Up":
refreshWindow(0, -increment);
break;
case "Down":
refreshWindow(0, increment);
break;
case "Left":
refreshWindow(-increment, 0);
break;
case "Right":
refreshWindow(increment, 0);
break;
}
}
private void refreshWindow(int deltaX, int deltaY) {
Rectangle frameArea = view.getFrame().getBounds();
Rectangle screenArea = getEffectiveScreenArea();
int x = frameArea.x;
int y = frameArea.y;
int minX = screenArea.x;
int minY = screenArea.y;
int maxX = screenArea.width - frameArea.width;
int maxY = screenArea.height - frameArea.height;
x += deltaX;
y += deltaY;
x = Math.max(minX, x);
x = Math.min(maxX, x);
y = Math.max(minY, y);
y = Math.min(maxY, y);
view.getFrame().setBounds(new Rectangle(x, y, frameArea.width, frameArea.height));
}
private Rectangle getEffectiveScreenArea() {
int minX = 0, minY = 0, maxX = 0, maxY = 0;
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
int screenDevices = environment.getScreenDevices().length;
for (GraphicsDevice device : environment.getScreenDevices()) {
Rectangle bounds = device.getDefaultConfiguration().getBounds();
minX = Math.min(minX, bounds.x);
minY = Math.min(minY, bounds.y);
maxX = Math.max(maxX, bounds.x + bounds.width);
maxY = Math.max(maxY, bounds.y + bounds.height);
}
return new Rectangle(minX, minY, (maxX - minX) / screenDevices,
(maxY - minY) / screenDevices);
}
}
}

Java rotating a Polgon deforms it

I have written a method, which randomly generates polygon shapes, which then are rotating and moving across the screen. Since I wanted to detect collision with these shapes, I did not rotate them with Graphics2D and instead used AffineTransform to rotate them. But for some reason, certain shapes are getting messed up by the rotation, while others are unaffected. Below is an example with one of the shapes which caused problems.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class Test extends JLabel{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private static final long serialVersionUID = 1L;
Polygon poly;
Point center;
Point source[];
Point dest[];
JFrame jf;
public Test() {
init();
createPolygon();
Timer timer = new Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
rotatePoly();
repaint();
}});
timer.start();
}
public void rotatePoly() {
AffineTransform transf = AffineTransform.getRotateInstance(Math.toRadians(2), center.x, center.y);
transf.transform(source, 0, dest, 0, source.length);
poly = toPolygon(dest);
}
public Polygon toPolygon(Point[] points) {
Polygon polygon = new Polygon();
for (int i = 0; i < points.length; i++) {
polygon.addPoint(points[i].x, points[i].y);
}
return polygon;
}
public void createPolygon() {
Point points[] = new Point[7];
points[0] = new Point(20, 97);
points[1] = new Point(82, 70);
points[2] = new Point(134, 70);
points[3] = new Point(210, 88);
points[4] = new Point(210, 106);
points[5] = new Point(144, 125);
points[6] = new Point(82, 125);
source = points;
dest = points;
poly = toPolygon(points);
center = new Point(poly.getBounds().x + poly.getBounds().width / 2, poly.getBounds().y + poly.getBounds().height / 2);
}
public void init() {
setVisible(true);
setSize(260, 260);
jf = new JFrame();
jf.setVisible(true);
jf.setSize(260, 260);
jf.setContentPane(new JLabel());
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocation((screenSize.width / 2) - (getWidth() / 2), (screenSize.height / 2) - (getHeight() / 2));
jf.add(this);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.drawPolygon(poly);
}
}
If you replace the points with the following lines, the shape mostly stays the same. The shape below is of course symmetrical, however the rotate method did work with other randomly generated and uneven shapes.
points[0] = new Point(10, 130);
points[1] = new Point(100, 10);
points[2] = new Point(160, 10);
points[3] = new Point(250, 100);
points[4] = new Point(250, 160);
points[5] = new Point(160, 250);
points[6] = new Point(100, 250);
This works with your AffineTransform. It returns a transformed shape instead of modifying the coordinates. I also recommend:
JFrame.setLocationRelativeTo(null); for centering on screen.
Use RenderingHints with Antialiasing on to smooth out the graphics.
Since Polygon implements Shape, a few locations needed to be retyped.
class Text extends JLabel{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private static final long serialVersionUID = 1L;
Shape poly;
Point center;
Point source[];
Point dest[];
JFrame jf;
public static void main(String[] args) {
new Text();
}
public Text() {
init();
createPolygon();
Timer timer = new Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
rotatePoly();
repaint();
}});
timer.start();
}
public void rotatePoly() {
AffineTransform transf =
AffineTransform.getRotateInstance(Math.toRadians(2), center.x, center.y);
poly = transf.createTransformedShape(poly);
}
public Shape toPolygon(Point[] points) {
Polygon polygon = new Polygon();
for (int i = 0; i < points.length; i++) {
polygon.addPoint(points[i].x, points[i].y);
}
return polygon;
}
public void createPolygon() {
Point points[] = new Point[7];
points[0] = new Point(20, 97);
points[1] = new Point(82, 70);
points[2] = new Point(134, 70);
points[3] = new Point(210, 88);
points[4] = new Point(210, 106);
points[5] = new Point(144, 125);
points[6] = new Point(82, 125);
source = points;
dest = points;
poly = toPolygon(points);
center = new Point(poly.getBounds().x + poly.getBounds().width / 2, poly.getBounds().y + poly.getBounds().height / 2);
}
public void init() {
setVisible(true);
setSize(260, 260);
jf = new JFrame();
jf.setVisible(true);
jf.setSize(260, 260);
jf.setContentPane(new JLabel());
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocation((screenSize.width / 2) - (getWidth() / 2), (screenSize.height / 2) - (getHeight() / 2));
jf.add(this);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.draw(poly);
}
}
The problem is mostly caused by using integer coordinates for the polygon.
Instead of accumulating the rotations in the polygon itself, use a variable to hold the angle and calculate a new polygon based on the original one every time the angle is changed. The original polygon is not changed.
I tried to maintain the original code as much as possible1:
package cfh.test.sf;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class PolygonTest extends JLabel{
public static void main(String[] args) {
new PolygonTest();
}
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private static final long serialVersionUID = 1L;
Polygon poly;
Shape rotated;
Point center;
int angle = 0;
JFrame jf;
public PolygonTest() {
init();
createPolygon();
Timer timer = new Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
rotatePoly();
repaint();
}});
timer.start();
}
public void rotatePoly() {
angle += 2;
AffineTransform transf = AffineTransform.getRotateInstance(Math.toRadians(angle), center.x, center.y);
rotated = transf.createTransformedShape(poly);
}
public Polygon toPolygon(Point[] points) {
Polygon polygon = new Polygon();
for (int i = 0; i < points.length; i++) {
polygon.addPoint(points[i].x, points[i].y);
}
return polygon;
}
public void createPolygon() {
Point points[] = new Point[7];
points[0] = new Point(20, 97);
points[1] = new Point(82, 70);
points[2] = new Point(134, 70);
points[3] = new Point(210, 88);
points[4] = new Point(210, 106);
points[5] = new Point(144, 125);
points[6] = new Point(82, 125);
poly = toPolygon(points);
rotated = poly;
center = new Point(poly.getBounds().x + poly.getBounds().width / 2, poly.getBounds().y + poly.getBounds().height / 2);
}
public void init() {
setVisible(true);
setSize(260, 260);
jf = new JFrame();
jf.setVisible(true);
jf.setSize(260, 260);
jf.setContentPane(new JLabel());
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocation((screenSize.width / 2) - (getWidth() / 2), (screenSize.height / 2) - (getHeight() / 2));
jf.add(this);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.draw(rotated);
}
}
1 - instead of having an additional shape in a field, I would prefer to create the rotated shape inside paintComponent. Not sure if that conflicts with the rest of the program (e.g. calculating intersection)
Alternative, not tested: use Point2D.Float or Point2D.Double instead of Point for the coordinates.

How do I repaint every second a component?

I'm trying to create a little game where the user need to click on squares for x seconds. The square should dissapear on mouse click or after 1 sec and at the end I should display the final score he achieved. I'm having troubles making the square repaint every second.
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class RectangleDemo extends JPanel{
JLabel label;
void buildUI(Container container) {
container.setLayout(new BoxLayout(container,BoxLayout.Y_AXIS));
RectangleArea rectangleArea = new RectangleArea(this);
container.add(rectangleArea);
label = new JLabel("Click within the framed area.");
container.add(label);
//Align the left edges of the components.
rectangleArea.setAlignmentX(LEFT_ALIGNMENT);
label.setAlignmentX(LEFT_ALIGNMENT); //unnecessary, but doesn't hurt
}
public void updateLabel(Point point) {
label.setText("Click occurred at coordinate ("
+ point.x + ", " + point.y + ").");
}
//Called only when this is run as an application.
public static void main(String[] args) {
JFrame f = new JFrame();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
RectangleDemo controller = new RectangleDemo();
controller.buildUI(f.getContentPane());
f.pack();
f.setVisible(true);
}
}
class RectangleArea extends JPanel implements ActionListener{
Random rand = new Random();
int a = rand.nextInt(400);
int b = rand.nextInt(400);
Point point = new Point(a,b);
RectangleDemo controller;
Dimension preferredSize = new Dimension(500,500);
int rectWidth = 50;
int rectHeight = 50;
Timer t;
public void actionPerformed (ActionEvent e)
{
}
//final Container panou;
public RectangleArea(RectangleDemo controller) {
this.controller = controller;
t=new Timer(1000, this); t.start();
Border raisedBevel = BorderFactory.createRaisedBevelBorder();
Border loweredBevel = BorderFactory.createLoweredBevelBorder();
Border compound = BorderFactory.createCompoundBorder
(raisedBevel, loweredBevel);
setBorder(compound);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if ((point.x<=x)&&(x<=point.x+50)&&(point.y<=y)&&(y<=point.y+50))
{point=null;t.stop();}
repaint();
}
});
}
public Dimension getPreferredSize() {
return preferredSize;
}
public void paintComponent(Graphics g) {
super.paintComponent(g); //paint background
//Paint a filled rectangle at user's chosen point.
if (point != null) {
g.drawRect(point.x, point.y,
rectWidth - 1, rectHeight - 1);
g.setColor(Color.yellow);
g.fillRect(point.x + 1, point.y + 1,
rectWidth - 2, rectHeight - 2);
controller.updateLabel(point);
}
}
}
Also after I click the first square I get get this error message:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at RectangleArea$1.mousePressed(RectangleDemo.java:82)

Drawing Circles to JFrame

I'm having issues drawing some circles to my JFrame. I originally had it using the default layout and realized this was only adding the most recent circle, so I changed the layout to null, and now nothing gets drawn. I've also tried frame.setLayout(new FlowLayout()) which also doesn't draw anything. Any help would be appreciated!
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
* #author Christopher Nielson
*
*/
public class Main {
private static JFrame frame;
private static Random rand;
private static Jiggler jiggler;
private static ArrayList<JComponent> circles;
private static int fps;
public static void main(String[] args) {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setBounds(100, 100, 450, 450);
rand = new Random();
circles = new ArrayList<JComponent>();
int x = frame.getWidth();
int y = frame.getHeight();
for (int i = 0; i < Integer.parseInt(args[0]); i++) {
circles.add(new Circle(rand.nextInt(frame.getWidth()), rand.nextInt(frame.getHeight()),
rand.nextInt(frame.getWidth() / 10) + 100, rand.nextInt(frame.getHeight() / 10) + 100, null));
}
circles.forEach(current -> {
frame.add(current);
});
frame.setVisible(true);
jiggler = new Jiggler(circles, new JLabel("FPS: ")); // TODO add fps
jiggler.run();
}
}
And this is one reason you'll see us recommending time and time again to avoid using null layouts like the plague.
Having said that, your main problem is a design problem, not a layout problem, and that problem being that your Circle class shouldn't extend JComponent or any component for that matter, since if you want to draw multiple circles, you should have only one component, probably a JPanel doing the drawing, and the Circles should be logical classes, classes that have a public void draw(Graphics g) method, not component classes. You would pass the List of Circles to your drawing JPanel, and it would draw the Circles in its paintComponent method by calling the draw(g) methods of each Circle in the list.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawChit extends JPanel {
private static final int PREF_W = 900;
private static final int PREF_H = 700;
private static final int MAX_SHAPES = 30;
private List<MyShape> shapes = new ArrayList<>();
public DrawChit() {
setBackground(Color.WHITE);
for (int i = 0; i < MAX_SHAPES; i++) {
double x = (PREF_W - 100) * Math.random();
double y = (PREF_H - 100) * Math.random();
double w = 100 + (Math.random() * PREF_W) / 10;
double h = 100 + (Math.random() * PREF_H) / 10;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
float hue = (float) Math.random();
double delta = 0.3;
float saturation = (float) (Math.random() * delta + (1 - delta));
float brightness = (float) (Math.random() * delta + (1 - delta));
Color color = Color.getHSBColor(hue, saturation, brightness);
shapes.add(new MyShape(ellipse, color));
}
// we'll throw a black square in the middle!
int rectW = 200;
int rectX = (PREF_W - rectW) / 2;
int rectY = (PREF_H - rectW) / 2;
shapes.add(new MyShape(new Rectangle(rectX, rectY, rectW, rectW), Color.BLACK));
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// use anti-aliasing to make graphics smooth
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// iterate through the shapes list, filling all
for (MyShape shape : shapes) {
shape.fill(g2);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
private Point p0 = null;
private MyShape shape = null;
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// iterate *backwards* so get top-most Shape
for (int i = shapes.size() - 1; i >= 0; i--) {
if (shapes.get(i).contains(e.getPoint())) {
p0 = e.getPoint();
shape = shapes.get(i);
// move selected shape to the top!
shapes.remove(shape);
shapes.add(shape);
repaint();
return;
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (p0 != null) {
moveShape(e.getPoint());
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (p0 != null) {
moveShape(e.getPoint());
p0 = null;
shape = null;
}
}
// translates the shape
private void moveShape(Point p1) {
int deltaX = p1.x - p0.x;
int deltaY = p1.y - p0.y;
shape.translate(deltaX, deltaY);
p0 = p1;
repaint();
}
}
private static void createAndShowGui() {
DrawChit mainPanel = new DrawChit();
JFrame frame = new JFrame("Draw Chit");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MyShape {
private Path2D path = new Path2D.Double();
private Color color;
public MyShape(Shape shape, Color color) {
path.append(shape, true);
this.color = color;
}
public boolean contains(Point p) {
return path.contains(p);
}
public void draw(Graphics2D g2) {
g2.setColor(color);
g2.draw(path);
}
public void fill(Graphics2D g2) {
g2.setColor(color);
g2.fill(path);
}
public void translate(int deltaX, int deltaY) {
path.transform(AffineTransform.getTranslateInstance(deltaX, deltaY));
}
}

Getting a null pointer exception [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Getting a null pointer exception in the MouseDragged function. Been trying to figure out for days what is causing it but I don't know what. Any help would be appreciated thanks. My program is supposed to add an image file and be able to paint over it.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
import java.awt.image.BufferedImage;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.geom.*;
import java.util.Vector;
import java.util.*;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.Toolkit;
public class Lab3 {
public static void main(String[] args)
{
new Lab3Frame();
}
}
class Lab3Frame extends JFrame implements ActionListener, MouseListener, MouseMotionListener, ChangeListener
{
JFrame frame;
JPanel toolbar;
JMenuBar menuBar;
JMenu tool, file;
JLabel image;
JToggleButton b1, b2, b3, b4, bcol;
JMenuItem pencil, eraser, brush, line, open;
final JFileChooser fc = new JFileChooser();
BufferedImage img;
JColorChooser tcc;
JScrollBar hbar, vbar;
PaintPanel inkPanel;
private Point[] stroke;
public Color ink_color = Color.black;
public Stroke ink_stroke = new BasicStroke(5.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
final int MAX_SAMPLES = 500;
private int sampleCount;
//private Vector<Line2D.Double> v;
Lab3Frame(){
frame = new JFrame();
menuBar = new JMenuBar();
image = new JLabel();
tool = new JMenu("Tools");
file = new JMenu("File");
pencil = new JMenuItem("Pencil");
eraser = new JMenuItem("Eraser");
brush = new JMenuItem("Brush");
line = new JMenuItem("Line");
tool.add(pencil);
tool.add(line);
tool.add(eraser);
tool.add(brush);
open = new JMenuItem("Open");
file.add(open);
menuBar.add(file);
menuBar.add(tool);
frame.setJMenuBar(menuBar);
tcc = new JColorChooser();
inkPanel = new PaintPanel();
toolbar = new JPanel();
toolbar.setSize(100,300);
image.setBackground(Color.blue);
//TOOLBAR BUTTONS
toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.Y_AXIS));
b1 = new JToggleButton("1");
toolbar.add(b1);
b2 = new JToggleButton("2");
toolbar.add(b2);
b3 = new JToggleButton("3");
toolbar.add(b3);
b4 = new JToggleButton("4");
toolbar.add(b4);
bcol = new JToggleButton(" ");
toolbar.add(bcol);
tcc.setPreviewPanel(new JPanel());
//LISTENERS
pencil.addActionListener(this);
open.addActionListener(this);
image.addMouseMotionListener(this);
pencil.addMouseMotionListener(this);
tcc.getSelectionModel().addChangeListener(this);
inkPanel.addMouseMotionListener(this);
inkPanel.addMouseListener(this);
//hbar.addAdjustmentListener(this);
//vbar.addAdjustmentListener(this);
//tcc.addChangeListener(this);
//ADD ELEMENTS TO FRAME
frame.setSize(600, 600);
hbar = new JScrollBar(JScrollBar.HORIZONTAL, 30, 20, 0, 300);
vbar = new JScrollBar(JScrollBar.VERTICAL, 30, 40, 0, 300);
frame.setLayout(new BorderLayout());
image.setLayout(new BorderLayout());
image.setBackground(Color.white);
frame.add(toolbar, BorderLayout.WEST);
frame.add(tcc, BorderLayout.SOUTH);
frame.add(image, BorderLayout.CENTER);
frame.setGlassPane(inkPanel);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == open){
int returnVal = fc.showOpenDialog(Lab3Frame.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
try {
// frame.add(inkPanel);
img=ImageIO.read(file);
ImageIcon icon=new ImageIcon(img); // ADDED
image.setIcon(icon); // ADDED
Dimension imageSize = new Dimension(icon.getIconWidth(),icon.getIconHeight()); // ADDED
image.setPreferredSize(imageSize); // ADDED
image.setVisible(true);
//
//image.add(hbar, BorderLayout.SOUTH);
//image.add(vbar, BorderLayout.EAST);
//image.revalidate(); // ADDED
//image.repaint(); // ADDED
}
catch(IOException e1) {
e1.printStackTrace();
}
}
}
}
public void stateChanged(ChangeEvent changeEvent) {
Color customCol = tcc.getColor();
bcol.setBackground(customCol);
}
/*
AdjustmentListener adjustmentListener = new AdjustmentListener(){
public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent) {
System.out.println("Adjusted: " + adjustmentEvent.getValue());
}
};
*/
public void mouseClicked(MouseEvent me) {
int x = me.getX();
int y = me.getY();
if (SwingUtilities.isLeftMouseButton(me))
{
stroke[sampleCount] = new Point(x, y);
int x1 = (int)stroke[sampleCount - 1].getX();
int y1 = (int)stroke[sampleCount - 1].getY();
int x2 = (int)stroke[sampleCount].getX();
int y2 = (int)stroke[sampleCount].getY();
if (sampleCount < MAX_SAMPLES - 1)
++sampleCount;
// draw ink trail from previous point to current point
inkPanel.drawInk(x1, y1, x2, y2);
}
}
public void mouseEntered(MouseEvent me) {}
public void mouseExited(MouseEvent me) {}
public void mousePressed(MouseEvent me) {
int x = me.getX();
int y = me.getY();
stroke[sampleCount] = new Point(x, y);
if (sampleCount < MAX_SAMPLES - 1)
++sampleCount;
}
public void mouseDragged(MouseEvent me) {
sampleCount = 1;
int x = me.getX();
int y = me.getY();
System.out.println("y2:" + y );
if (SwingUtilities.isLeftMouseButton(me))
{
// try{
stroke[sampleCount] = new Point(x, y);
int x2 = (int)stroke[sampleCount].getX();
int y2 = (int)stroke[sampleCount].getY();
int x1 = (int)stroke[sampleCount - 1].getX();
int y1 = (int)stroke[sampleCount - 1].getY();
if (sampleCount < MAX_SAMPLES - 1){
++sampleCount;}
//draw.Line2D.
inkPanel.drawInk(x1, y1, x2, y2);
//inkPanel.repaint();
}
/*catch ( Exception err1 ) {
System.out.println( err1.getMessage( ) );
}*/
// draw ink trail from previous point to current point
// }
}
public void mouseReleased(MouseEvent me) {
}
public void mouseMoved(MouseEvent me) {
}
class PaintPanel extends JPanel
{
private Vector<Line2D.Double> v;
private final Stroke INK_STROKE = new BasicStroke(5.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
PaintPanel()
{
v = new Vector<Line2D.Double>();
this.setBackground(Color.white);
}
#Override
public void paintComponent(Graphics gd) {
super.paintComponent(gd);
paintImage(gd);
}
public void paintImage(Graphics gd){
Graphics2D g2 = (Graphics2D)gd;
//Rectangle aa = new Rectangle( 10, 10, 100, 100);
//g2.draw(aa);
g2.setColor(Color.red);
Stroke s = g2.getStroke(); // save current stroke
g2.setStroke(INK_STROKE);
for (int i = 0; i < v.size(); ++i)
g2.draw((Line2D.Double)v.elementAt(i));
g2.setStroke(s);
repaint();
}
public void drawInk(int x1, int y1, int x2, int y2)
{
// get graphics context
Graphics2D g2 = (Graphics2D)this.getGraphics();
//System.out.println("dn " + g2 + "method was called");
// create the line
Line2D.Double inkSegment = new Line2D.Double(x1, y1, x2, y2);
g2.setColor(Color.red); // set the inking color
Stroke s = g2.getStroke(); // save current stroke
g2.setStroke(INK_STROKE); // set desired stroke
g2.draw(inkSegment); // draw it!
g2.setStroke(s); // restore stroke
v.add(inkSegment); // add to vector
repaint();
}
}
}
stroke[sampleCount]
I don't see the var stroke to be allocated, so this can be your null pointer exception.
You try to use stroke but you never initialized it. Initialize that with new array!!

Categories