SWING - drawing straight lines, which won't appear when compiled - java

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);
}
}
}

Related

MouseListener - MouseClicked

After 2 hours of searching I really can't find out why my code isn't working so I wonder if you could help.
All I want to see is "Clicked" when I press the button. My class MouseInput implements MouseListener and in the method mouseClicked all I got is system.out...("clicked");
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
public class App implements Runnable {
private Display display;
private BufferStrategy bs;
private Graphics g;
private int cubeSide = 150;
private String title;
private int height,width;
private boolean running = false;
private Thread thread;
private MouseInput mouseInput;
public App(String title,int width,int height){
this.height=height;
this.width=width;
this.title=title;
display = new Display(title, width, height);
}
void setBufferStrategy(){
if(display.getCanvas().getBufferStrategy()==null){
display.getCanvas().createBufferStrategy(3);
}
bs = display.getCanvas().getBufferStrategy();
}
void init(){
setBufferStrategy();
mouseInput = new MouseInput();
display.getFrame().addMouseListener(mouseInput);
}
public synchronized void start(){
if(running==true)
return;
running=true;
thread = new Thread(this);
thread.start();
}
void render(){
}
#Override
public void run() {
init();
while(running){
render();
}
}
public synchronized void stop(){
}
}
MouseInput Code:
`import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MouseInput implements MouseListener {
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Click");
}
#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 for the Display class:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Display {
private JFrame frame;
private Canvas canvas;
private String title;
private int width,height;
public Display(String title,int width,int height){
this.width = width;
this.height=height;
this.title=title;
CreateDisplay();
}
public void CreateDisplay(){
frame = new JFrame(title);
canvas = new Canvas();
frame.setSize(width,height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setFocusable(false);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
canvas.setPreferredSize(new Dimension(width,height));
canvas.setMaximumSize(new Dimension(width,height));
canvas.setMinimumSize(new Dimension(width,height));
canvas.setBackground(Color.WHITE);
frame.add(canvas);
frame.pack();
}
public Canvas getCanvas(){
return canvas;
}
public JFrame getFrame(){
return frame;
}
}
I think the problem can be in display.getFrame().addMouseListener(mouseInput): I suppose display.getFrame() returns a an instance of a class extending java.awt.Component; according to API reference, addMouseListener
Adds the specified mouse listener to receive mouse events from this component.
I think an event on your button is not an event from the component you registered the listener on: can you try to register the listener on the canvas instance instead of on frame instance? May be the event originated from canvas, not from frame...
First, you can use an inline mouse adapter rather than extending mouse listener and needing a separate file for the mouse code.
Second, if you want to observe the click on your button, add the listener to your button.
yourJButton.addMouseListener( new MouseAdapter()
{
#Override
public void mouseClicked( MouseEvent e )
{
{
//do stuff
}
}
});

Rectangle not moving

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.

Why won't circle draw where I click

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();
}
}

Why does the paint clear on my JPanel whenever the JFrame is resized?

Go ahead, test the code. When the program is running, you can draw on the panel, but whenever it resized, the paint disappears. Any idea why or how to solve this? I would love the help!
Window.java
--The GUI class
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
public class Window extends JFrame implements ComponentListener {
public Window(){
this.setSize(700, 700);
this.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
this.setJMenuBar(menubar);
this.add(new PaintPanel());
this.setTitle("JPaint");
this.setBackground(Color.WHITE);
this.add(TOOL_BAR, BorderLayout.NORTH);
TOOL_BAR.add(BUTTON);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.add(PAINT_PANEL);
menubar.add(FILE);
FILE.setMnemonic(KeyEvent.VK_F);
FILE.add(NEW);
FILE.add(NEW_OPEN_SEPARATOR);
FILE.add(OPEN);
FILE.add(SAVE);
FILE.add(SAVE_AS);
FILE.add(SEPARATOR);
FILE.add(EXIT);
menubar.add(Box.createHorizontalGlue());
menubar.add(HELP);
HELP.add(ABOUT);
HELP.add(GNU_PUBLIC_LICENSE);
this.setVisible(true);
NEW.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
PAINT_PANEL.repaint();
}
});
OPEN.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
final JFileChooser FILE_CHOOSER = new JFileChooser();
int CHOSEN_FILE = FILE_CHOOSER.showOpenDialog(FILE_CHOOSER);
}
});
SAVE.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
final JFileChooser SAVE_FILE_CHOOSER = new JFileChooser();
SAVE_FILE_CHOOSER.showSaveDialog(null);
Container c = frame.getContentPane();
BufferedImage SAVED_IMAGE = new BufferedImage(c.getWidth(), c
.getHeight(), BufferedImage.TYPE_INT_ARGB);
c.paint(SAVED_IMAGE.getGraphics());
try {
ImageIO.write(SAVED_IMAGE, "PNG", new File("test.png"));
} catch (IOException e1) {
// If unable to save image for 'Exception' reason.
e1.printStackTrace();
}
}
});
EXIT.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
ABOUT.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JOptionPane
.showMessageDialog(frame,
"Created by Matthew Hanzelik for "
+ "open source use!");
}
});
GNU_PUBLIC_LICENSE.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "gpl.txt");
}
});
}
/**
* Serial Version
*/
private static final JFrame frame = new JFrame();
private static final long serialVersionUID = 5259700796854880162L;
private static final JMenuBar menubar = new JMenuBar();
private static final JMenu FILE = new JMenu("File");
private static final JMenu HELP = new JMenu("Help");
private static final JMenuItem SAVE = new JMenuItem("Save");
private static final JMenuItem EXIT = new JMenuItem("Exit");
private static final JSeparator SEPARATOR = new JSeparator();
private static final JSeparator NEW_OPEN_SEPARATOR = new JSeparator();
private static final JMenuItem NEW = new JMenuItem("New");
private static final JMenuItem OPEN = new JMenuItem("Open");
private static final JMenuItem SAVE_AS = new JMenuItem("Save as...");
private static final JMenuItem ABOUT = new JMenuItem("About");
private static final JMenuItem GNU_PUBLIC_LICENSE = new JMenuItem(
"GNU Public License");
private static final JToolBar TOOL_BAR = new JToolBar();
private static final JButton BUTTON = new JButton("Test");
private static final PaintPanel PAINT_PANEL = new PaintPanel();
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Window GUI = new Window();
}
});
}
#Override
public void componentHidden(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void componentMoved(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void componentResized(ComponentEvent arg0) {
// TODO Auto-generated method stub
System.out.println("resized");
}
#Override
public void componentShown(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
}
PaintPanel
--The class that contains the panel on which to paint on
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class PaintPanel extends JPanel {
MouseMotionListener theListener;
Graphics g;
MouseListener theListening;
int x, y, x1, y1;
boolean inside;
public PaintPanel() {
x = 0;
y = 0;
x1 = -99;
y1 = -99;
inside = false;
theListener = new MouseMotionListener() {
public void mouseDragged(MouseEvent arg0) {
if (inside) {
repaint();
}
}
public void mouseMoved(MouseEvent arg0) {
}
};
theListening = new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
x1 = -99;
y1 = -99;
}
public void mouseEntered(MouseEvent arg0) {
inside = true;
x1 = -99;
y1 = -99;
}
public void mouseExited(MouseEvent arg0) {
inside = false;
x1 = -99;
y1 = -99;
}
};
this.setBackground(Color.WHITE);
this.setVisible(true);
this.addMouseMotionListener(theListener);
this.addMouseListener(theListening);
}
#Override
public void paint(Graphics g) {
try {
if (x1 == -99) {
x = getMousePosition().x;
x1 = x;
y = getMousePosition().y;
y1 = y;
} else
{
x = getMousePosition().x;
y = getMousePosition().y;
g.drawLine(x, y, x1, y1);
x1 = x;
y1 = y;
}
} catch (Exception ex) {
}
}
}
Two things: first, when extending a JComponent, you should really override paintCompontent, not paint.
Secondly, inside of your paintComponent, you need to render all of the lines that the user has drawn. This means that you need to store them as they are drawn, and then render them all inside of paintComponent every time. This is because paintComponent gets called any time the window needs to be re-rendered (for example, when the window has been minimized and then restored). Swing does not "remember" which pixels you've set to which colors in this case. Instead, it calls paintComponent and expects you to re-create them.
Also, when you override paintComponent, you will most likely want to call super.paintComponent before doing any of your rendering work.
, but whenever it resized, the paint disappears. Any idea why or how to solve this?
If you want to do incremental painting then there are two common approaches:
Keep an ArrayList of the Objects you want to paint and then repaint all the Object every time the component is repainted.
Paint your objects directly to a BufferedImage. Then the BufferedImage will be repainted automatically every time.
See Custom Painting Approaches for more information and working examples of each approach.

How paint() in a CLONE JPanel?

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()

Categories