Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Can anyone give me some information what did I do wrong? Program runs but drowing a rectangle or anything else doesnt work. There is just empty space on the middle. I tried open the program from terminal and eclipse on kubuntu 15 and windows. Always with the same result.
I m just starting my adventure with java so please be patient.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyGUI {
JFrame frame;
JLabel label;
public static void main(String[] args)
{
MyGUI gui = new MyGUI();
gui.go();
}
public void go()
{
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton labelButton = new JButton("Change label");
labelButton.addActionListener(new LabelListener());
JButton colorButton = new JButton("Change color");
colorButton.addActionListener(new ColorListener());
label = new JLabel("LABEL");
DrawSmth2 drawPanel = new DrawSmth2();
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);
frame.setSize(680,480);
frame.setVisible(true);
}
class LabelListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
label.setText("DONE");
}
}
class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
public class DrawSmth2 extends JPanel{
public void PaintComponent(Graphics g)
{
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
}
Java is case-sensitive which means that PaintComponent is not the same as paintComponent. To avoid such problems always add #Override annotation to methods you want to override (if you are not overriding existing method compiler will inform you about it - more info: When do you use Java's #Override annotation and why?).
Also don't forget to call super.paintComponent(g); at start of your own implementation of paintComponent to let Swing perform standard operations needed to properly paint this component.
Just add gloabal variable count;
int count=0;
class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
count++;
frame.repaint();
}
}
public class DrawSmth2 extends JPanel{
public void paintComponent(Graphics g)
{
if(count%2==1)
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
Question: Write JFrame that when you press the "start" button draws, and keep drawing random colored and sized filled ovals until the "stop" button is pressed.
Problem: loop inside the actionPerformed method() Doesn't Work.
The Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class p6 extends JFrame implements ActionListener
{
String str;
JButton start,stop;
int h=0,w=0;
p6()
{
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1500,1000);
start= new JButton("Start");
stop= new JButton("Stop");
setLayout(null);
start.setBounds(500, 50, 100,30);
stop.setBounds(610, 50, 100,30);
add(start);
add(stop);
start.addActionListener(this);
stop.addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
String c=ae.getActionCommand();
if(c=="Start")
{
while(c!="Stop")
{
h+=20;
w+=20;
}
repaint();
}
str=" "+h+" "+w;
}
public void paint(Graphics g)
{
super.paintComponents(g);
g.drawString(str, 100, 100);
//g.drawOval(100, 100, 100, 100);
g.drawOval((int)Math.random()*2000,(int) Math.random()*2000, w,h);
}
public static void main(String[] args)
{
new p6();
}
}
Let's start with How do I compare strings in Java?. This is pretty basic Java 101 and something you REALLY need to understand.
The move onto Concurrency in Swing. Swing is a single threaded. This means that any long running or blocking operations executed within the context of the Event Dispatching Thread will cause the app to "hang" and prevent any further possible updates or interaction.
Swing is also not thread safe, which means that you should only ever update the UI or state the UI depends on, from within the context of the Event Dispatching Thread.
This might seem like a dilemma, but Swing also provides a useful tool to help work with these constraints, see How to user Swing Timer for more details.
Swing also has a well defined and documented painting process, see Painting in AWT and Swing and Performing Custom Painting to get a better understand of how painting works in Swing and how you're suppose to work with it
It is generally recommended not to override the paint method of top level containers (like JFrame). These tend to be composite components and trying to paint on them tends to end up not working very well.
Image from How to Use Root Panes
And you really should make the time to learn how to use layout managers, see Laying Out Components Within a Container. They will save many hours of frustration. The following examples makes use of both a BorderLayout and CardLayout.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private CardLayout cardLayout;
private JPanel showPane;
private DrawingPane drawingPane;
public TestPane() {
setLayout(new BorderLayout());
cardLayout = new CardLayout();
showPane = new JPanel(cardLayout);
showPane.add(new EmptyPane(), "Empty");
drawingPane = new DrawingPane();
showPane.add(drawingPane, "Drawing");
cardLayout.show(showPane, "Empty");
add(showPane);
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
stopButton.setEnabled(false);
JPanel actionsPane = new JPanel();
actionsPane.add(startButton);
actionsPane.add(stopButton);
add(actionsPane, BorderLayout.SOUTH);
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(false);
stopButton.setEnabled(true);
drawingPane.start();
cardLayout.show(showPane, "Drawing");
}
});
stopButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(true);
stopButton.setEnabled(false);
drawingPane.stop();
cardLayout.show(showPane, "Empty");
}
});
}
}
public class EmptyPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public class DrawingPane extends JPanel {
private int h = 0, w = 0;
private Timer timer;
private Random rnd = new Random();
public DrawingPane() {
}
public void start() {
if (timer == null) {
timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
h += 20;
w += 20;
repaint();
}
});
}
timer.start();
}
public void stop() {
if (timer != null) {
timer.stop();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
int x = 0;
int y = 0;
if (w < getWidth() && h < getHeight()) {
x = rnd.nextInt(0, getWidth() - w);
y = rnd.nextInt(0, getHeight() - w);
}
g2d.drawOval(x, y, w, h);
g2d.dispose();
}
}
}
Why make use of CardLayout?
Based on the original code, when not painting, nothing is shown. So I made use of a CardLayout to switch to an "empty" state. Now, it wouldn't be very hard to derive a model to hold the state information and share that between the "empty" and "running" states and show something different on the "empty" state. Equally, we could make use of the glassPane, but I think we're drifting of course.
The purpose is to demonstrate ONE possible solution for showing different states.
Why use two different panes?
First, we don't "need" EmptyPane, we could get away with just an instance of JPanel, but, if you wanted to display something else when not drawing, this is one approach you could take.
The original code had a if statement which means that when not drawing, nothing is painted, so why waste the time and instead just show a "empty" pane instead.
Again, this is just a demonstration of one possible solution.
You have to add these lines before actionPerformed method,
start.setActionCommand("start");
stop.setActionCommand("stop");
I'm new here. Been reading questions and answers for aeons. Recently I found time to start studying Java, and I'm seriously enjoying the process. Until I started to write some code. The getting stuck is killing me. So I've come to seek advice on something extremely simple but I cannot crack it.
The code below attempts to create a frame, maximize it, and place elements inside. I was just fooling around. First the button1, I tried to change its size (so I got it into a FlowLayout). Then a button in the mainPanel, just to... try. Then an oval. I tried for 2 hours to get the oval to display but it is Impossible. When I found about "drawOval" I thought that was it but it made no difference. And to think that I was planning for the button1 to create Moving Balls. I'm so, So far away from that.
Please, why does the silly Oval refuse to display itself. Help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainClass {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JPanel southPanel = new JPanel();
JButton button1 = new JButton("Button1");
JButton button2 = new JButton("Button2");
Oval oval = new Oval();
public static void main(String[] args) {
MainClass program = new MainClass();
program.go();
}
public void go() {
buildGUI();
}
public void buildGUI() {
button1.setBorder(BorderFactory.createMatteBorder(2,2,2,2, Color.BLACK));
button1.addActionListener(new Button1Listener());
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
button1.setPreferredSize(new Dimension(200, 50));
frame.getContentPane().add(BorderLayout.SOUTH, southPanel);
southPanel.add(button1);
mainPanel.add(button2);
mainPanel.add(oval);
frame.setSize(400, 400);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class Button1Listener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
//What the button will do.
}
}
}
And the Oval part
import java.awt.*;
import javax.swing.*;
public class Oval extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.orange);
g.fillOval(20, 50, 100, 100);
}
}
JPanel uses a FlowLayout by default. Since you Oval class doesn't provide any sizing hints, then it's set to a default size of 0x0.
Start by updating your class to something more like...
public class Oval extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 150);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.orange);
g.fillOval(20, 50, 100, 100);
}
}
to create Moving Balls.
Ok, you might want to have a look at:
java bounceBall mouse escape
paintComponent not working
This question already has answers here:
Swing - paintComponent method not being called
(2 answers)
Closed 5 years ago.
I am trying to draw a simple rectangle but I think the paintComponent method is not getting called.
Here is the code for the class with main method:
package painting;
import java.awt.*;
import javax.swing.*;
public class Painting {
public static void main(String[] args) {
JFrame jf;
jf = new JFrame("JUST DRAW A RECTANGLE");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(null);
jf.setLocationRelativeTo(null);
jf.setSize(600,600);
jf.setVisible(true);
Mainting maint = new Mainting();
jf.add(maint);
}
}
and the class with paintComponent()
package painting;
import java.awt.*;
import javax.swing.*;
public class Mainting extends JPanel {
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(0, 0 , 200, 200);
System.out.println("haha");
g.setColor(Color.red);
}
}
What is the problem here, I cannot figure out...
While the answers already provided might have resulted in the rectangle appearing, the approach was less than optimal. This example aims to show a better approach. Read the comments in the code for details.
Note that Swing/AWT GUIs should be started on the EDT. This is left as an exercise for the reader.
import java.awt.*;
import javax.swing.*;
public class Painting {
public static void main(String[] args) {
JFrame jf = new JFrame("JUST DRAW A RECTANGLE");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// null layouts cause more problems than they solve. DO NOT USE!
//jf.setLayout(null);
jf.setLocationRelativeTo(null);
/* if components return a sensible preferred size,
it's better to add them, then pack */
//jf.setSize(600, 600);
//jf.setVisible(true); // as mentioned, this should be last
Mainting maint = new Mainting();
jf.add(maint);
jf.pack(); // makes the GUI the size it NEEDS to be
jf.setVisible(true);
}
}
class Mainting extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(10, 10, 200, 200);
System.out.println("paintComponent called");
/* This does nothing useful, since nothing is painted
before the Graphics instance goes out of scope! */
//g.setColor(Color.red);
}
#Override
public Dimension getPreferredSize() {
// Provide hints to the layout manager!
return new Dimension(220, 220);
}
}
Try setting your layout manager to eg. BorderLayout
so use
jf.setLayout(new BorderLayout());
and then add your component with some constraints
Mainting maint = new Mainting();
jf.add(maint,BorderLayout.CENTER);
I am trying to get my hands on GUI programming in java and wanted to draw a rectangle in Jpanel. Code does not give any error but I cannot get rectangle in the GUI. Can somebody please tell me what I am missing in the following code. I am sure it is pretty simple so please be gentle.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloWorldGUI2 {
private static class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
private static class RectDraw extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}
}
public static void main(String[] args) {
JPanel content = new JPanel();
RectDraw newrect= new RectDraw();
JButton okButton= new JButton("OK");
JButton clearButton= new JButton("Clear");
ButtonHandler listener= new ButtonHandler();
okButton.addActionListener(listener);
clearButton.addActionListener(listener);
content.add(okButton);
content.add(clearButton);
content.add(newrect);
JFrame window = new JFrame("GUI Test");
window.setContentPane(content);
window.setSize(250,100);
window.setLocation(100,100);
window.setVisible(true);
}
}
Your newrect RectDraw's size is likely going to be quite small, probably [0, 0], since it has been added to a FlowLayout using JPanel and doesn't have a preferredSize set. Consider overriding its getPreferredSize() method and returning a suitable Dimension so that its drawing can be seen.
private static class RectDraw extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H); // appropriate constants
}
}
Also,
The paintComponent method should be protected, not public
Don't forget to use #Override before your method overrides.
Aim for much less code in the main method and more code in the "instance" world, not the static world.
Take care with your code formatting. Poor code formatting, especially misleading indentations, leads to silly errors.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Marquee effect in Java Swing
I am trying to obtain marquee effect (the same we have in html). But I am unable to do so with this code. How can I improve this code to obtain marquee effect?
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
class tester {
JLabel l;
tester() {
JFrame fr=new JFrame();
JPanel p=new JPanel();
l=new JLabel("");
fr.add(p);
p.add(l);
fr.setVisible(true);
fr.setSize(400,400);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void MarqueeEffect() {
ActionListener ac = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
l.setText("To action alone hast thou a right and never at all to its fruits let not the fruits of action be thy motive; neither let there be in thee any attachment to inaction");
}
};
new Timer(2000,ac).start();
}
public static void main(String args[]) {
tester t=new tester();
t.MarqueeEffect();
}
}
You will have to extend JLabel and override paintComponent to bring marquee effect. It wont come just by setting text to it without extending JLabel. You can do something like this in your customized JLabel class.
protected void paintComponent(Graphics g)
{
g.translate((int)((System.currentTimeMillis() / MARQUEE_SPEED_DIV) % (getWidth() * 2)) - getWidth(), 0);
super.paintComponent(g);
repaint(REPAINT_WITHIN_MS);
}