【问题标题】:Java: Overriding methods from non inherited classesJava:覆盖非继承类的方法
【发布时间】:2016-01-24 08:25:38
【问题描述】:

你如何/可以覆盖非继承类的方法?其次,还有比“非继承类”更好的术语吗?

我有一个“扩展”JFrame 的类,需要从 JPanel 覆盖paintComponent。如何?或者可以扩展JPanel,需要访问setTitle()、setResizable()、setDefaultCloseOperation()等方法;

回应最新回答:

我已经这样做了:

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

}

它应该在屏幕上移动椭圆(我正在尝试了解基础知识)但是当我运行它时,不会出现一个框。它在使用jFrame并覆盖paint并从paint()调用非覆盖paintComponent()时起作用。不是我想做的。为什么不再出现框?

【问题讨论】:

    标签: java swing inheritance methods overriding


    【解决方案1】:
    1. 在创建 Java 程序时,您可以使用多个类。
    2. 所以你可以让一个类扩展 JFrame
    3. 还有另一个扩展 JPanel - 并覆盖该类的 paintComponent 方法。
    4. 话虽如此,但请注意,当您经常需要更大的灵活性时,您可能会通过让您的类扩展 JFrame,从而迫使您创建和显示 JFrame,从而使自己陷入困境。事实上,我敢冒险说,我创建的大部分 Swing GUI 代码扩展了 JFrame,事实上你很少愿意这样做这。更常见的是,您的 GUI 类将用于创建 JPanel,然后可以将其放置到 JFrame 或 JDialogs 或 JTabbedPanes 中,或者在需要时通过 CardLayouts 交换。这将大大增加您的 GUI 编码的灵活性。

    例如,这里有一个简单的类,它显示鼠标点击时的鼠标位置:

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

    关于

    我有一个“扩展”JFrame 的类,需要从 JPanel 覆盖paintComponent。如何?

    如上所述。请注意,我避免设置大小,而是覆盖 JPanel 的 getPreferredSize(),如果我想强制它为某个大小。然后,当我在 JFrame 上调用 pack() 时,布局管理器会完成剩下的工作。

    或者可以扩展JPanel,需要访问setTitle()、setResizable()、setDefaultCloseOperation()等方法...

    按照我上面的示例创建 JFrame 实例后,可以简单地调用这些方法。

    【讨论】:

    • @jacob:在您的代码中,您永远不会创建诸如 JFrame 之类的顶级窗口,然后将 Chess JPanel 放在该窗口中,因此不会显示任何内容。请再次查看我上面的代码,因为我向您展示了如何执行此操作。另外,永远不要从paintComponent 方法内部调用repaint()。永远。
    • 也不要在paintComponent中调用setBackground(...)。该行应该在类的构造函数中。
    • @jacob:我现在看到您尝试在构造函数中创建 JFrame,但它不是真正的构造函数,而是伪构造函数,因为它具有 void 返回类型。 1)摆脱那个 void - 构造函数没有声明的返回类型,并且 2)不要在那里创建 JFrame。在 JPanel 的非静态代码之外的 main 方法或其他地方执行此操作。
    • 非常感谢,终于明白了
    • 最后一件事,当我取出 repaint() 时,框架没有像应有的那样刷新(自从我在上面发布了覆盖的 paintComponent() 以来,我没有改变任何东西),为什么是吗?
    猜你喜欢
    • 2012-11-20
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2013-08-13
    • 2021-05-04
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多