java - 在Java中调用类中的方法

标签 java swing jpanel awt

我有一个非常基本的问题:我的 MainDriver 类希望在按下 Line 按钮时运行 Line 类;但是,我知道我们无法运行整个类(class),所以如果有其他方法来实现这一点,请告诉我。

以下是MainDriver类;我已经用星号突出显示了相关部分。

package javafx.scene;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
//import java.awt.*;
class MainDriver extends JFrame implements ActionListener { 
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    // create a frame 
    static JFrame frame; 


    // main function 
    public static void main(String args[]) 
    { 
        // create a frame 
        frame = new JFrame("DrawShapes"); 

        try { 
            // set look and feel 
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
        } 
        catch (Exception e) { 
            System.err.println(e.getMessage()); 
        } 

        // create a object of class 
        Line line = new Line(); 

        // create number buttons and some operators 
        JButton b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bs, bd, bm, be, beq; 

        // create number buttons 
        b0 = new JButton("line"); 
        b1 = new JButton("circle"); 
        b2 = new JButton("triangle"); 
        b3 = new JButton("rectangle"); 
        b4 = new JButton("quadrilateral"); 
        b5 = new JButton("move"); 
        b6 = new JButton("copy"); 
        b7 = new JButton("delete"); 
        b8 = new JButton("random"); 
        b9 = new JButton("import");
        ba = new JButton("export"); 
        bs = new JButton(""); 
        bd = new JButton("/"); 
        bm = new JButton("*"); 
        beq = new JButton("C"); 

        // create . button 
        be = new JButton("."); 

        // create a panel 
        JPanel p = new JPanel(); 

        // add action listeners 
        b0.addActionListener(line); 
   //add more later 


        // add elements to panel 
        p.add(b0); 
        p.add(ba); 
        p.add(b1); 
        p.add(b2); 
        p.add(b3); 
        p.add(bs); 
        p.add(b4); 
        p.add(b5); 
        p.add(b6); 
        p.add(bm); 
        p.add(b7); 
        p.add(b8); 
        p.add(b9); 
        p.add(bd); 
        p.add(be); 
        p.add(b0); 
        p.add(beq); 


        // set Background of panel 
        p.setBackground(Color.blue); 

        // add panel to frame 
        frame.add(p); 

        frame.setSize(450, 400); 

    } 
    public void actionPerformed(ActionEvent e) 
    { 
        String s = e.getActionCommand(); 
            *************************
            if (s.equals("line")) {
                //Im not sure how to implement the object here
            }
            ***************************


        } 

} 

这是 Line

package javafx.scene;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class Line extends JPanel implements MouseListener,ActionListener{

    private int x,y,x2,y2,a=1;
    public Line(){
        super();
        addMouseListener(this);   
    }

    public void paint(Graphics g){
        int w = x2 - x ;
        int h = y2 - y ;
        int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0 ;
        if (w<0) dx1 = -1 ; else if (w>0) dx1 = 1 ;
        if (h<0) dy1 = -1 ; else if (h>0) dy1 = 1 ;
        if (w<0) dx2 = -1 ; else if (w>0) dx2 = 1 ;
        int longest = Math.abs(w) ;
        int shortest = Math.abs(h) ;
        if (!(longest>shortest)) {
            longest = Math.abs(h) ;
            shortest = Math.abs(w) ;
            if (h<0) dy2 = -1 ; else if (h>0) dy2 = 1 ;
            dx2 = 0 ;            
        }
        int numerator = longest >> 1 ;
        for (int i=0;i<=longest;i++) {
            g.fillRect(x,y,1,1);
            numerator += shortest ;
            if (!(numerator<longest)) {
                numerator -= longest ;
                x += dx1 ;
                y += dy1 ; 
            } else {
                x += dx2 ;
                y += dy2 ;
            }
        }
    }

    public void mouseClicked(MouseEvent mouse) {
        if (a == 1) {
            a = 0;
            x = x2 = mouse.getX();
            y = y2 = mouse.getY();
        } else {
            a = 1;
            x = x2;
            y = y2;
            x2 = mouse.getX();
            y2 = mouse.getY();
            repaint();
        }
    }

    public void mouseEntered(MouseEvent mouse){ }   
    public void mouseExited(MouseEvent mouse){ }
    public void mousePressed(MouseEvent mouse){ }
    public void mouseReleased(MouseEvent mouse){ }


    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
}

最佳答案

以下是有关如何进行操作的示例:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;

public class Main {

    private static void drawPoint(final Graphics g, final Point p) {
        g.drawLine(p.x - 10, p.y, p.x + 10, p.y);
        g.drawLine(p.x, p.y - 10, p.x, p.y + 10);
    }

    private static void drawLine(final Graphics g, final Point p1, final Point p2) {
        g.drawLine(p1.x, p1.y, p2.x, p2.y);
    }

    public static interface ShapeByPoints {
        int getPointCount();
        void draw(final Graphics g, final Point... points);
    }

    public static class DrawPanel extends JPanel {
        private final ArrayList<Point> points;
        private ShapeByPoints s;

        public DrawPanel() {
            points = new ArrayList<>();
            s = null;
        }

        public void setShape(final ShapeByPoints s) {
            this.s = s;
            points.clear();
            repaint();
        }

        public void modifyLastPoint(final Point p) {
            points.get(points.size() - 1).setLocation(p);
            repaint();
        }

        public void addPoint(final Point p) {
            if (s != null && points.size() == s.getPointCount())
                points.clear();
            points.add(p);
            repaint();
        }

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            if (s != null && s.getPointCount() == points.size())
                s.draw(g, points.toArray(new Point[s.getPointCount()]));
            else {
                points.forEach(p -> drawPoint(g, p));
                for (int i = 1; i < points.size(); ++i)
                    drawLine(g, points.get(i - 1), points.get(i));
            }
        }
    }

    public static class EllipseByPoints implements ShapeByPoints {
        @Override
        public int getPointCount() {
            return 2;
        }

        @Override
        public void draw(final Graphics g, final Point... points) {
            g.drawOval(Math.min(points[0].x, points[1].x), Math.min(points[0].y, points[1].y), Math.abs(points[1].x - points[0].x), Math.abs(points[1].y - points[0].y));
        }
    }

    public static class PolygonByPoints implements ShapeByPoints {
        private final int points;

        public PolygonByPoints(final int points) {
            this.points = points;
        }

        @Override
        public int getPointCount() {
            return points;
        }

        @Override
        public void draw(final Graphics g, final Point... points) {
            for (int i = 1; i < this.points; ++i)
                drawLine(g, points[i - 1], points[i]);
            drawLine(g, points[this.points - 1], points[0]);
        }
    }

    public static class LineByPoints extends PolygonByPoints {
        public LineByPoints() {
            super(2);
        }
    }

    public static class RectangleByPoints implements ShapeByPoints {
        @Override
        public int getPointCount() {
            return 2;
        }

        @Override
        public void draw(final Graphics g, final Point... points) {
            g.drawRect(Math.min(points[0].x, points[1].x), Math.min(points[0].y, points[1].y), Math.abs(points[1].x - points[0].x), Math.abs(points[1].y - points[0].y));
        }
    }

    private static JRadioButton createButton(final String buttonText, final ButtonGroup bg, final DrawPanel dp, final ShapeByPoints s) {
        final JRadioButton btn = new JRadioButton(buttonText);
        btn.addActionListener(e -> dp.setShape(s));
        bg.add(btn);
        return btn;
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {
            final DrawPanel dp = new DrawPanel();

            final MouseAdapter ma = new MouseAdapter() {
                @Override
                public void mousePressed(final MouseEvent mevt) {
                    dp.addPoint(mevt.getPoint());
                }

                @Override
                public void mouseDragged(final MouseEvent mevt) {
                    dp.modifyLastPoint(mevt.getPoint());
                }

                @Override
                public void mouseReleased(final MouseEvent mevt) {
                    dp.modifyLastPoint(mevt.getPoint());
                }
            };

            dp.setPreferredSize(new Dimension(500, 350));
            dp.addMouseListener(ma);
            dp.addMouseMotionListener(ma);

            final ButtonGroup bg = new ButtonGroup();

            final JPanel buttons = new JPanel();
            buttons.add(createButton("Line", bg, dp, new LineByPoints()));
            buttons.add(createButton("Ellipse", bg, dp, new EllipseByPoints()));
            buttons.add(createButton("Rectangle", bg, dp, new RectangleByPoints()));
            buttons.add(createButton("Triangle", bg, dp, new PolygonByPoints(3)));
            buttons.add(createButton("Pentagon", bg, dp, new PolygonByPoints(5)));
            //... keep creating buttons here ...

            final JPanel contents = new JPanel(new BorderLayout());
            contents.add(dp, BorderLayout.CENTER);
            contents.add(buttons, BorderLayout.PAGE_START);

            final JFrame frame = new JFrame("Clicking shapes.");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(contents);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

注释:

  1. 除非有充分的理由,否则不要使用paint,但通常情况下没有。在大多数情况下,您想要绘制面板,在这种情况下 paintComponent 应该足够了。
  2. 不要忘记首先在 paintComponent 覆盖中调用 super.paintComponent 。这应该是第一次调用,因为它将清除以前绘图中的面板。
  3. 决定是否要添加用于绘制形状的 JComponent,或者自己在子类面板中绘制形状。在这种情况下,您似乎正在尝试两者(因为 Line 扩展了 JPanel 并且您还覆盖了 Paint)。在我看来,在这种情况下,使用在某些点之间绘制的形状的抽象就可以完成这项工作。这就是我创建 ShapeByPoints 界面的原因。
  4. Swing 不是线程安全的,这意味着同一变量的竞争访问之间可能存在条件。为了避免这种情况,您可以在事件调度线程(或简称​​EDT)中运行每个与Swing 相关的操作。要在 EDT 中显式进行调用,请调用 SwingUtilities.invokeLaterSwingUtilities.invokeAndWaitEventQueue.invokeLater 等方法。 . 互联网上有足够的关于这个主题的 Material 。例如here .
  5. 基本上,我的方法中的所有内容都是从头开始重新设计的(即我没有修改您的示例代码,因为我猜测这会花费更多时间,但这只是一个猜测)。

我刚刚创建了 ShapeByPoints 接口(interface),它指定了如何绘制形状(即它需要的点数,以及用于绘制的 draw 方法)。

然后我创建了一个 DrawPanel extends JPanel,其中包含每个操作的状态。例如,如果用户选择要绘制的五边形,则需要 5 个点,但是当他/她仅单击两次时会发生什么?... DrawPanel 负责此类场景并负责绘制当所有点都完成/单击时给定的形状。

我在框架中添加了一个 DrawPanel 实例、一个用于用户交互的 MouseAdapter 以及几个按钮来演示此逻辑。

您现在需要做的就是根据需要实现 ShapeByPoints 并根据按下的按钮向 DrawPanel 提供它的实例。我已经做了一些关于如何在代码中执行此操作的示例(例如 EllipseByPointsLineByPointsRectangleByPointsPolygonByPoints >).

最后,作为奖励,我添加了拖动单击点的功能(即不仅单击它们,而是单击并拖动它们)。

希望有帮助。

关于java - 在Java中调用类中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61284657/

相关文章:

java - 如何将值为json的Map<String, String>转换为POJO

java - DefaultTableModel 的 ImageIcon

Java Swing : Graphics2D rotation creating disgusting edges

Java Swing - 按钮不改变宽度大小

Bufferedimage 上的 Java JScrollPane

java - 我可以在java中设置默认包吗?

java - 如何使 If 语句以 false boolean 值运行?

java - 如何让按钮实际出现在屏幕上?

java - 如果父级正在调整大小或 JComponent 的内容正在更改,如何使 JComponent 始终填充父级事件?

java - 基本绘画代码。这不起作用