I'm trying to make checkers game but the following architecture does not show on JFrame what I'm doing wrong
//base class
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public abstract class Case extends JComponent implements MouseListener {
/**
*
*/
private static final long serialVersionUID = 1L;
protected static final int LONGUEUR=40;
protected int x,y,width,height;
#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
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
//black rectangle
import java.awt.Color;
import java.awt.Graphics;
public class CaseNoire extends Case
{
/**
*
*/
private static final long serialVersionUID = 1L;
public CaseNoire(int x, int y,int width,int height)
{
this.x=x;
this.y=y;
this.width = width;
this.height= height;
}
#Override
protected void paintComponent(Graphics g)
{
g.setColor(Color.black);
g.fillRect(x, y,width,height);
}
}
//white rectangle
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
public class CaseBlanche extends Case {
/**
*
*/
private static final long serialVersionUID = 1L;
public CaseBlanche(int x, int y,int width,int height)
{
this.x=x;
this.y=y;
this.width = width;
this.height= height;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(x, y,width,height);
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Paint;
import javax.swing.JComponent;
import javax.swing.JPanel;
public class Plateau extends JComponent
{
private Case[][] cases= new Case[10][10];
#Override
protected void paintComponent(Graphics g) {
// TODO Auto-generated method stub
super.paintComponent(g);
for(int i=0; i<10; i++)
{
for(int j=0;j<10;j++)
{
if((i+j)%2==0)
{
CaseBlanche blanche= new CaseBlanche(j*Case.LONGUEUR,i*Case.LONGUEUR,Case.LONGUEUR, Case.LONGUEUR);
//cases[i][j]=blanche;
add(blanche);
//g.setColor(Color.white);
// g.fillRect(j*40, i*40,40,40);
}
else
{
CaseNoire caseNoire=new CaseNoire(j*Case.LONGUEUR,i*Case.LONGUEUR,Case.LONGUEUR, Case.LONGUEUR);
add(caseNoire);
}
}
}
}
}
and here the Main Class
import javax.swing.JFrame;
public class MainDamesFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String[] args )
{
MainDamesFrame damesFrame = new MainDamesFrame();
}
public MainDamesFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Jeu de Dames");
this.getContentPane().add(new Plateau());
setSize(800, 600);
setVisible(true);
}
}
I expect something like this
So what's wrong with my code? why paintComponent in CaseBlanche and CaseNoire does not behave as expected?
Please help
public void paintComponents(Graphics g)
You have a typo. Get rid of the "s" in paintComponents().
setSize(800, 600);
This won't work as you expected because the (880, 600) included the title bar and borders, so some of the squares will not be painted properly.
So, your custom painting classes should override the getPreferredSize() method to return the size of each component. Then you can use the pack() method to make sure the components are properly sized.
There is no need for the CaseNoir and CaseBlanche classes. When you create the Case object you can just use:
setBackground(Color.BLACK);
Then when you paint the component you just use:
g.setColor( getBackground() );
Also, your Plateau class is wrong. The paintComponent() method is for painting. Your code is creating and adding components components. If you want to add components then you should be using a layout manager. The GridLayout will easily add components in a grid as long as the getPreferredSize() method has been implemented. You create the component with a specified width/height, so to implement this method you do something like:
#Override
public Dimension getPreferredSize()
{
return new Dimension(width, height)
}
Check out this Chessboard Example for a way to add components in a grid.
Related
I am not very good with using multiple classes in java, as I've always found it easier to do all of my code in 1 class. Recently I've found the need to use a second class for a game I'm making and I'm running into an error.
Right now I'm just trying to spawn the enemy where and when the user clicks.
Main Class -
package joey.rts;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class RTSMain extends JFrame implements MouseListener{
/**
*
*/
private static final long serialVersionUID = -7122370886923000314L;
public static BufferedImage menu,enemy;
public static boolean onmenu,oneenemy;
public static void main(String[] args){
new RTSMain();
}
public RTSMain(){
init();
}
public void init(){
setSize(1700,1100);
setVisible(true);
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("RTS");
addMouseListener(this);
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
if(onmenu == true){
g2.drawImage(menu,0,0,this);
}
}
#Override
public void mouseClicked(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
}
#Override
public void mousePressed(MouseEvent e) {
Enemy enemy = new Enemy();
int x = e.getX();
int y = e.getY();
enemy.spawnEnemy(x, y);
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
Enemy class -
package joey.rts;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class Enemy{
/**
*
*/
public static BufferedImage enemy;
private static final long serialVersionUID = 7898827977636314494L;
public static RTSMain rts;
public static void main(String[] args){
try{
enemy = ImageIO.read(new File(javax.swing.filechooser.FileSystemView.getFileSystemView().getHomeDirectory() + "\\enemy.png"));
} catch (Exception e){
e.printStackTrace();
}
}
public static void spawnEnemy(int x, int y){
Graphics g = rts.getGraphics();
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(enemy,x,y,null);
}
}
In your Main class update your mouseClicked function to be :
#Override
public void mouseClicked(MouseEvent e) {
Enemy enemy = new Enemy();
int x=e.getX(); // get mouse positionX
int y=e.getY();//get mouse positionY
enemy.spawnEnemy(x,y);//spawn Enemy
}
Consider saving the enemy objects if you need to reuse it later.
Also I see no need to extend anything in Enemy Class.
I've Updated Your Main and your Enemy class :
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class Main extends JFrame implements MouseListener{
/**
*
*/
private static final long serialVersionUID = -7122370886923000314L;
public static BufferedImage menu,enemy;
public static boolean onmenu,oneenemy;
public static void main(String[] args){
new Main().setVisible(true);
}
public Main(){
init();
}
public void init(){
setSize(1700,1100);
setVisible(true);
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("RTS");
addMouseListener(this);
}
#Override
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
if(onmenu == true){
g2.drawImage(menu,0,0,this);
}
}
#Override
public void mouseClicked(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
}
#Override
public void mousePressed(MouseEvent e) {
Enemy enemy = new Enemy();
int x = e.getX();
int y = e.getY();
enemy.spawnEnemy(x, y,this.getGraphics());
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
And this is the Enemy class :
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class Enemy{
public static BufferedImage enemy;
private static final long serialVersionUID = 7898827977636314494L;
public Enemy(){
try {
//MAKE SURE THAT THIS IS THE CORRECT IMAGE PATH
enemy = ImageIO.read(new File(javax.swing.filechooser.FileSystemView.getFileSystemView().getHomeDirectory() + "\\enemy.png"));
} catch (IOException ex) {
Logger.getLogger(Enemy.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void spawnEnemy(int x, int y,Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(enemy,x,y,null);
}
}
I've removed the instance variable of Main that was on Enemy class.
I've removed the static modifier for the spawnEnemy function.
I've sent the graphics object as an attribute to spawnEnemy function .
I've Moved the code that was in main method in Enemy class to the Enemy Constructor.
Hope it helps !
It just seemed easier to paste an answer than to try to explain it in a comment. Your OO is a bit off. Add this to your RTSMain class:
protected ArrayList<Enemy> enemies = new ArrayList<Enemy>();
protected BufferedImage enemyImage = null;
...
public void init() {
...
// everything you already have...
enemyImage = //read in your enemy image here
...
}
...
#Override
public void mouseClicked(MouseEvent e) {
// this takes place of Enemy.spawn(), get rid of it
int x = e.getX(); // get mouse positionX
int y = e.getY(); //get mouse positionY
Enemy enemy = new Enemy( enemyImage, x, y );
Enemies.add( enemy );
// Iterate over list above to draw each enemy in your paintComponent method
}
Also, JFrame doesn't have a paintComponent() method, which you need to override to do your painting (paint() is deprecated). Add a JPanel, override it's paintComponent() and so on. For a game, you'll probably want to create a game loop to do your painting, unless it's very turn-based.
Happy coding.
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 got a strange problem with displaying components in JFrame.
I have to write my own GUI engine (buttons, textboxes, etc...) without using Swing. Only JFrame/JPanel is allowed to be used.
Let's say I want to place 3 buttons.
My button class:
public class Button extends JPanel implements MouseListener {
Rectangle r = new Rectangle();
String text;
int X,Y,W,H;
public Button(int x, int y, int w, int h, String t)
{
X=x;
Y=y;
W=w;
H=h;
this.setBackground(Color.CYAN);
addMouseListener(this);
r.setSize(w, h);
r.setLocation(x, y);
this.text = t;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.draw(r);
g2d.drawString(text, X+W/2, Y+H/2);
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
if((arg0.getButton()==1) && r.contains(arg0.getPoint()))
System.out.println(arg0.getPoint().toString());
}
#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
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
And in main class I create a JFrame and JPanel. I add to JPanel 3 buttons, and finally JPanel to JFrame, but only the last declared button shows up.
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame f = new JFrame("Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBackground(Color.cyan);
JPanel j = new JPanel(new BorderLayout());
j.add(new Button(10,10,100,50,"text"));
j.add(new Button(10,100,100,50,"text2"));
j.add(new Button(300,10,100,50,"text3"));
f.add(j);
f.pack();
f.setSize(640, 400);;
f.setVisible(true);
}
What am I doing wrong?
Your code does not respect the BorderLayout rules. When adding 3 components to the BorderLayout using container without specifying BorderLayout location, they all get added to the default BorderLayout.CENTER spot, and the last one added covers the other 3. Consider using BorderLayout constants when adding components or using another layout manager(s).
Having said this, I think that you're better off completely changing route. Instead consider ...
making your Button class a logical and non-GUI class (i.e., by not having it extend JPanel),
having one single non-Button JPanel hold a List<Button>,
having this single JPanel draw all the Buttons by iterating through the list within its paintComponent method, calling a draw(Graphics g) method that each Button has
have the JPanel interact with the Buttons via a single MouseListener.
This will greatly simplify things.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class FooGui extends JPanel {
private static final int PREF_W = 640;
private static final int PREF_H = 400;
private List<MyButton> btnList = new ArrayList<>();
public FooGui() {
addMouseListener(new MyMouse());
}
public void addButton(MyButton btn) {
btnList.add(btn);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (MyButton myButton : btnList) {
myButton.draw(g);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
for (MyButton myButton : btnList) {
if (myButton.getRect().contains(e.getPoint())) {
System.out.println("Text: " + myButton.getText());
}
}
}
}
private static void createAndShowGui() {
FooGui fooGui = new FooGui();
fooGui.addButton(new MyButton(10,10,100,50,"text"));
fooGui.addButton(new MyButton(10,100,100,50,"text2"));
fooGui.addButton(new MyButton(300,10,100,50,"text3"));
JFrame frame = new JFrame("FooGui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(fooGui);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyButton {
private static final Color BK = Color.CYAN;
private static final Color TEXT_COLOR = Color.BLACK;
private int x;
private int y;
private int w;
private int h;
private String text;
private Rectangle rect;
public MyButton(int x, int y, int w, int h, String t) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.text = t;
rect = new Rectangle(x, y, w, h);
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(BK);
g2.fill(rect);
g2.setColor(TEXT_COLOR);
FontMetrics metrics = g2.getFontMetrics();
Rectangle2D bounds = metrics.getStringBounds(text, g2);
int textX = (int) (x + (w - bounds.getWidth()) / 2);
int textY = (int) (y + (h + bounds.getHeight()) / 2);
g2.drawString(text, textX, textY);
}
public Rectangle getRect() {
return rect;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getW() {
return w;
}
public int getH() {
return h;
}
public String getText() {
return text;
}
}
The purpose of this assigment is to create a GUI, which can be used when for example, there is no implemented JButton, JLabel etc. in a certain device (such as old mobile phones)
Well, that doesn't really answer my question. You addressed the issue of custom painting of buttons and labels, but there is more to a GUI then just painting things.
I also asked if you can use other features of AWT, like MouseListeners, KeyListeners, tabbing, layout managers etc. Because if you can use these features, then there is no reason to completely reinvent the wheel as has been done in the answer by hovercraft.
If all you need to do is extend JPanel and do custom painting for a button or label, then the problem with your code is that you are NOT using the layout managers properly. That is the default layout of a frame is a BorderLayout and you can't add multiple components to the CENTER of the BorderLayout.
The second problem with your posted code is you don't override the getPreferredSize() method of your components. Therefore the size will be 0 and the layout managers can't do their job properly.
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()