Java drawing- need to refresh screen - java

In this code are two buttons.One makes rectangle move to the right on x axis, and second makes rectangle move down on y axis.My problem is, that each previous position of rectangle stays on screen and it looks like rect is leaving a trail behind it.Anny suggestions how could I clear screen or something?
public class testing extends JFrame implements ActionListener{
public JButton button;
public JButton button2;
public boolean check;
public int x;
public int y;
public void paint(Graphics g){
if(check==true){
g.setColor(Color.red);
g.fillRect(x, y, 50, 50);
}
}
public void start(){
setLayout(new FlowLayout());
button=new JButton();
button2=new JButton();
button.setPreferredSize(new Dimension(50,50));
button.setText("R");
button.addActionListener(this);
button2.setPreferredSize(new Dimension(50,50));
button2.setText("D");
button2.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){y=y+10;check=true;repaint();}});
add(button);
add(button2);
setSize(500,500);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
x=x+10;
check=true;
repaint();
}
public static void main(String args[]){
testing x=new testing();
x.start();
}
}

I'm not 100% sure on this, but I believe you need to call the parent's paint method, so change your paint method to this:
public void paint(Graphics g)
{
super.paint(g);
if(check)
{
g.setColor(Color.red);
g.fillRect(x, y, 50, 50);
}
}

Related

Failing to call a call paintcomponent method :(

What I am trying to achieve is that the program would draw a line in the middle of the frame as soon as the user has clicked draw. But sadly nothing is happening other than "frame 3" is disappearing. Any ideas about how I could fix the problem?
Here is the method:
Windowj is my frame. Frame3 is the previous frame please don't worry about it.
public static void graf() {
frame3.setVisible(false);
windowj.setSize(400, 500);
windowj.setLocationRelativeTo(null);
windowj.setResizable(false);
windowj.setLayout(null);
windowj.setVisible(true);
windowj.setTitle("Graphs");
windowj.setDefaultCloseOperation(EXIT_ON_CLOSE);
xinwindow.setBounds(30,40, 90, 40);
yinwindow.setBounds(100,100,90,40);
thefunction.setBounds(200,300,90,40);
draw.setBounds(300,200,90,40 );
windowj.add(xinwindow);
windowj.add(yinwindow);
windowj.add(thefunction);
windowj.add(draw);
c.setPreferredSize(new Dimension(300,200));
draw.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowj.add(c);
c.revalidate();
c.repaint();
}
And here is the paintcomponent method:
private static Component c = new JComponent() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawLine(50, 0, 70 , 100);
}
};
Any help would be appreciated, and please try to keep it simple, I am a beginner. :)
I will assume you use windowj as your JFrame and that what will happen when you click draw button your use windowj.setVisible(false) and that will make your window disappear
so remove it
2nd thing is you need to put your Component in windowj as windowj.add(c); in your draw ActionListener at actionPerformed before c.revalidate();
and here a little code that I wrote to understand what I mean:
public class DrawLine {
private JFrame windowj = new JFrame();
private JButton draw = new JButton();
private static int width = 640, height = 480;
private static JComponent c = new JComponent() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawLine((width/2) - 1, 0, (width/2) +1 , height);
}
};
public DrawLine() {
windowj.setDefaultCloseOperation(windowj.EXIT_ON_CLOSE);
windowj.setSize(width, height);
windowj.setLayout(new FlowLayout());
windowj.setResizable(false);
windowj.setLocationRelativeTo(null);
windowj.setVisible(true);
draw = new JButton("Draw");
draw.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//i don't know why you set windowj(windowj) false but that will close your window
//windowj.setVisible(false);
//add component to windowj(windowj)
windowj.add(c);
c.revalidate();
c.repaint();
}
});
c.setPreferredSize(new Dimension(width, height-100));
windowj.add(draw);
}
public static void main(String[] args) {
new DrawLine();
}
}
Here is the modified code:
private JFrame frame3, windowj;
private JPanel xinwindow, yinwindow,thefunction;
private JButton draw;
private static Component c = new JComponent() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawLine(50, 0, 70 , 100);
}
};
public DrawLine() {
xinwindow = new JPanel();
yinwindow = new JPanel();
thefunction = new JPanel();
draw = new JButton("Draw");
//i ignored frame3 as you said so just ignore my implementation here
frame3 = new JFrame();
frame3.setVisible(false);
windowj = new JFrame();
windowj.setSize(400, 500);
windowj.setLocationRelativeTo(null);
windowj.setResizable(false);
windowj.setLayout(null);
windowj.setVisible(true);
windowj.setTitle("Graphs");
windowj.setDefaultCloseOperation(EXIT_ON_CLOSE);
/*i used setBackground(Color.anycolor); to make it easier for me to know where
your window is in your frame*/
xinwindow.setBackground(Color.RED);
xinwindow.setBounds(30,40, 90, 40);
yinwindow.setBackground(Color.yellow);
yinwindow.setBounds(100,100,90,40);
thefunction.setBounds(200,300,90,40);
thefunction.setBackground(Color.green);
draw.setBounds(300,200,90,40 );
windowj.add(xinwindow);
windowj.add(yinwindow);
windowj.add(thefunction);
windowj.add(draw);
//here use setBonds instead of setPreferredSize
c.setBounds(100, 200, 200, 200);
draw.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowj.add(c);
c.revalidate();
c.repaint();
}
});
}
public static void main(String[] args) {
new DrawLine();
}
hope that solve your problem.

How Can This Stickman Be Made to Be Interactive?

So, I need to make the stick-man movable by a user-input. When the user clicks on a part (Head, hands, feet and posterior) and he should move, and have no idea how to go about this..
If possible, there also needs to be a confine around the character, likely rectangular, so that there is a limit to how far each part can be pulled.
See below for my code;
// Created by Charlie Carr - (28/11/17 - /11/17)
import java.awt.*;
import java.applet.Applet;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
//Imports complete
//Suppress warning about undeclared static final serialVersionUID field in VS Code
#SuppressWarnings("serial")
public class Animator extends JPanel {
public static class AnimatorWindow extends JPanel {
public void paint(Graphics page) {
setBackground(Color.gray);
setForeground(Color.white);
super.paintComponent(page);
page.drawString("Stickmen Animation Station", 150, 15);
//draw the head
//x1, y1, x2, y2
page.drawOval(90, 60, 20, 20);
// draw the body
page.drawLine(100, 80, 100, 110);
// draw the hands
page.drawLine(100, 90, 80, 105);
page.drawLine(100, 90, 120, 105);
//draw the legs, he hasn't a leg to stand on..
page.drawLine(100, 110, 85, 135);
page.drawLine(100, 110, 115, 135);
}
}
public static void main(String[] args) {
AnimatorWindow displayPanel = new AnimatorWindow();
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(displayPanel, BorderLayout.CENTER);
//declare window size
int x = 480;
int y = 240;
JFrame window = new JFrame("GUI");
window.setContentPane(content);
window.setSize(x, y);
window.setLocation(101, 101);
window.setVisible(true);
}
}
Use MouseListenerto deal with mouse events.
Also, you should override the paintComponent() method instead of paint(), because paint() also paints the border and other stuff.
public static class AnimatorWindow extends JPanel implements MouseListener{
public AnimatorWindow(){
setBackground(Color.gray);
setForeground(Color.white);
//add the listener
addMouseListener(this);
}
public void paintComponent(Graphics page) {
super.paintComponent(page);
//You should not alter the Graphics object passed in
Graphics2D g = (Graphics2D) page.create();
//draw your stuff with g
g.drawString("Stickmen Animation Station", 150, 15);
.......
//finish
g.dispose();
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){
//implement your clicking here
//Use e.getX() and e.getY() to get the click position
}
}
For more on swing events, check this site
EDIT: Your problem also includes animation, and you can use a javax.swing.Timer to do that.

How do i get my action listener to remove the contents from the current JPanel?

I am trying to add a button which will when pressed, clear the contents off the JPanel and return the panel back to its original set-up. How would i go about doing this? I have tried to revalidate, removeall etc but none have worked for me so far. Any suggestions on how i can do this? I will attach the code below, Help would be greatly appreciated.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class WindowBlind extends JFrame
implements ChangeListener, ActionListener {
private JSlider slider;
private int sliderValue = 0;
private JPanel panel;
private JButton open;
private JButton close;
private JButton exit;
private boolean clear;
public static void main(String[] args) {
WindowBlind applic = new WindowBlind();
applic.setLocation(100,100);
applic.setVisible(true);
} // main
public WindowBlind() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("WindowBlind");
setSize(300,300);
Container window = getContentPane();
window.setLayout(new FlowLayout());
panel = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
paintScreen(g);
} // paintComponent
};
panel.setPreferredSize(new Dimension(200, 200));
panel.setBackground(Color.white);
window.add(panel);
slider = new JSlider(JSlider.VERTICAL,0,100,0);
slider.setInverted(true); // 0 will be at top, not bottom, of vertical slider
window.add(slider);
slider.addChangeListener(this); // Register for slider events
JButton open = new JButton("Open Slider");
window.add(open);
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
JButton close = new JButton("Close Slider");
window.add(close);
close.addActionListener(this);
JButton exit = new JButton("Exit Slider");
window.add(exit);
exit.addActionListener(this);
} // WindowBlind constructor
public void paintScreen(Graphics g) {
g.setColor(Color.cyan);
g.fillRect(70, 40, 60, 100); // The blue sky
g.setColor(Color.lightGray);
g.fillRect(70, 40, 60, sliderValue); // The blind, partially closed
g.setColor(Color.black);
g.drawRect(70, 40, 60, 100); // The window frame
} // paintScreen
// When the slider is adjusted, this method is called automatically
public void stateChanged(ChangeEvent e) {
sliderValue = slider.getValue(); // Fetch the slider's current setting
repaint(); // Force a screen refresh (paintComponent is called indirectly)
} // stateChanged
#Override
public void actionPerformed(ActionEvent e) {
}
}
I'm taking a HUGE guess and assuming you want to reset the slider to it's "default" state, which would suggest that you need to change the sliderValue, something like...
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sliderValue = 0;
slider.repaint();
}
});
A better solution would be to generate a self contained class which encapsulated all this functionality, for example...
public class SliderPane extends JPanel {
private double sliderValue;
public double getSliderValue() {
return sliderValue;
}
public void setSliderValue(double sliderValue) {
this.sliderValue = Math.max(Math.min(1.0, sliderValue), 0);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(Color.cyan);
g.fillRect(0, 0, width, height); // The blue sky
g.setColor(Color.lightGray);
g.fillRect(0, 0, width, (int)(sliderValue * height)); // The blind, partially closed
g.setColor(Color.black);
g.drawRect(0, 0, width, height); // The window frame
}
}
Then you could control the slider value through the setSliderValue method.
This also allows you to specify the slider value as percentage, meaning that the size of the component doesn't matter as the area filled is a percentage of the height
This is because you always call paintScreen from the panel's paintComponent method. I would suggest this midification:
panel = new JPanel() {
boolean drawMe = true;
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(drawMe)
paintScreen(g);
} // paintComponent
};
Whenever you want to clear the panel, do this:
panel.drawMe=false;
panel.invalidate();

Label gets added to JPanel without reason swing

I'm trying to make a simple application for painting. I have a main method that sets up a JFrame, and then adds a JPanel and a JLabel using flowlayout. The JLabel is for counting clicks.
The panel class implements a mouselistener and mousemotionlistener.
The problem is when I paint something or click on the panel, it adds the label to the JPanel aswell, and depending on where I click, it can add it twice to the panel, it's making me mad. I just can't understand why it's added to the JPanel.
Also, the JPanel is surrounded by a border, and when I click or paint something it adds a new vertical borderline somewhere on the panel, it's random every time.
Code for the two classes:
public class mainepanel extends JPanel implements MouseMotionListener, MouseListener{
Graphics globalGraphics;
int clickCount = 0;
public mainepanel(){
setBorder(BorderFactory.createLineBorder(Color.black));
setPreferredSize(new DimensionUIResource(200,200));
addMouseMotionListener(this);
addMouseListener(this);
validate();
setFocusable(true);
}
public void paintComponent(Graphics g){
globalGraphics = g.create();
}
#Override
public void mouseDragged(MouseEvent e) {
globalGraphics.fillOval(e.getX(), e.getY(), 10,10);
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
clickCount ++;
maine.setLabel(clickCount);
globalGraphics.fillOval(e.getX(), e.getY(), 10,10);
repaint();
}
maine
public class maine extends JFrame{
static JLabel label;
public maine(){
setSize(600,400);
setDefaultCloseOperation(3);
setResizable(false);
label = new JLabel("Clicks:");
setLayout(new FlowLayout());
add(label);
add(new mainepanel());
setVisible(true);
}
public static void setLabel(int clicks){
label.setText("Clicks: " + clicks);
}
public static void main(String[]args){
new maine();
}
}
Perform all the drawing within paintComponent (and be sure to call super.paintComponent) - the MouseListener/MouseMotionListener should only need to change the data model (and if necessary call repaint so the UI reflects the change).
A simple example below with a single circle created with a Mouse click, and moved with a mouse dragged:
Point center = null;
...
#Override
public void mouseClicked(MouseEvent e){
center = e.getPoint();
repaint();
}
#Override
public void mouseDragged(MouseEvent e){
center = e.getPoint();
repaint();
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if ( center != null ){
g.fillOval(center.getX(), center.getY(), 10, 10);
}
}

repaint() is not working

I want to draw circle and align it to center, but when I am calling repaint() nothing happens. I tried almost everything, I have changed layouts, alignments, but always the same. This is my code:
public class Frame extends JFrame {
JButton button,dugme;
JLabel lab;
public Frame(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(480,320);
setResizable(false);
setLocationRelativeTo(null);
setLayout(new FlowLayout());
setVisible(true);
button = new JButton("Klikni me");
button.setSize(75,75);
add(button);
button.setHorizontalAlignment(SwingConstants.RIGHT);
dugme= new JButton("Klikni opet");
dugme.setSize(75,75);
add(dugme);
dugme.setHorizontalAlignment(SwingConstants.LEFT);
lab = new JLabel("Ovde je tekst koji se menja");
add(lab);
lab.setHorizontalAlignment(SwingConstants.CENTER);
Handler handler = new Handler();
Handler1 handler1= new Handler1();
repaint();
button.addActionListener(handler);
dugme.addActionListener(handler1);
}
public void paintComponent(Graphics g){
super.paintComponents(g);
g.fillOval(30, 30, 60, 75);
}
public class Handler implements ActionListener{
public void actionPerformed(ActionEvent e){
repaint();
lab.setText("New text");
}
}
public class Handler1 implements ActionListener{
public void actionPerformed(ActionEvent e){
lab.setText("Same text again ");
repaint();
}
}
}
public void paintComponent(Graphics g){
super.paintComponents(g);
Breaks the paint chain, it should be:
public void paintComponent(Graphics g){
super.paintComponent(g); // no S in method name..

Categories