首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中添加绘图标签

在Java中添加绘图标签
EN

Stack Overflow用户
提问于 2018-01-14 17:12:32
回答 1查看 1.9K关注 0票数 2

我在Java方面的经验很少,但我喜欢编程,我所做的一切我都希望它尽可能好。在学习Java最多2天之后,它并不是那么容易。

我被要求做一个逻辑门模拟器。除了GUI,我已经做了所有的事情。这是不必要的,我们的老师,但对我来说,因为与用户在这样一个程序是复杂的沟通。GUI将使它更加清晰。

我想在画布上创建大门,然后能够移动它们。我开始做一个和门,并让它移动与鼠标时,点击。

然而,我注意到,现在我在每件事上都有一张画布。我添加的每一个标签、按钮等都在画布后面。似乎画布是必要的,以移动大门,因为它实际上是重新油漆,当我移动它。

这个门是用paintComponent在一个类中创建的。我要把这一班的每一扇门都做好吗?这样他们就可以在同一张画布上了吗?我如何使每个门,标签,按钮共享相同的画布?

这是我的代码finally.Gates移动与双击。但这是很长的时间。

Main:

代码语言:javascript
复制
                package Pack;
                import java.util.Scanner;
                import javax.swing.*;
                import java.awt.*;
                import java.awt.geom.*;

                public class Main {
                    public static JFrame f;
                    public static void main(String[] args) {

                    ShapeAnd sh=new ShapeAnd();
                    ShapeOr sh2=new ShapeOr();

                    f=new JFrame();
                    f.add(sh);
                    f.add(sh2);
                    f.setVisible(true);
                    f.setSize(700,600);
                    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    f.setTitle("LGS");
                    f.getContentPane().setBackground(Color.RED);
                    }
                    }

或:

代码语言:javascript
复制
            package Pack;
            import javax.swing.*;
            import java.awt.*;
            import java.awt.event.*;
            import java.awt.geom.*;

            public class ShapeOr extends JPanel implements MouseListener,MouseMotionListener{

                int preX,preY,preX2,preY2,difX,difY;
                Graphics g2;
                GeneralPath Or;
                int lim1x,lim2x,lim1y,lim2y;
                boolean check;
                public ShapeOr() {
                    preX=15;
                    preY=0;
                    addMouseMotionListener(this);
                    addMouseListener(this);
                  }
                public void paintComponent(Graphics g){
                    super.paintComponent(g);
                     Graphics2D g2 = (Graphics2D) g;
                     lim1x=preX;
                     lim2x=preX+80;
                     lim1y=preY;
                     lim2y=preY+60;
                             int x1Points[] = {preX,preX+50,preX+60,preX+70,preX+80,preX+70,preX+60,preX+50,preX,preX+10,preX+20,preX+30,preX+20,preX+10,preX};
                            int y1Points[] = {preY,preY,preY+5,preY+15,preY+30,preY+45,preY+55,preY+60,preY+60,preY+55,preY+45,preY+30,preY+15,preY+5,preY};
                            GeneralPath Or = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
                                                    x1Points.length);

                            Or.moveTo(preX-15,preY+15);
                            Or.lineTo(preX+20,preY+15);
                            Or.moveTo(preX-15,preY+45);
                            Or.lineTo(preX+20,preY+45);
                            Or.moveTo(preX,preY);

                            for (int index = 1; index < x1Points.length; index++) {
                                    Or.lineTo(x1Points[index], y1Points[index]);
                            };
                            Or.closePath();
                            g2.draw(Or);
                            //check=false;
                }
                public void mousePressed(MouseEvent e) {
                    difX=preX-e.getX();
                    difY=preY-e.getY();

                  }
                public void updateLocation(MouseEvent e){
                    preX=e.getX()+difX;
                    preY=e.getY()+difY;
                    repaint();
                }

                      public void mouseReleased(MouseEvent e) {
                       check=false;
                      }

                      public void mouseMoved(MouseEvent e) {
                      }

                      public void mouseClicked(MouseEvent e) {
                          int mouseX=e.getX();
                          int mouseY=e.getY();
                            if(mouseX>lim1x && mouseX<lim2x && mouseY>lim1y && mouseY<lim2y){
                                check=true;
                            }
                      }

                      public void mouseExited(MouseEvent e) {
                      }

                      public void mouseEntered(MouseEvent e) {
                      }

                      public void mouseDragged(MouseEvent e) {
                          if(check==true){
                              updateLocation(e);
                          }
                      }

            }

和:

代码语言:javascript
复制
        package Pack;
        import javax.swing.*;
        import java.awt.*;
        import java.awt.event.*;
        import java.awt.geom.*;

        public class ShapeAnd extends JPanel implements MouseListener,MouseMotionListener{

            int preX,preY,preX2,preY2,difX,difY;
            Graphics g2;
            GeneralPath And;
            int lim1x,lim2x,lim1y,lim2y;
            boolean check;
            public ShapeAnd() {
                addMouseMotionListener(this);
                addMouseListener(this);
              }
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                 Graphics2D g2 = (Graphics2D) g;
                 lim1x=preX+15;
                 lim2x=preX+95;
                 lim1y=preY;
                 lim2y=preY+75;
                         int x1Points[] = {preX,preX+ 50, preX+60,preX +70,preX+80,preX+70,preX+60,preX+50,preX+0};
                        int y1Points[] = {preY+0,preY+ 0,preY+5,preY+15,preY+30,preY+45,preY+55,preY+60,preY+60};
                        GeneralPath And = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
                                                x1Points.length);

                        And.moveTo(preX,preY+15);
                        And.lineTo(preX+15,preY+15);
                        And.moveTo(preX,preY+45);
                        And.lineTo(preX+15,preY+45);
                        And.moveTo(preX+15,y1Points[0]);

                        for (int index = 1; index < x1Points.length; index++) {
                                And.lineTo(x1Points[index]+15, y1Points[index]);
                        };
                        And.closePath();
                        g2.draw(And);
                        //check=false;
            }
            public void mousePressed(MouseEvent e) {
                difX=preX-e.getX();
                difY=preY-e.getY();

              }
            public void updateLocation(MouseEvent e){
                preX=e.getX()+difX;
                preY=e.getY()+difY;
                repaint();
            }

                  public void mouseReleased(MouseEvent e) {
                   check=false;
                  }

                  public void mouseMoved(MouseEvent e) {
                  }

                  public void mouseClicked(MouseEvent e) {
                      int mouseX=e.getX();
                      int mouseY=e.getY();
                        if(mouseX>lim1x && mouseX<lim2x && mouseY>lim1y && mouseY<lim2y){
                            check=true;
                        }
                  }

                  public void mouseExited(MouseEvent e) {
                  }

                  public void mouseEntered(MouseEvent e) {
                  }

                  public void mouseDragged(MouseEvent e) {
                      if(check==true){
                          updateLocation(e);
                      }
                  }

        }

PS:我知道,需要一个更好的标题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-14 20:04:57

感谢您的代码帖子,因为这有助于澄清相当多的事情。我的假设是正确的--你让你的大门扩展了一个GUI组件,给它们增加了很多不必要的“重量”,让它们很难随意移动,或者在你的GUI上放置多个。

关于解决办法的建议包括:

  • 使您的门更轻,不让他们扩展JPanel或任何图形用户界面组件。
  • 相反,让它们“逻辑”(非GUI组件),这些组件可以通过public void draw(Graphics2d g2)方法由单个绘图组件绘制。我通常使用单个paintComponent(Graphics g)的JPanel方法来绘制这幅图。
  • 为这个绘图JPanel提供一个gates的ArrayList,然后通过迭代JPanel的单个paintComponent方法中的列表来绘制门。
  • 将鼠标侦听器和运动侦听器添加到同一个JPanel中,并允许此侦听器更改已单击或拖动的任何门形状的状态。
  • 允许大门通过给它们一个绘图组件可以调用的draw(...)方法来绘制自己,
  • 给您的gate一个public boolean contains(Point p)方法,它允许您判断鼠标是否单击了它们。
  • 并为他们的位置提供getter和setter方法,这样就可以检查和更改。
  • 利用从形状接口派生出来的功能类(按组合)来帮助您自己的形状绘制和移动。为此,我使用了Path2D对象,因为它们可以通过使用AffineTransforms轻松地移动。

示例代码即将..。

所有的门对象都可以共享相同的接口.

代码语言:javascript
复制
interface MyGate {
    void draw(Graphics2D g2);
    void setPoint(Point p);
    Point getPoint();
    boolean contains(Point p);  
}

实现上述接口的示例门类。

代码语言:javascript
复制
class OrGate implements MyGate {
    private Path2D path; 
    private Point point = new Point(0, 0); // initial Point

    public OrGate() {
        // initialize the Path2D and give it a winding rule
        path = new Path2D.Double(Path2D.WIND_EVEN_ODD);

        // lots of "magic" numbers below, a code design "smell"
        // better to not do this. Perhaps have a data file to hold
        // this information, and have it read on program startup
        int preX = 15;
        int preY = 0;
        int x1Points[] = { preX, preX + 50, preX + 60, preX + 70, preX + 80, preX + 70, preX + 60,
                preX + 50, preX, preX + 10, preX + 20, preX + 30, preX + 20, preX + 10, preX };
        int y1Points[] = { preY, preY, preY + 5, preY + 15, preY + 30, preY + 45, preY + 55,
                preY + 60, preY + 60, preY + 55, preY + 45, preY + 30, preY + 15, preY + 5, preY };
        path.moveTo(preX - 15, preY + 15);
        path.lineTo(preX + 20, preY + 15);
        path.moveTo(preX - 15, preY + 45);
        path.lineTo(preX + 20, preY + 45);
        path.moveTo(preX, preY);

        for (int index = 1; index < x1Points.length; index++) {
            path.lineTo(x1Points[index], y1Points[index]);
        }
        path.closePath();
    }

    @Override
    public void draw(Graphics2D g2) {
        // simple method that leverages the Path2D path object
        g2.draw(path);
    }

    @Override
    public boolean contains(Point p) {
        // simple method that leverages the Path2D path object
        return path.contains(p);
    }

    @Override
    public Point getPoint() {
        return point;
    }

    @Override
    public void setPoint(Point p) {
        Point pOld = this.point;
        Point pNew = p;
        this.point = p;

        // create a transform that helps us move our Path2D
        int tx = pNew.x - pOld.x;
        int ty = pNew.y - pOld.y;       
        AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
        path.transform(at);  // and then move it
    }    

}

显示使用JPanel和绘制/拖动形状的主MouseAdapter:

代码语言:javascript
复制
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class MainGates2 extends JPanel {
    private static final int PREF_W = 700;
    private static final int PREF_H = 600;
    private List<MyGate> gates = new ArrayList<>();

    public MainGates2() {
        // create a few Gates
        MyGate gate1 = new OrGate();
        gate1.setPoint(new Point(200, 300)); // move this guy
        MyGate gate2 = new OrGate();

        // add them to the gates ArrayList
        gates.add(gate1);
        gates.add(gate2);

        // create our mouse listener / adapter and add to JPanel
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);        
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        // rendering hints to smooth graphics
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // iterate through collection and draw
        for (MyGate myGate : gates) {
            myGate.draw(g2);
        }

    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        // give our JPanel some size
        return new Dimension(PREF_W, PREF_H);
    }

    private class MyMouse extends MouseAdapter {
        private MyGate selectedGate = null;
        private Point p0; // initial Gate location
        private Point p1; // first mouse press location

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            p1 = e.getPoint();
            for (int i = gates.size() - 1; i >= 0; i--) {
                if (gates.get(i).contains(e.getPoint())) {
                    selectedGate = gates.get(i);
                    p0 = selectedGate.getPoint();
                    return;
                }
            }
            p1 = null;
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (selectedGate != null) {
                dragShape(e);

                // de-select the gate
                selectedGate = null;
                p0 = null;
                p1 = null;
            }
        }

        public void mouseDragged(MouseEvent e) {
            if (selectedGate != null) {
                dragShape(e);
            }
        }

        private void dragShape(MouseEvent e) {
            Point p2 = e.getPoint(); // current mouse location
            int x = p0.x + p2.x - p1.x;
            int y = p0.y + p2.y - p1.y;
            Point p = new Point(x, y);
            selectedGate.setPoint(p);
            repaint();
        };
    }

    private static void createAndShowGui() {
        // main JPanel
        MainGates2 mainPanel = new MainGates2();

        JFrame frame = new JFrame("Main Gates2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48252092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档