1

How do/can you override methods from non-inherited class? Secondly is there a better term than "non-inherited classes"?

I have a class that "extends" JFrame and needs to override paintComponent from JPanel. How? Or it can extend JPanel and needs to access methods like setTitle(), setResizable(), and setDefaultCloseOperation();

In response to the latest answer:

i've done this:

public class Chess extends JPanel {

boolean du, dd, dl, dr;
double x, y;
public class AL extends KeyAdapter {

    public void keyPressed(KeyEvent e) {
        int keyC = e.getKeyCode();
        switch(keyC) {
            case KeyEvent.VK_LEFT:
                dl = true;
                break;
            case KeyEvent.VK_RIGHT:
                dr = true;
                break;
            case KeyEvent.VK_DOWN:
                dd = true;
                break;
            case KeyEvent.VK_UP:
                du = true;
                break;
        }

    }
    public void keyReleased(KeyEvent e) {
         int keyC = e.getKeyCode();
        switch(keyC) {
            case KeyEvent.VK_LEFT:
                dl = false;
                break;
            case KeyEvent.VK_RIGHT:
                dr = false;
                break;
            case KeyEvent.VK_DOWN:
                dd = false;
                break;
            case KeyEvent.VK_UP:
                du = false;
                break;
        }
    }
}

public void Chess() {
    JFrame frame = new JFrame();
    frame.addKeyListener(new AL());
    frame.setTitle("Chess");
    frame.setSize(500, 500);
    frame.setResizable(false);
    frame.setVisible(true);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    du = dl = dd = dr = false;
    x = y = 150;

}

public void paintComponent(Graphics g) {

    super.paintComponent(g);

    setBackground(Color.CYAN);


    double i = .25;
    if (du) {
        y -= i;
    }
    if (dr) {
        x += i;
    }
    if (dd) {
        y += i;
    }
    if (dl) {
        x -= i;
    }

    if (x < 0) {
        x = 0;
    }
    if (x > getWidth() - 25) {
        x = getWidth() - 25;
    }
    if (y < 25) {
        y = 25;
    }
    if (y > getHeight() - 25) {
        y = getHeight() - 25;
    }

    g.drawOval( (int) x, (int) y, 25, 25);
    repaint();

}
public static void main(String[] args) {
    new Chess();
}

}

It should move the oval around the screen (I'm trying to get the basics down) but when i run it, a box doesn't appear. It worked when was using jFrame and overrode paint and called a non-overridden paintComponent() from paint(). not what i want to do. Why does a box no longer appear?

Jean Valjean
  • 747
  • 1
  • 9
  • 30

1 Answers1

4
  1. You're allowed to use more than one class when creating Java programs.
  2. So you can have one class extend JFrame
  3. And another extend JPanel -- and have that class's paintComponent method overridden.
  4. Having said that, note that you may be painting yourself in a corner by having your class extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. In fact, I would venture that most of the Swing GUI code that I've created and that I've seen does not extend JFrame, and in fact it is rare that you'll ever want to do this. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding.

For example, here's a simple class that displays mouse position on mouse click:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class MousePosition extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = PREF_W;
    // format String for display String
    protected static final String FORMAT = "(%d, %d)";
    private int xPos = -40;
    private int yPos = -40;
    private String displayText = "";

    public MousePosition() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                xPos = e.getX();
                yPos = e.getY();
                // use FORMAT String to create our display text
                displayText = String.format(FORMAT, xPos, yPos);
                repaint();
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString(displayText, xPos, yPos);

    }

    private static void createAndShowGui() {
        MousePosition mainPanel = new MousePosition();

        JFrame frame = new JFrame("MousePosition");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Regarding

I have a class that "extends" JFrame and needs to override paintComponent from JPanel. How?

As noted above. Note that I avoid setting sizes but instead override the JPanel's getPreferredSize() if I want to force it to a certain size. Then the layout managers do the rest when I call pack() on the JFrame.

Or it can extend JPanel and needs to access methods like setTitle(), setResizable(), and setDefaultCloseOperation()...

Those methods can be simply called on the JFrame instance after you've created it as per my example above.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • @jacob: In your code you never create a top-level window such as a JFrame, and then place the Chess JPanel in that window, so nothing will ever display. Please look again at my code above as I show you exactly how to do this. Also, never call `repaint()` from inside of a `paintComponent` method. Ever. – Hovercraft Full Of Eels Oct 25 '15 at 02:35
  • Also don't call `setBackground(...)` from within paintComponent. That line should be in the class's constructor. – Hovercraft Full Of Eels Oct 25 '15 at 02:36
  • @jacob: I now see that you try to create a JFrame in a constructor, but it's not a real constructor but rather a pseudo-constructor since it has a `void` return type. 1) Get rid of that void -- constructors have no declared return type, and 2) don't create the JFrame in there. Do it in the main method or elsewhere outside of the JPanel's non-static code. – Hovercraft Full Of Eels Oct 25 '15 at 02:38
  • Thank you very much, I finally got it – Jean Valjean Oct 25 '15 at 02:59
  • One last quick thing, when i take the repaint() out, the frame doesn't refresh like it should (i haven't changed anything since i posted the overridden paintComponent() above), why is that? – Jean Valjean Oct 25 '15 at 03:07
  • @jacob: you're using `repaint()` to drive your animation, but it's a dangerous way to do this. Much better is to use a [Swing Timer](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html), and for example, please check out: [Java Animate JLabel](http://stackoverflow.com/a/12545773/522444). – Hovercraft Full Of Eels Oct 25 '15 at 03:11