Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

need help or explanation

0 views
Skip to first unread message

Dave

unread,
Dec 22, 2009, 7:56:46 PM12/22/09
to
I'm new to Java and I'm running into a problem I can't figure out.

I have a menu on a screen and I'm also drawing a moving filled oval on it.

When I run the program, I end up with a double menu line. It's as if
the first repaint is shifting the whole display down the size of the menu
line.
The first oval is also shifted down the size of the menu line. The rest of
the oval repaints seem to be where they should be.

Even though I have 2 menu lines, only the top menu works when I
click on it. When I click on "Menu1", I get 2 "first entry" items, one
below the other. See Menu example below.

------------------------------------------------
Menu1 (this menu works when I click on it)
------------------------------------------------
Menu1 (this menu doesn't do anything)
------------------------------------------------

-----------------------------------------------------------
Menu1 (when I click the top menu, I get 2 first entries)
-----------------------------------------------------------
first entry (the lower Menu1 is written over)
-----------------------------------------------------------
first entry
-----------------------------------------------------------

The bad part is, when I run this program at work, it works like
it's supposed to. When I run it at home, I get the double menu.
I haven't tried the program on any other PC's yet.

I'm using JCreator LE version 3.50.013 both at work and home.
My Java version is 1.6.0_17-b04 both at work and home.
I have XP Pro at work, but just XP at home.

Here is the program.

import javax.swing.*;
import java.awt.*;

public class graph1
{
int x = 70;
int y = 70;

public static void main(String[] args)
{
graph1 gui = new graph1();
gui.go();
}

public void go()
{
JMenuBar mBar = new JMenuBar();
JMenu mMenu1 = new JMenu("Menu1");
JMenuItem mItem = new JMenuItem("first entry");

mBar.add(mMenu1);
mMenu1.add(mItem);

JFrame frame = new JFrame("Graph1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(mBar);

MyPaint mp = new MyPaint();
frame.getContentPane().add(mp);

frame.setSize(600,600);
frame.setVisible(true);

for ( int i = 0; i < 200; i++ )
{
++x;
++y;

try
{
Thread.sleep(200);
}
catch(Exception ex) {}

mp.repaint();
}
}

class MyPaint extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(Color.green);
g.fillOval(x,y,40,40);
}
}
}


John B. Matthews

unread,
Dec 22, 2009, 8:50:52 PM12/22/09
to
In article <jLGdnTFE1sd696zW...@posted.oberlin>,
"Dave" <non...@none456.net> wrote:

First, you need to construct your GUI on the Even Dispatch Thread (EDT),
otherwise your program may exhibit various such anomalies on different
platforms:

<http://java.sun.com/docs/books/tutorial/uiswing/concurrency/initial.html>

Having done that, you must not then block the EDT with time-consuming
operations. Here's a modified version of your program that uses a Swing
Timer to periodically repaint the panel:

package news;

import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;

public class Graph1 extends JFrame implements ActionListener {

private final Timer timer = new Timer(200, this);
private final MyPaint mp = new MyPaint();
private int x = 70;
private int y = 70;

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Graph1();
}
});
}

public Graph1() {
super("Graph1");


JMenuBar mBar = new JMenuBar();
JMenu mMenu1 = new JMenu("Menu1");
JMenuItem mItem = new JMenuItem("first entry");

mBar.add(mMenu1);
mMenu1.add(mItem);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setJMenuBar(mBar);
this.add(mp);
this.pack();
this.setVisible(true);
timer.start();
}

@Override
public void actionPerformed(ActionEvent e) {
x++; y ++;
mp.repaint();
}

private class MyPaint extends JPanel {

public MyPaint() {
this.setPreferredSize(new Dimension (600, 600));
}

@Override


public void paintComponent(Graphics g) {
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}

See also, <http://zetcode.com/tutorials/javagamestutorial/>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

markspace

unread,
Dec 22, 2009, 8:58:46 PM12/22/09
to
Dave wrote:

> The bad part is, when I run this program at work, it works like
> it's supposed to. When I run it at home, I get the double menu.
> I haven't tried the program on any other PC's yet.


I see the double menus too. I have Vista Ultimate, and Java 1.6 update
17 also. Good job on the sample code btw, you're light-years ahead of
most of the new posters we get around here.

I see two big problems which may be affecting this. First, you
absolutely have to use proper synchronization when dealing with Swing
components. Otherwise, all bets are off. You call methods which are
not thread safe directly from your "main" method, which could be causing
all sorts of errors.

<http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html>

The second thing that I notice that if Thread.sleep() is called on the
EDT, well, you're going to be really unhappy about that. So I
substituted a Swing Timer instead.

What actually fixed the funny display is calling repaint() on the whole
frame instead of just the component. Swing likes to layout whole
components, just trying to update part of one may not work I suppose.

Finally, pay attention to coding standards. Class names should begin
with a capital letter. If this code is from work, I'd think you'd want
to be a bit more rigorous about adhering to standards.

My version follows:


package test;

import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;

public class Main {


public static void main(String[] args) {

graph1.main( args );
}

}

class graph1
{
int x = 70;
int y = 70;

public static void main(String[] args)
{

SwingUtilities.invokeLater( new Runnable() {
public void run() {


graph1 gui = new graph1();
gui.go();
}
} );
}

public void go()
{
JMenuBar mBar = new JMenuBar();
JMenu mMenu1 = new JMenu("Menu1");
JMenuItem mItem = new JMenuItem("first entry");

mBar.add(mMenu1);
mMenu1.add(mItem);

final JFrame frame = new JFrame("Graph1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(mBar);

final MyPaint mp = new MyPaint();
frame.getContentPane().add(mp);

frame.setSize(600,600);
frame.setVisible(true);

ActionListener sprite = new ActionListener() {

public void actionPerformed(ActionEvent e) {
++x;
++y;
frame.repaint();
}
};

Timer spriteTimer = new Timer(200, sprite);
spriteTimer.setInitialDelay( 400 );
spriteTimer.start();

Knute Johnson

unread,
Dec 22, 2009, 9:05:58 PM12/22/09
to

Minimum to make your work:

import javax.swing.*;
import java.awt.*;

public class graph1 implements Runnable


{
int x = 70;
int y = 70;

MyPaint mp;

public static void main(String[] args)
{

EventQueue.invokeLater(new Runnable() {
public void run() {


graph1 gui = new graph1();
gui.go();

new Thread(gui).start();
}
});
}

public void go()
{
JMenuBar mBar = new JMenuBar();
JMenu mMenu1 = new JMenu("Menu1");
JMenuItem mItem = new JMenuItem("first entry");

mBar.add(mMenu1);
mMenu1.add(mItem);

JFrame frame = new JFrame("Graph1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(mBar);

mp = new MyPaint();
frame.getContentPane().add(mp);

frame.setSize(600,600);
frame.setVisible(true);
}

public void run() {

for ( int i = 0; i < 200; i++ )
{
++x;
++y;

try
{
Thread.sleep(200);
}
catch(Exception ex) {}

mp.repaint();
}
}

class MyPaint extends JPanel
{
public void paintComponent(Graphics g)
{

g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.green);
g.fillOval(x,y,40,40);
}
}
}


Better example and a few goodies thrown in:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GraphOne extends JPanel implements ActionListener, Runnable {
private int x,y;
private int deltaX = 1;
private int deltaY = 1;

public GraphOne() {
setBackground(Color.WHITE);
setForeground(Color.GREEN);
setPreferredSize(new Dimension(400,300));
}

public void actionPerformed(ActionEvent ae) {
String ac = ae.getActionCommand();
if (ac.equals("Quit"))
System.exit(0);
}

public void run() {
while (true) {
x += deltaX;
y += deltaY;
if (x >= getWidth()-40 || x <= 0)
deltaX = -deltaX;
if (y >= getHeight()-40 || y <=0)
deltaY = -deltaY;
repaint();
try { Thread.sleep(10);
} catch (InterruptedException ie) { }
}
}

public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getBackground());
g2d.fillRect(0,0,getWidth(),getHeight());
g2d.setColor(getForeground());
g2d.fillOval(x,y,40,40);
}

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("GraphOne");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphOne g1 = new GraphOne();
JMenuBar mb = new JMenuBar();
JMenu file = new JMenu("File");
JMenuItem quit = new JMenuItem("Quit");
f.setJMenuBar(mb);
mb.add(file);
file.add(quit);
quit.addActionListener(g1);
f.add(g1,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
new Thread(g1).start();
}
});
}
}

--

Knute Johnson
email s/nospam/knute2010/


--
Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
------->>>>>>http://www.NewsDemon.com<<<<<<------
Unlimited Access, Anonymous Accounts, Uncensored Broadband Access

Roedy Green

unread,
Dec 22, 2009, 9:19:54 PM12/22/09
to
On Tue, 22 Dec 2009 19:56:46 -0500, "Dave" <non...@none456.net>
wrote, quoted or indirectly quoted someone who said :

>Thread.sleep(200);

You must never put the EDT threat to sleep. Otherwise Swing can't
process events. Use a Timer, or do your sleeping on some other
thread.

See http://mindprod.com/jgloss/timer.html
--
Roedy Green Canadian Mind Products
http://mindprod.com
If you think it�s expensive to hire a professional to do the job, wait until you hire an amateur.
~ Red Adair (born: 1915-06-18 died: 2004-08-07 at age: 89)

Dave

unread,
Dec 22, 2009, 9:28:11 PM12/22/09
to
John;

Thanks for the response.

I tried compiling the program, but I get errors on the first @Override,
at super("Graph1"), and the @Override after that.

The two @Override give "method does not override a method from its
superclass".
The super("Graph1") gives "call to super must be first statement in
constructor".

I don't know what the @Override is supposed to do, but I'll look at
the links you provided and see if I can get anything out of them.

Dave.


"John B. Matthews" <nos...@nospam.invalid> wrote in message
news:nospam-D5E9CD....@news.aioe.org...

Dave

unread,
Dec 22, 2009, 9:45:53 PM12/22/09
to
Thanks for the reply.

In my program, if I replaced mp.repaint() with frame.repaint()
the program works OK. But my original intent was not to clear
the previous draws. This program is a simple version, to keep it
small, of another program that I'm writing. In that program I don't
want to clear the previous draws on the screen, but I want to leave a trail.


"markspace" <nos...@nowhere.com> wrote in message
news:hgrtgq$hq5$1...@news.eternal-september.org...

John B. Matthews

unread,
Dec 22, 2009, 9:49:16 PM12/22/09
to
In article <ycOdnfcNP4LYHazW...@posted.oberlin>,
"Dave" <non...@none456.net> wrote:

> Thanks for the response.
>
> I tried compiling the program, but I get errors on the first
> @Override, at super("Graph1"), and the @Override after that.
>
> The two @Override give "method does not override a method from its
> superclass". The super("Graph1") gives "call to super must be first
> statement in constructor".
>
> I don't know what the @Override is supposed to do, but I'll look at
> the links you provided and see if I can get anything out of them.

Your java compiler may not recognize the annotation; just comment them
out for now. Introduced in Java 1.5 to catch incorrect signatures in
overridden methods, the usage was expanded to include implemented
interfaces in 1.6:

<http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html>
<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html>
<http://mindprod.com/jgloss/annotations.html>

Also, compare my variation to those of markspace and Knute Johnson. Like
mine, the former uses Timer; the latter uses a separate thread. The
example link discusses both:

markspace

unread,
Dec 22, 2009, 10:20:50 PM12/22/09
to
Dave wrote:
> Thanks for the reply.
>
> In my program, if I replaced mp.repaint() with frame.repaint()
> the program works OK. But my original intent was not to clear
> the previous draws. This program is a simple version, to keep it
> small, of another program that I'm writing. In that program I don't
> want to clear the previous draws on the screen, but I want to leave a trail.


If you want to leave a trail, you need to save your previous draw
commands. Make the updates to an Image, then blit the image to the
screen when you paint the panel.

You have to redraw the background or you'll lose your previous draws
commands the first time the app is minimized (try it and see), and on
some systems as soon as it's covered by another app.

Lew

unread,
Dec 22, 2009, 11:48:52 PM12/22/09
to
Dave wrote:
>> Thanks for the response.
>>
>> I tried compiling the program, but I get errors on the first
>> @Override, at super("Graph1"), and the @Override after that.
>>
>> The two @Override give "method does not override a method from its
>> superclass". The super("Graph1") gives "call to super must be first
>> statement in constructor".
>>
>> I don't know what the @Override is supposed to do, but I'll look at
>> the links you provided and see if I can get anything out of them.

John B. Matthews wrote:
> Your java compiler may not recognize the annotation; just comment them

Of course his compiler recognized the annotation. How else would it have
known that the annotation was placed not upon a method from the superclass?

> out for now. Introduced in Java 1.5 to catch incorrect signatures in
> overridden methods, the usage was expanded to include implemented
> interfaces in 1.6:
>
> <http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html>
> <http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html>
> <http://mindprod.com/jgloss/annotations.html>
>
> Also, compare my variation to those of markspace and Knute Johnson. Like
> mine, the former uses Timer; the latter uses a separate thread. The
> example link discusses both:
>
> <http://zetcode.com/tutorials/javagamestutorial/>

He's using @Override in constructors, which makes no sense and is wrong.

He's using @Override in the body of the constructor, which also makes no sense
and is wrong.

If you actually read the documentation on annotations.

<http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.7>

you see that there are only certain places you can use them, and they are all
declarations, not invocations.

In future, Dave, when asking for help with code you wrote, it pays to show the
code about which you're asking. Else how is one to know that '@Override' was
inside the body of the constructor instead of atop the declaration of a method?

--
Lew

John B. Matthews

unread,
Dec 23, 2009, 12:11:00 PM12/23/09
to
In article <hgs7fl$146$1...@news.albasani.net>, Lew <no...@lewscanon.com>
wrote:

> Dave wrote:
> >> Thanks for the response.
> >>
> >> I tried compiling the program, but I get errors on the first
> >> @Override, at super("Graph1"), and the @Override after that.
> >>
> >> The two @Override give "method does not override a method from its
> >> superclass". The super("Graph1") gives "call to super must be
> >> first statement in constructor".
> >>
> >> I don't know what the @Override is supposed to do, but I'll look
> >> at the links you provided and see if I can get anything out of
> >> them.
>
> John B. Matthews wrote:
> > Your java compiler may not recognize the annotation; just comment
> > them
>
> Of course his compiler recognized the annotation. How else would it
> have known that the annotation was placed not upon a method from the
> superclass?

Good question: His compiler did not recognize the annotations as
applicable to either of the two implemented interface methods in my
example, run() and actionPerformed(). It did recognize the single
overridden method, paintComponent(). Together, these are pathognomonic
of the implementation in Java 1.5.

I am unable to explain the super failure; @Override does not appear in
the constructor, which extends JFrame. As an instructive contrast,
markspace's example extends JPanel:

<http://groups.google.com/group/comp.lang.java.programmer/msg/cdc97be27c89ad0a>

[...]

> He's using @Override in constructors, which makes no sense and is
> wrong. He's using @Override in the body of the constructor, which
> also makes no sense and is wrong.

He never used @Override; I did. My usage is correct for Java 1.6
but fails under Java 1.5:

<http://groups.google.com/group/comp.lang.java.programmer/msg/3a6918190945a2a1>

> If you actually read the documentation on annotations.
>
> <http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.7>
>
> you see that there are only certain places you can use them, and they
> are all declarations, not invocations.

Indeed. Here is a previous discussion:

<http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/f3b21ed1083a3f75>

[...]

Dave

unread,
Dec 23, 2009, 7:45:45 PM12/23/09
to
Thanks to all for your comments and help.

I have plenty of links to look at and suggestions to try.

Dave.


"Dave" <non...@none456.net> wrote in message
news:jLGdnTFE1sd696zW...@posted.oberlin...

0 new messages