I'm making a basic bubble shooter game to practice my coding and I am trying to make the pointer so that it will aim where I want it to shoot, I have the line movement to follow my mouse but it extends one it gets further away from the center. I want to turn almost like there is a pivot point.
public static void pointer(Graphics g) {
g = panel.getGraphics();
g.drawLine(325, 530, x, 450);
g.fillRect(325, 530, x, 450);
}
public static void UI() {
frame = new JFrame("Bubble shooter");
panel = new JPanel();
panel.setBackground(Color.white);
panel.setLayout(null);
frame.setSize(650,550);
frame.setResizable(false);
frame.setVisible(true);
//frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
mouseMoving = true;
x = e.getX();
System.out.println("X: " + e.getX());
System.out.println("Y: " + e.getY());
}
});
I am trying to make the line follow my mouse without growing or shrinking onto a pivot point. Instead, the line doesn't pass the set y coordinate but extends to follow the mouse.
You have some errors in your code:
You need to add panel to frame.
You need to call your drawing method.
You need to set color while drawing.
You should calculate first point by current size of your panel instead of constant point.
Here is a working code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MouseTest {
int x = -1;
int y = -1;
public void pointer(Graphics g) {
if (x < 0) {
return;
}
g.setColor(Color.BLUE);
Rectangle bounds = g.getClipBounds();
int startX = (int) (bounds.getWidth() / 2);
int startY = (int) bounds.getHeight();
g.drawLine(startX, startY, x, y);
}
public void UI() {
JFrame frame = new JFrame("Bubble shooter");
JPanel panel = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
pointer(g);
}
};
panel.setBackground(Color.white);
panel.setLayout(null);
frame.setSize(650,550);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(panel);
frame.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
x = e.getX();
y = e.getY();
panel.repaint();
}
});
}
public static void main(String[] args) {
MouseTest mouseTest = new MouseTest();
mouseTest.UI();
}
}
Related
I want to have a text field to input an integer, then select 1) Grow or 2) Shrink, and then click the button so that the circle gets redrawn on the screen based on the selected options.
I don't know why it isn't repaining. (Don't worry about the layout, just want to get it to work first)
My Frame:
public class Main {
public static void main(String[] args) {
var frame = new JFrame();
frame.setSize(400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
var circleComp = new circleComponent();
var panel1 = new JPanel();
var multiplierLabel = new JLabel("Grow Multiplier");
var multiplierField = new JTextField(20);
var radio1 = new JRadioButton("Grow Circle");
var radio2 = new JRadioButton("Shrink Circle");
var bg = new ButtonGroup();
bg.add(radio1);
bg.add(radio2);
JButton button = new JButton("Rivizato");
button.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(radio1.isSelected()){
rrComp.repaint(0,0,Integer.parseInt(multiplierField.getText())*rrComp.getWidth(), Integer.parseInt(multiplierField.getText())*rrComp.getHeight());
}
else if(radio2.isSelected()){
rrComp.repaint(0,0,Integer.parseInt(multiplierField.getText())/rrComp.getWidth(), Integer.parseInt(multiplierField.getText())/rrComp.getHeight());
}
}
}
);
panel1.add(multiplierLabel);
panel1.add(multiplierField);
panel1.add(button);
panel1.add(radio1);
panel1.add(radio2);
frame.add(panel1);
frame.add(circleComp);
}
}
My CircleComponent class:
public class CircleComponent extends JComponent {
public void paintComponent(Graphics g){
super.paintComponent(g);
var g2 = (Graphics2D) g;
var circle = new Ellipse2D.Double(0,0,100,100);
g2.draw(circle);
}
}
var circle = new Ellipse2D.Double(0,0,100,100); means that your circle will never change size.
You should also be careful with repaint(x, y, width, height) as it could leave regions of your component "dirty". Better to just use repaint.
As a conceptual example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
private CirclePane circlePane;
public MainPane() {
setLayout(new BorderLayout());
JPanel actionsPane = new JPanel(new GridBagLayout());
JButton growButton = new JButton("Grow");
growButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
circlePane.grow();
}
});
JButton shrinkButton = new JButton("Shrink");
shrinkButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
circlePane.shrink();
}
});
actionsPane.add(growButton);
actionsPane.add(shrinkButton);
circlePane = new CirclePane();
add(circlePane);
add(actionsPane, BorderLayout.SOUTH);
}
}
public class CirclePane extends JPanel {
private Ellipse2D circle;
public CirclePane() {
circle = new Ellipse2D.Double(0, 0, 100, 100);
}
public void grow() {
double width = circle.getWidth() + 10;
double height = circle.getHeight() + 10;
circle.setFrame(0, 0, width, height);
repaint();
}
public void shrink() {
double width = Math.max(0, circle.getWidth() - 10);
double height = Math.max(0, circle.getHeight() - 10);
circle.setFrame(0, 0, width, height);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double x = (getWidth() - circle.getWidth()) / 2d;
double y = (getHeight() - circle.getHeight()) / 2d;
g2d.translate(x, y);
g2d.draw(circle);
g2d.dispose();
}
}
}
nb: I know I've not used JTextField to specify the size of the circle, that's on purpose. You will need to adapt your requirements to work in a similar way - can you see where you might pass parameters to the CirclePane?
I am practicing to draw a ball in the Panel and show the ball's coordinate when the ball is dragged.
This is my first time to practice a drawing exercise(?)
This is my code.
import java.awt.*;
import java.awt.event.*;
public class MovingBall extends Frame {
Panel ballPanel = new Panel();
Label ballLabel = new Label();
Panel coordinatePanel = new Panel();
Label coordinateLabel = new Label();
int x0=0,y0 =0, x=20,y=30;
int nowX, nowY;
Label nowXcoordinateLabel = new Label("Now X :"+nowX);
Label nowYcoordinateLabel = new Label("Now Y :"+nowY);
MovingBall(){
setLayout(new GridLayout(1,1));
ballPanel.add(ballLabel); coordinatePanel.add(coordinateLabel);
add(ballPanel);
add(coordinatePanel);
ballPanel.setBackground(Color.white);
coordinatePanel.setBackground(Color.LIGHT_GRAY);
nowXcoordinateLabel.setBackground(Color.WHITE);
nowYcoordinateLabel.setBackground(Color.WHITE);
coordinatePanel.add(nowXcoordinateLabel);
coordinatePanel.add(nowYcoordinateLabel);
setVisible(true);
setSize(400,400);
MouseMotionListener ml = new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
Point p = new Point();
nowX = (int) p.getX();
nowY = (int) p.getY();
}
};
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
dispose();
}
}
);
}
public void paintComponent(Graphics2D gg){
// super.paintComponents(gg);
ballPanel.paintComponents(gg);
gg.setColor(Color.BLUE);
gg.fillOval(x0, y0, 10, 10);
}
public static void main(String[]arg){
MovingBall mb = new MovingBall();
}
}
I have two problems
I used fillOval and paintComponent to draw and display a ball but I don't see that on the screen. Why?
Any idea how to move the ball if I want to move that using mouseDragged? Do I need some thread?
Let's start with
Frame doesn't have a paintComponent method, so nothing is ever going to call it.
Even if it did, position 0x0 would paint the circle under the frame's borders, so you wouldn't see it
You should be getting the Point from the MouseEvent, not from the new Point object you've created
It's not the responsibility of the frame to manage the mouse dragged or painting, the frame is responsible for providing the initial container onto which everything else added
From that, you should move the functionality of the painting and mouse dragged management to it's own class. This provides you with two things, first, a surface onto which you can paint, and which will contained within the frame borders and the mouse events will automatically be converted to the panels context (0x0 will be the top left corner of the panel)
This raises the question about how to update the labels. Well, you could take a leaf from the AWT API and use a simple observer pattern to generate events when the coordinates are changed, for example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
public class MovingBall extends Frame {
BallPane ballPanel = new BallPane();
Label ballLabel = new Label();
int x0 = 0, y0 = 0, x = 20, y = 30;
int nowX, nowY;
Label nowXcoordinateLabel = new Label("Now X :" + nowX);
Label nowYcoordinateLabel = new Label("Now Y :" + nowY);
MovingBall() {
setLayout(new BorderLayout());
ballPanel.add(ballLabel);
add(ballPanel);
ballPanel.setBackground(Color.white);
nowXcoordinateLabel.setBackground(Color.WHITE);
nowYcoordinateLabel.setBackground(Color.WHITE);
setVisible(true);
setSize(400, 400);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
dispose();
}
});
Panel coordinates = new Panel(new FlowLayout());
coordinates.add(nowXcoordinateLabel);
coordinates.add(nowYcoordinateLabel);
coordinates.setBackground(Color.LIGHT_GRAY);
add(coordinates, BorderLayout.SOUTH);
ballPanel.addCoordinateListene(new CoordinateListener() {
#Override
public void coordinatesChanged(CoordinateEvent evt) {
nowXcoordinateLabel.setText("Now X: " + evt.getCoordinate().getX());
nowYcoordinateLabel.setText("Now X: " + evt.getCoordinate().getY());
revalidate();
repaint();
}
});
}
public static void main(String[] arg) {
MovingBall mb = new MovingBall();
}
public class CoordinateEvent extends EventObject {
private final Point p;
public CoordinateEvent(Object source, Point p) {
super(source);
this.p = p;
}
public Point getCoordinate() {
return p;
}
}
public interface CoordinateListener {
public void coordinatesChanged(CoordinateEvent evt);
}
public class BallPane extends Panel {
int x0 = 0, y0 = 0, x = 20, y = 30;
private List<CoordinateListener> coordinateListeners;
public BallPane() {
MouseMotionListener ml = new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
x0 = (int) e.getX();
y0 = (int) e.getY();
fireCoordinateChange(new Point(e.getPoint()));
repaint();
}
};
addMouseMotionListener(ml);
coordinateListeners = new ArrayList<>(5);
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.BLUE);
g.fillOval(x0, y0, 10, 10);
}
public void addCoordinateListene(CoordinateListener listener) {
coordinateListeners.add(listener);
}
public void removeCoordinateListene(CoordinateListener listener) {
coordinateListeners.remove(listener);
}
protected void fireCoordinateChange(Point p) {
CoordinateEvent evt = new CoordinateEvent(this, p);
for (CoordinateListener listener : coordinateListeners) {
listener.coordinatesChanged(evt);
}
}
}
}
Make your class extending Panel and make it ready to drawing with overriding paint method and add the MouseMotionListener to listining your panel.Get X and Y coordinates for using in paint method, at last add your drawing panel to Frame.
Simple code : UPDATED
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestClass extends Panel {
/**
*
*/
private static final long serialVersionUID = 1L;
Panel ballPanel = new Panel();
Label ballLabel = new Label();
Panel coordinatePanel = new Panel();
Label coordinateLabel = new Label();
int nowX, nowY;
Label nowXcoordinateLabel = new Label("Now X :");
Label nowYcoordinateLabel = new Label("Now Y :");
TestClass() {
coordinatePanel.add(coordinateLabel);
nowXcoordinateLabel.setBackground(Color.WHITE);
nowYcoordinateLabel.setBackground(Color.WHITE);
nowXcoordinateLabel.setPreferredSize(new Dimension(100, 25));
nowYcoordinateLabel.setPreferredSize(new Dimension(100, 25));
coordinatePanel.setPreferredSize(new Dimension(400, 30));
coordinatePanel.setBackground(Color.LIGHT_GRAY);
coordinatePanel.add(nowXcoordinateLabel);
coordinatePanel.add(nowYcoordinateLabel);
MouseAdapter ml = new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
nowXcoordinateLabel.setText("Now X :" + e.getX());
nowYcoordinateLabel.setText("Now Y :" + e.getY());
nowX = e.getX();
nowY = e.getY();
repaint();
super.mouseMoved(e);
}
};
setLayout(new GridLayout(1, 1));
setBackground(Color.WHITE);
addMouseMotionListener(ml);
setVisible(true);
setSize(400, 400);
}
#Override
public void paint(Graphics g) {
Graphics2D gg = (Graphics2D) g;
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gg.setColor(Color.BLUE);
gg.fillOval(nowX, nowY, 20, 20);
}
public static void main(String[] arg) {
TestClass mb = new TestClass();
Frame frame = new Frame("Test drawing");
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
frame.dispose();
super.windowClosing(e);
}
});
frame.setLayout(new GridLayout(1, 1));
frame.add(mb);
frame.add(mb.coordinatePanel);
frame.setSize(800, 600);
frame.setVisible(true);
}
}
To get the position of the mouse instead of:
nowX = (int) p.getX();
Write this:
nowX = (int) e.getX();
You also need to redraw the oval every time the user triggers a Mouse Drag event
This is my main class:
public class Sad {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sad window = new Sad();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sad() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 512, 399);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new CardLayout(0, 0));
JPanel panel = new JPanel();
frame.getContentPane().add(panel, "name_12361565901507");
panel.setLayout(null);
JButton btnNes = new JButton("Nes");
btnNes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Grafik grafik = new Grafik(20, 20, 100);
panel.add(grafik);
}
});
btnNes.setBounds(90, 146, 89, 23);
panel.add(btnNes);
}
}
And this is drawing class
public class Grafik extends JPanel{
private int x;
private int y;
private int r;
public Grafik(int x, int y, int r){
this.x = x;
this.y = y;
this.r = r;
}
public void paintComponent(Graphics g) {
Graphics2D g2 =(Graphics2D) g;
Ellipse2D circ = new Ellipse2D.Float(x, y, r, r);
g2.setColor(Color.RED);
g2.draw(circ);
}
}
They are in same package. And when i click button its suposed to draw Ellipse in red color, but it doesn't show anything. Can someone help me? BTW Sorry for bad english
It's because you don't call panel.setBounds(), revalidate() and repaint().
But you shouldn't use a null layout anyway: Use layout
managers.
You should call super.paintComponent(g) at the beginning of
the paintComponent method.
Rather than adding a new component to the panel after every button press you might want to just toggle a boolean value inside the Grafik instance which determines wheter the ellipse should be visible or not.
If you want the ellipse to be "smooth", you can call g2.setRenderingHint(hintKey, hintValue).
Modified code including my suggestions:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Sad {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sad window = new Sad();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sad() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 512, 399);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Grafik grafik = new Grafik(20, 20, 100);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(grafik);
JButton btnNes = new JButton("Nes");
btnNes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
grafik.setEllipseVisible(true);
panel.repaint();
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(btnNes);
panel.add(btnPanel, BorderLayout.SOUTH);
frame.setContentPane(panel);
}
}
class Grafik extends JPanel {
private int x;
private int y;
private int r;
private boolean ellipseVisible;
public Grafik(int x, int y, int r) {
this.x = x;
this.y = y;
this.r = r;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (isEllipseVisible()) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Ellipse2D circ = new Ellipse2D.Float(x, y, r, r);
g2.setColor(Color.RED);
g2.draw(circ);
}
}
public boolean isEllipseVisible() {
return ellipseVisible;
}
public void setEllipseVisible(boolean ellipseVisible) {
this.ellipseVisible = ellipseVisible;
}
}
So I am trying to create a simple paint program and I have been having a problem. The program has a window, on the left of the window is a bar with pen size control, and the rest of the window is the drawing pane. However, whenever I draw on the pane, the side bar is basically copied onto the pane, but it can be drawn over.
Here is my CHPaint class (main):
package paint;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CHPaint{
JFrame frame;
JLabel penSizeLabel;
PaintPanel panel;
JButton upButton;
JButton downButton;
JPanel left;
JPanel main;
int penSize = 1;
public static void main(String[] args){
CHPaint gui = new CHPaint();
System.out.println("gui built");
gui.go();
}
public void go() {
frame = new JFrame("Caleb's Paint");
panel = new PaintPanel();
upButton = new JButton("Up");
downButton = new JButton("Down");
penSizeLabel = new JLabel("Size: " + penSize);
left = new JPanel();
main = new JPanel();
panel.addMouseListener(new Painting());
panel.addMouseMotionListener(new Painting());
upButton.addActionListener(new UpButton());
downButton.addActionListener(new DownButton());
left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
main.setLayout(new BorderLayout());
left.add(upButton);
left.add(penSizeLabel);
left.add(downButton);
left.setBackground(Color.gray);
penSizeLabel.setBackground(Color.gray);
frame.getContentPane().add(BorderLayout.CENTER, main);
main.add(BorderLayout.WEST, left);
main.add(BorderLayout.CENTER, panel);
frame.setSize(600, 600);
frame.setVisible(true);
}
class UpButton implements ActionListener{
public void actionPerformed(ActionEvent e){
panel.changePenSize(1);
penSize++;
penSizeLabel.setText("Size: " + penSize);
}
}
class DownButton implements ActionListener{
public void actionPerformed(ActionEvent e){
panel.changePenSize(-1);
if (penSize > 1){
penSize--;
}
penSizeLabel.setText("Size: " + penSize);
}
}
class Painting implements MouseListener, MouseMotionListener{
public void mousePressed(MouseEvent e) {
panel.draw(e.getX(), e.getY());
}
public void mouseDragged(MouseEvent e) {
panel.draw(e.getX(), e.getY());
}
public void mouseReleased(MouseEvent e) {
panel.mouseUp();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
}
Here is the class for the drawing panel:
package paint;
import java.awt.*;
import javax.swing.*;
public class PaintPanel extends JPanel {
int drawX = -10;
int drawY = -10;
int oldX = -10;
int oldY = -10;
int penSize = 1;
public void draw(int x, int y){
oldX = drawX;
oldY = drawY;
drawX = x;
drawY = y;
this.repaint();
}
public void mouseUp(){
oldX = -10;
oldY = -10;
drawX= -10;
drawY= -10;
}
public void changePenSize(int p){
if (penSize > 0){
penSize = penSize+p;
}
}
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
if (oldX != -10 && (oldY) != -10){ // If you didn't just start or lift the pen
g2.setStroke(new BasicStroke(penSize, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g.setColor(Color.red);
g.drawLine(oldX, oldY, drawX, drawY);
} else {
g.setColor(Color.red);
g.fillOval(drawX-(penSize/2), drawY-(penSize/2), penSize, penSize);
}
}
}
EDIT:
Sorry, I didn't know the rules here for posting, please forgive me D:. Also, I didn't know what part of the code messed it up so I didn't know what I should cut out. Thanks for your help.
This won't solve your problem but the following is not used anymore:
main.add(BorderLayout.CENTER, panel); // read the API for more info
You should be using:
main.add(panel, BorderLayout.CENTER);
You need to call super.paintComponent() in your paintComponent() method. Among other things, this will clear the JPanel for you.
I have an angle in a frame (I draw it with two lines). I want to make it flexible to frame; I mean, when the user expands the frame angle also become expanded and vice versa. I tried a lot of examples but I could not solve it. Can someone help?
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class LineDraw extends Frame {
Line2D line1 = new Line2D.Double(200, 200, 100, 300);
Stroke drawingStroke1 = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,
new float[] { 9 }, 0);
Line2D line2 = new Line2D.Double(200, 200, 200, 300);
public void paint(Graphics g) {
Graphics2D graph = (Graphics2D) g;
graph.setPaint(Color.red);
graph.draw(line2);
graph.setStroke(drawingStroke1);
graph.setPaint(Color.green);
graph.draw(line1);
}
public static void main(String args[]) {
Frame frame = new LineDraw();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.setSize(300, 250);
frame.setVisible(true);
}
}
Here it is done in Swing. Everything is done in the EDT, as is intended with Swing as it is not thread safe. It is double buffered. Why the JLabel/Icon combination? It's just the best way to do it, as far as I have discovered, and I'd struggle to give you a historical/technical explanation of why - that's just the way it seems to have been designed. The other approach is to get involved with BufferStrategy but that starts to get more complicated IMHO.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class LineDrawSwing extends JLabel implements Icon {
Line2D line1, line2;
public LineDrawSwing() { this.setIcon(this); }
Stroke drawingStroke1 = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,
new float[] { 9 }, 0);
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.add(new LineDrawSwing());
frame.validate();
frame.setSize(300, 250);
frame.setVisible(true);
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Dimension size = getSize();
line1 = new Line2D.Double(size.width/2, size.height-10, 10, 10);
line2 = new Line2D.Double(size.width/2, size.height-10, size.width-10, 10);
Graphics2D graph = (Graphics2D) g;
graph.setPaint(Color.red);
graph.draw(line2);
graph.setStroke(drawingStroke1);
graph.setPaint(Color.green);
graph.draw(line1);
}
#Override
public int getIconHeight() {
return getSize().height;
}
#Override
public int getIconWidth() {
return getSize().width;
}
}
If sticking with AWT, I would use a ComponentListener to track the size changes for the Frame and reset the line coordinates accordingly.
You may get away with creating/updating the lines in the Frame.paint() context, but that's just not a very clean implementation, with a lot of implied logic and assumptions and, therefore, probably some issues.
So here's the ComponentListener approach. I had to make a few assumptions about where you wanted your lines to get drawn from/to, as you were not clear on this. (If you can be clearer on this, I can update the example.)
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class LineDraw extends Canvas implements ComponentListener {
Line2D line1, line2;
public LineDraw() {
this.addComponentListener(this);
}
// set up lines every size update
public void componentResized(ComponentEvent e) {
Dimension size = getSize();
line1 = new Line2D.Double(size.width/2, size.height-10, 10, 10);
line2 = new Line2D.Double(size.width/2, size.height-10, size.width-10, 10);
}
// required to satisfy ComponentListener interface
public void componentHidden(ComponentEvent e) { }
public void componentMoved(ComponentEvent e) { }
public void componentShown(ComponentEvent e) { }
// paint, main both as before
Stroke drawingStroke1 = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,
new float[] { 9 }, 0);
public void paint(Graphics g) {
Graphics2D graph = (Graphics2D) g;
graph.setPaint(Color.red);
graph.draw(line2);
graph.setStroke(drawingStroke1);
graph.setPaint(Color.green);
graph.draw(line1);
}
public static void main(String args[]) {
Frame frame = new Frame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.add(new LineDraw());
frame.validate();
frame.setSize(300, 250);
frame.setVisible(true);
}
}