在java中制作绘图应用程序的方法更简单?

时间:2015-10-07 00:11:01

标签: java swing jframe paint jcomponent

所以基本上我有一些我前几天工作的代码,有点像Paint,它允许你使用鼠标在屏幕上绘制。我偶然发现了这个属性,我意识到这是非常低效的,我想知道是否有更实际的方法来做到这一点。我没有任何理由给出我的所有代码,但这里有重要的部分

private static void createAndShowGui() {
    SimpleDraw mainPanel = new SimpleDraw();
    MenuBar.createMenuBar();
    JLabel label = new JLabel();
    label.setText("Drawing prototype 0.0.1");
     // label.setHorizontalTextPosition(JLabel.NORTH);
    label.setFont(new Font("Serif", Font.BOLD, 20));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(mainPanel);
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.PAGE_AXIS));
    frame.setVisible(true);
    frame.setJMenuBar(MenuBar.getMenuBar());
    frame.setBackground(Color.WHITE);
    frame.add(label);

上面的代码块设置了jframe(窗口)

 @Override
    public void mouseDragged(MouseEvent e)
    {
    // These console outputs are just so that I know what is happening
        System.out.println("Event: MOUSE_DRAG");
        System.out.println(e.getX());
        System.out.println(e.getY());
        System.out.println(e.getComponent());
        System.out.println(e.getWhen());
        System.out.println(e.getButton());
         MOUSE_X = e.getX() - 5;  //-5 so that the cursor represents the center of the square, not the top left corner.
         MOUSE_Y = e.getY() - 5;  //^
         rect = new Rectangle(MOUSE_X, MOUSE_Y, 10, 10 ); //This doesn't ever come into action.
         repaint();  

     }

上面的代码几乎只设置了MOUSE_X和MOUSE_Y变量以及repaint();方法

@Override
    protected void paintComponent(Graphics g) {

    Graphics2D g2 = (Graphics2D) g;
    if (rect != null) {

        if (!colorChoice.equals("Default"))
        {
            g2.setColor(Color.BLACK);
        }

        switch(colorChoice) {

        case "GRAY":
            g2.setColor(Color.GRAY);
            break;
        case "CYAN":
            g2.setColor(Color.CYAN);
            break;
        case "BLUE":
            g2.setColor(Color.BLUE);
            break;
        case "RED":
            g2.setColor(Color.RED);
            break;
        case "PINK":
            g2.setColor(Color.PINK);
            break;
        case "YELLOW":
            g2.setColor(Color.YELLOW);
            break;
        case "GREEN":
            g2.setColor(Color.GREEN);
            break;
        case "PURPLE":
            g2.setColor(Color.MAGENTA);
            break;
        case "RESET":
            g2.setColor(Color.WHITE);
        case "WHITE":
            g2.setColor(Color.WHITE);

        }





        g2.fillRect(MOUSE_X, MOUSE_Y, 15, 15); 

        if (colorChoice.equals("RESET")) 
        resetColorOnCursor(); 

        }
    }

    public static void clearBoard()
    {
    tempColor = colorChoice;
    setColorChoice("RESET");
    frame.repaint();




    }


    public static void resetColorOnCursor()
    {
    setColorChoice(tempColor);
    }

这是我偶然遇到的事情。当我发现这个时,我试图做的基本上是每当你移动鼠标时都按照光标做一个正方形。但是我忘了键入代码部分paintComponent(g);,它将这个程序变成了我原本想要的东西。这部分的底部基本上是我如何清除董事会。我100%确定这不是清除/重置这样的帧的正确方法,但我找不到另一种方法。如果有人有任何提示或更好的方法来正确地做到这一点我会非常感激。谢谢! :d

3 个答案:

答案 0 :(得分:7)

您目前的做法基本上是打破了油漆链的要求,而不是调用super.paintComponentpaintComponent方法执行一组操作,您没有接管这些操作,这可能会导致一些非常奇怪的绘制工件难以一致地复制。

Graphics是一个共享资源,因此用于绘制其他控件的Graphics上下文将与用于绘制组件的相同,除非您之前“清理”上下文手,之前绘制到上下文的内容将保留(这就是为什么你的代码目前似乎“似乎”工作)。

相反,你应该使用MouseListener来定义一个锚点,它表示按下鼠标的点,然后使用MouseMotionListener来定义选择区域的范围,例如...

Paint Selection

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SelectExample {

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

    public SelectExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Rectangle selection;

        public TestPane() {
            MouseAdapter ma = new MouseAdapter() {

                private Point clickPoint;

                @Override
                public void mousePressed(MouseEvent e) {
                    clickPoint = e.getPoint();
                    selection = null;
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    Point dragPoint = e.getPoint();
                    int x = Math.min(clickPoint.x, dragPoint.x);
                    int y = Math.min(clickPoint.y, dragPoint.y);

                    int width = Math.max(clickPoint.x, dragPoint.x) - x;
                    int height = Math.max(clickPoint.y, dragPoint.y) - y;

                    if (selection == null) {
                        selection = new Rectangle(x, y, width, height);
                    } else {
                        selection.setBounds(x, y, width, height);
                    }
                    repaint();
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    selection = null;
                    repaint();
                }

            };

            addMouseListener(ma);
            addMouseMotionListener(ma);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (selection != null) {
                g.setColor(UIManager.getColor("List.selectionBackground"));
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                g2d.fill(selection);
                g2d.dispose();
                g2d = (Graphics2D) g.create();
                g2d.draw(selection);
                g2d.dispose();
            }
        }

    }

}

如果您继续违反paintComponent方法的要求,只需突出显示您将遇到的问题,这就是当我不致电super.paintComponent时会发生的事情

Violated

我只是将两个JButton添加到JFrame(所以甚至不直接添加到面板中)。 paintComponent做了一系列重要的工作,你忽略了这些工作,这会导致更多的问题和问题。

免费表单行示例...

自由形式线实际上是一种幻觉,它是在一系列点之间绘制的一系列(小)线,原因是MouseListener不会报告它移动的每个鼠标位置,根据鼠标移动的速度,你可能会收到很多回电或一些回电。

因此,我们不是绘制只绘制点,而是将点存储在List中并在它们之间绘制线条,例如......

FreeForm

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FreeFormLines {

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

    public FreeFormLines() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<List<Point>> points;

        public TestPane() {
            points = new ArrayList<>(25);
            MouseAdapter ma = new MouseAdapter() {

                private List<Point> currentPath;

                @Override
                public void mousePressed(MouseEvent e) {
                    currentPath = new ArrayList<>(25);
                    currentPath.add(e.getPoint());

                    points.add(currentPath);
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    Point dragPoint = e.getPoint();
                    currentPath.add(dragPoint);
                    repaint();
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    currentPath = null;
                }

            };

            addMouseListener(ma);
            addMouseMotionListener(ma);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (List<Point> path : points) {
                Point from = null;
                for (Point p : path) {
                    if (from != null) {
                        g2d.drawLine(from.x, from.y, p.x, p.y);
                    }
                    from = p;
                }
            }
            g2d.dispose();
        }

    }

}

答案 1 :(得分:0)

这是一个实际的绘画应用程序的简单示例,您可以在其中控制和更改图形的大小和颜色。

public class Main extends Application{
    @Override
    public void start(Stage stage){
        try{
            g = can.getGraphicsContext2D();
            g.setStroke(Color.BLACK);
            g.setLineWidth(1);
            c.setValue(Color.BLACK);
            c.setOnAction(e->{
                g.setStroke(c.getValue());
            });
            sli.setMin(1);
            sli.setMax(100);
            sli.setShowTickLabels(true);
            sli.setShowTickMarks(true);
            sli.valueProperty().addListener(e->{
                double val = sli.getValue();
                String str = String.format("%.1f",  val);
                lab.setText(str);
                g.setLineWidth(val);
            });
            gri.addRow(0,  c, sli, lab);
            gri.setHgap(20);
            gri.setAlignement(Pos.TOP_CENTER);
            gri.setPadding( new Insets( 20, 0, 0, 0));

            scene.setOnMousePressed(e->{.
               g.beginPath();
               g.lineTo(e.getSceneX(), e.getSceneY());
               g.stroke();
            });
            scene.setOnMoudrDragged(e->{. 
                g.lineTo(e.getSceneX(),  e.getSceneY());
                g.stroke();
            });
            pan.getChildren().addAll(can, gri);
            stage.setScene(scene);
            stage.show();
        }catch(Exception e){

            e.printStrackTrace();
        }

       Canvas can = new Canvas(760, 490);
       GraphicsContext  g ;
       ColorPicker  c =  new ColorPicker();
       Slider sli = new Slider();
       Label lab = new Label("1.0");
       GridPane gri = new GridPane();
       StackPane pan =  new StackPane();
       Scene  scene = new Scene(pan, 760, 490);
   public static void main (String [] args){
       launch(args);
   }
}

答案 2 :(得分:0)

或者我们可以尝试仅绘制Java代码,我认为它是如此简单和强大。

package drawingbymouse;

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

public class DrawingByMouse extends Frame 
                          implements MouseMotionListener{

    DrawingByMouse(){
        addMouseMotionListener(this);
        setSize(400, 400);
        setLayout(null);
        setVisible(true);
    }
    @Override
    public void mouseDragged(MouseEvent e){
        Graphics g = getGraphics();
        g.setColor(Color.BLACK);
        g.fillOval(e.getX(), e.getY(), 10, 10);
    }
    public void mouseMoved(MouseEvent e){
    }
    public static void main (String[]args){
        new DrawingByMouse();
    }
}