I am trying to draw to my JFrame with Graphics. For some reason, it won't draw anything. What am I doing wrong? I have added my paint method, imported everything. Am I placing the method in the wrong place?
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
public class Main extends Canvas implements MouseListener, KeyListener {
public int WIDTH = 1080;
public static Main main;
public boolean playing = false;
public Main() {
addMouseListener(this);
addKeyListener(this);
JFrame frame = new JFrame("Clicker");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(50, 50, 100, 100);
}
public static void main(String[] args) {
main = new Main();
}
public void MainScreen() {
}
#
Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#
Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#
Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#
Override
public void mouseClicked(MouseEvent evt) {
// TODO Auto-generated method stub
}
#
Override
public void mouseEntered(MouseEvent evt) {
// TODO Auto-generated method stub
}
#
Override
public void mouseExited(MouseEvent evt) {
// TODO Auto-generated method stub
}
#
Override
public void mousePressed(MouseEvent evt) {
// TODO Auto-generated method stub
}
#
Override
public void mouseReleased(MouseEvent evt) {
// TODO Auto-generated method stub
}
}
Try to extend from the JFrame class instead of the Canvas class:
public class Main extends JFrame implements ...
You also have to edit your constructor then like:
public Main() {
super("Clicker");
addMouseListener(this);
addKeyListener(this);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
Related
Hello I'm trying to create a brick breaker game. There is a main class called Real_Main and another class called Real_Create that extends JPanel. I feel like my code is right but I can't seem to move my rectangle with the right and left arrow keys. Could anyone tell me what's wrong with it? And why do we need a timer to move the rectangle?
import javax.swing.JFrame;
public class Real_Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame jf= new JFrame();
Real_Create panel=new Real_Create();
jf.setSize(500, 500);
jf.setVisible(true);
jf.setResizable(false);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(panel);
}
}
Real_Create:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Real_Create extends JPanel implements KeyListener,ActionListener {
int baseX=200;
int ballX=250;
int ballY=250;
int delay=20;
Timer tim;
Boolean play=false;
public Real_Create(){
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
tim=new Timer(delay,this);
tim.start();
}
public void paint(Graphics g){
//background
g.setColor(Color.black);
g.fillRect(1,1,500,500 );
//baseplayer
g.setColor(Color.white);
g.fillRect(baseX, 430, 80, 10);
//ball
g.setColor(Color.green);
g.fillOval(ballX, ballY, 20, 20);
g.dispose();
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
tim.start();
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode()== KeyEvent.VK_RIGHT){
if(baseX >=420){
baseX=420;
}
else{
moveRight();
}
}
if(e.getKeyCode()== KeyEvent.VK_LEFT){
if(baseX <=0){
baseX=0;
}
else{
moveLeft();
}
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public void moveRight(){
play=true;
baseX+=10;
}
public void moveLeft(){
play=true;
baseX-=10;
}
}
Image from the game:
What you are dealing with is unpredictable Swing behaviour due to its lack of thread safety. According to documentation "all code that creates or interacts with Swing components must run on the event dispatch thread". To achieve that you should rewrite your GUI creation like so:
public class Real_Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame jf = new JFrame();
Real_Create panel = new Real_Create();
jf.setSize(500, 500);
jf.setVisible(true);
jf.setResizable(false);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(panel);
}
}
You can read more on the subject here.
So I'm trying to draw a circle where a user clicks, which can then be re-sized by the bar down below. Everything works except for that the circle won't draw where I want it to. Any suggestions?
Here is my Panel
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.event.*;
public class TestClass extends JFrame {
private JSlider slide;
private MainClass myPanel;
public int x1=0;
public int y1=0;
public TestClass(){
super("The Title");
myPanel = new MainClass();
myPanel.setBackground(Color.YELLOW);
slide = new JSlider(SwingConstants.HORIZONTAL, 0, 200, 10);
slide.setMajorTickSpacing(10);
slide.setPaintTicks(true);
slide.addChangeListener(
new ChangeListener(){
public void stateChanged(ChangeEvent e){
myPanel.checkDiameter(slide.getValue());
}
}
);
HandlerClass handler = new HandlerClass();
slide.addMouseListener(handler);
add(slide, BorderLayout.SOUTH);
add(myPanel, BorderLayout.CENTER);
}
public int setX1(){
return x1;
}
public int setY1(){
return y1;
}
private class HandlerClass implements MouseListener{
#Override
public void mouseClicked(MouseEvent event) {
// TODO Auto-generated method stub
x1=event.getX();
y1=event.getY();
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
Here is the other important class which creates a window and call TestClass;
import java.awt.*;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MainClass extends JPanel{
private int d = 10;
public void paintComponent(Graphics g){
super.paintComponent(g);
TestClass values = new TestClass();
g.setColor(Color.CYAN);
g.fillOval(values.setX1()+50, values.setY1(), d, d);
}
public void checkDiameter(int newD)
{
//New format for if statements
d = (newD >= 0 ? newD //if
: 10//else
);
repaint();
}
public Dimension getPreferredSize(){
return new Dimension(200,200);
}
public Dimension getMinimumSize(){
return getPreferredSize();
}
}
Hey Guys I found a way to get it working.
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.event.*;
public class TestClass extends JFrame {
private JSlider slide;
private MainClass myPanel;
public static int x1=0,y1=0;
public TestClass(){
super("The Title");
myPanel = new Panel();
myPanel.setBackground(Color.YELLOW);
//Allows you to re-size the drawn circle
slide = new JSlider(SwingConstants.HORIZONTAL, 0, 200, 10);
slide.setMajorTickSpacing(10);
slide.setPaintTicks(true);
slide.addChangeListener(
new ChangeListener(){
public void stateChanged(ChangeEvent e){
myPanel.checkDiameter(slide.getValue());
}
}
);
//Create a way to handle user mouse events
HandlerClass handler = new HandlerClass();
myPanel.addMouseListener(handler);
add(slide, BorderLayout.SOUTH);
add(myPanel, BorderLayout.CENTER);
}
private class HandlerClass implements MouseListener{
#Override
public void mouseClicked(MouseEvent event) {
// TODO Auto-generated method stub
Right here is what is new with the code, this method gets the x and y coordinates of a click and sends it to MainClass object myPanel which has the setPosition method; class show before.
myPanel.setPosition(event.getX(),event.getY());
repaint(); }
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
Here is the MainClass class, it is poorley named as it's not actually the main class...
import java.awt.;
import javax.swing.;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Panel extends JPanel{
private int x1,y1;
private int d = 10;
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.CYAN);
g.fillOval(x1, y1, d, d);
}
public void checkDiameter(int newD)
{
//New format for if statements
d = (newD >= 0 ? newD //if
: 10//else
);
repaint();
}
public void setPosition(int newX, int newY) {
this.x1 = newX;
this.y1 = newY;
repaint();
}
public Dimension getPreferredSize(){
return new Dimension(200,200);
}
public Dimension getMinimumSize(){
return getPreferredSize();
}
}
I have a very simple example. I'm trying to get working before i try and apply this to the more complex program I have planned. But I'm trying to be able to drag and drop the JPanels that are in say a Flow or Vertical Layout.
I'm not really sure where to start, as this isn't really anything I've dealt with before. But from what I've researched, it would seem that I surely need a listener on each JPanel, that listens for clicks. From here it will gather initial data from a mousePressed, and run a overridden repaint(), that will update the coordinates of the panel in the container. Then according to where the coordinate is placed, it will repack() and hopefully resize the panels.
Am I onto the right track?
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
public class DraggablePanels extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
Border raisedbevel = BorderFactory.createRaisedBevelBorder();
int px, py;
JPanel main = new JPanel();
public DraggablePanels(){
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
JPanel p1 = new JPanel();
p1.addMouseListener(new MouseListener(){
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
px = e.getX();
py = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
});
p1.setBorder(raisedbevel);
JPanel p2 = new JPanel();
p2.addMouseListener(new MouseListener(){
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
px = e.getX();
py = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
});
p2.setBorder(raisedbevel);
p1.add(new JLabel("Thing 1"));
p2.add(new JLabel("Thing 2"));
main.add(p1);
main.add(p2);
add(main);
pack();
setVisible(true);
}
public static void main (String args[]){
DraggablePanels d = new DraggablePanels();
}
}
Check this Sample Application for rearranging jpanel:
http://www.bryanesmith.com/docs/drag-and-drop-java-5/
I am trying to draw lines with the mouse in a JFrame window, and when I try to do so, it doesn't work! Please ignore the menu, I am trying to do things with that later! What did I miss! I would be grateful if you could give me some hints!
public class newGUI extends JFrame implements ActionListener, MouseMotionListener, MouseListener {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 300;
public static final int HEIGHT = 200;
Point point1;
Point point2;
Line2D line2d;
public static void main(String[] args){
newGUI gui = new newGUI();
gui.setVisible(true);
}
public newGUI()
{
super("Menu Demonstration");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenu colorMenu = new JMenu("Choose Colors");
JMenuItem greenChoice = new JMenuItem("GREEN");
greenChoice.addActionListener(this);
colorMenu.add(greenChoice);
JMenuItem redChoice = new JMenuItem("RED");
colorMenu.add(redChoice);
JMenuBar bar = new JMenuBar();
bar.add(colorMenu);
setJMenuBar(bar);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
point1=arg0.getPoint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
point2=arg0.getPoint();
line2d=new Line2D.Double(point1, point2);
repaint();
}
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
if(point1!=null && point2!=null){
g2d.setPaint(Color.RED);
g2d.setStroke(new BasicStroke(1.5f));
g2d.draw(line2d);
repaint();
}
}
}
Always start class names with a capital letter i.e NewGui
Use Event Dispatch Thread for creating and changing of UI components
Do not extend JFrame class uncecessarily
Do not call setSize(..) rather call JFrame#pack() on JFrame instance
JFrame does not have a paintComponent(..), rather add custom JPanel and override its paintComponent(..) and getPreferredSize(..)
Dont forget to call super.paintComponent(..) in your custom JPanel
Do not call repaint() from within paintComponent(..) (this will cause an infinite loop of repainting more than needed)
Also where possible (if it is not used by other classes) use anonymous MouseListeners/MouseMotionListeners and rather use MouseAdapter instead of MouseListener/MouseMotionListeners etc.
Here is an example I made (basically your code with fixes mentioned):
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class NewGui implements ActionListener {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 300;
public static final int HEIGHT = 200;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
NewGui gui = new NewGui();
}
});
}
public NewGui() {
initComponents();
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
private void initComponents() {
JFrame frame = new JFrame("Menu Demonstration");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenu colorMenu = new JMenu("Choose Colors");
JMenuItem greenChoice = new JMenuItem("GREEN");
greenChoice.addActionListener(this);
colorMenu.add(greenChoice);
JMenuItem redChoice = new JMenuItem("RED");
colorMenu.add(redChoice);
JMenuBar bar = new JMenuBar();
bar.add(colorMenu);
frame.setJMenuBar(bar);
frame.add(new MyPanel());
frame.pack();
frame.setVisible(true);
}
}
class MyPanel extends JPanel {
Point point1;
Point point2;
Line2D line2d;
public MyPanel() {
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent me) {
super.mousePressed(me);
point1 = me.getPoint();
}
});
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent me) {
super.mouseDragged(me);
// TODO Auto-generated method stub
point2 = me.getPoint();
line2d = new Line2D.Double(point1, point2);
repaint();
}
});
}
//so our panel will be visible
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 200);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//Set anti-alias!
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (point1 != null && point2 != null) {
g2d.setPaint(Color.RED);
g2d.setStroke(new BasicStroke(1.5f));
g2d.draw(line2d);
}
}
}
Anybody know how can I repaint in a clone JPanel. Im using CLONE, so I can REPAINT() one, and the other will do the same automatically.
My code only paints the original JPanel if I move the mouse in the original or in the clone panel,
but If I move the mouse in the clone panel, this jpanel doesn't paint.
Thanks in advance
CODE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ProcessorClone {
public static void main(String[] args) {
JFrame aWindow = new JFrame();
aWindow.setBounds(300, 200, 300, 100);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Container content = aWindow.getContentP
aWindow.setVisible(true);
CardViewer panel02=new CardViewer();
CardViewer panel01= (CardViewer) panel02.clone();
aWindow.setLayout(new BorderLayout());
aWindow.add(panel01,BorderLayout.NORTH);
aWindow.add(panel02,BorderLayout.SOUTH);
panel01.setBackground(Color.RED);
panel02.setBackground(Color.blue);
panel01.repaint();
panel02.repaint();
panel01.validate();
panel02.validate();
}
}
class CardViewer extends JPanel implements MouseListener,MouseMotionListener, Cloneable {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel mContentPaneBorder;
private JPanel mContentPane;
private JButton FileButton=new JButton("AAA");
private Point p;
public CardViewer(){
super();
this.add(FileButton);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("mouseClicked");
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
System.out.println("mousePressed");
p = null;
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
System.out.println("mouseMoved");
p = e.getPoint();
this.repaint();
this.validate();
}
public void paint(Graphics g) {
System.out.println( g.getClass() );
if (p != null) {
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
g.drawLine(p.x, p.y, p.x, p.y);
this.setBackground(Color.pink);
}
}
public Object clone () {
// First make exact bitwise copy
CardViewer copy = null;
try {
copy = (CardViewer)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return copy;
}
}
.clone() does not return a mirror of the JPanel but returns a copy of the object, so you really have 2 separate JPanel objects so actions in one will not automatically reflect in the other.
You could override all the actions in a component that inherits from JPanel with a reference to a .cloned() JPanel object and then route all methods to the other JPanel after calling super()