Рисование графики Java Swing и заполнение выбранных прямоугольников цветами

Я новичок в настольных графических приложениях Java Swing. У меня возникла проблема. Пожалуйста, предложите мне выбрать некоторые из прямоугольников и заполнить прямоугольники. Есть ли у нас какая-либо предопределенная концепция, например, резиновая лента, если таковая имеется, пожалуйста, предложите мне начать рисунок.

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Exam extends JPanel implements MouseMotionListener {

    private static final int recW = 50;
    private static final int MAX = 100;
    private Rectangle[] rect = new Rectangle[MAX];
    private int numOfRecs = 0;
    private int currentSquareIndex = -1;
    private Point startPoint = new Point();
    private Point currentPoint = new Point();
    private int x, y, width, height;
    private Stroke dashedStroke = new BasicStroke(0.0f, BasicStroke.CAP_ROUND,
            BasicStroke.CAP_SQUARE, 5.0f, new float[] { 5f, 5f, 5f, 5f }, 5.0f);

    ArrayList list = new ArrayList();

    public Exam() {

        addRect(50, 50);
        addRect(100, 50);
        addRect(150, 50);
        addRect(200, 50);
        addRect(250, 50);
        addRect(300, 50);
        addRect(350, 50);
        addRect(400, 50);
        addRect(450, 50);
        addRect(500, 50);
        //
        addRect(50, 100);
        addRect(100, 100);
        addRect(150, 100);
        addRect(200, 100);
        addRect(250, 100);
        addRect(300, 100);
        addRect(350, 100);
        addRect(400, 100);
        addRect(450, 100);
        addRect(500, 100);
        //
        addRect(50, 150);
        addRect(100, 150);
        addRect(150, 150);
        addRect(200, 150);
        addRect(250, 150);
        addRect(300, 150);
        addRect(350, 150);
        addRect(400, 150);
        addRect(450, 150);
        addRect(500, 150);
        //
        addRect(50, 200);
        addRect(100, 200);
        addRect(150, 200);
        addRect(200, 200);
        addRect(250, 200);
        addRect(300, 200);
        addRect(350, 200);
        addRect(400, 200);
        addRect(450, 200);
        addRect(500, 200);

        addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent evt) {
                startPoint = evt.getPoint();
            }

            public void mouseReleased(MouseEvent e) {

                System.out.println(" mouseReleased is " + e.getX() + " y i s "
                        + e.getY());
                Graphics g = getGraphics();
                Graphics2D g2 = (Graphics2D) g;
                g2.setComposite(AlphaComposite.SrcOver.derive(0.8f));
                Color myColour = new Color(255, 0, 0);
                g.setColor(myColour);
                x = Math.min(startPoint.x, currentPoint.x);
                y = Math.min(startPoint.y, currentPoint.y);
                width = Math.abs(startPoint.x - currentPoint.x);
                height = Math.abs(startPoint.y - currentPoint.y);
                rect[numOfRecs] = new Rectangle(x, y, width, height);
                // System.out.println("list size is:"+list.size());
                 Rectangle ggg=new Rectangle(x, y, width, height);
            for(Rectangle rect3d: rect){
                if(ggg.intersects(rect3d)){
                g2.fill(rect3d);
                }
                else
                    System.out.println("doesn't contains");
                }
repaint();
            }

        });

        addMouseMotionListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < numOfRecs; i++) {
            ((Graphics2D) g).draw(rect[i]);
            list.add(rect[i]);
        }

        x = Math.min(startPoint.x, currentPoint.x);
        y = Math.min(startPoint.y, currentPoint.y);
        width = Math.abs(startPoint.x - currentPoint.x);
        height = Math.abs(startPoint.y - currentPoint.y);
        ((Graphics2D) g).setStroke(dashedStroke);
        g.setColor(Color.BLACK);
        g.drawRect(x, y, width, height);
        // Rectangle dashedRec=new Rectangle(x, y, width, height);

    }

    public void addRect(int x, int y) {
        if (numOfRecs < MAX) {
            rect[numOfRecs] = new Rectangle(x, y, recW, recW);
            currentSquareIndex = numOfRecs;
            numOfRecs++;
            repaint();
        }
    }

    @Override
    public void mouseMoved(MouseEvent event) {
    }

    @Override
    public void mouseDragged(MouseEvent event) {

        currentPoint = event.getPoint();
        repaint();
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.setTitle("");
        jFrame.setSize(600, 300);
        Container cPane = jFrame.getContentPane();
        cPane.add(new Exam());
        jFrame.setVisible(true);
    }
}

person Vskiran    schedule 17.07.2014    source источник
comment
Добро пожаловать в Stack Overflow. Прочтите Переполнение стека: как спросить и Контрольный список вопросов Джона Скита, чтобы узнать, как задать хороший вопрос, который принесет пользу, ответы.   -  person Our Man in Bananas    schedule 17.07.2014
comment
пожалуйста, покажите нам, что вы пробовали, немного кода и, возможно, jsfiddle   -  person Our Man in Bananas    schedule 17.07.2014
comment
MouseMotionListener не реагирует на mousePressed/Clicked   -  person mKorbel    schedule 17.07.2014
comment
Я вставил некоторый код, пожалуйста, проверьте его один раз и предложите мне пройти через выбор прямоугольников   -  person Vskiran    schedule 17.07.2014
comment
перетаскивание мыши связано с прослушивателем движения мыши вправо   -  person Vskiran    schedule 17.07.2014
comment
Полный пример приведен здесь.   -  person trashgod    schedule 17.07.2014


Ответы (3)


Вы должны начать с изменения import java.awt.event.MouseMotionListener;

to

импортировать java.awt.event.MouseListener;

mousePressed не работает с MouseMotionListener

person charles    schedule 17.07.2014
comment
Спасибо, но никто не предлагает и не концентрируется на моей проблеме. Не могли бы вы предложить решение для этого. При перетаскивании я выбираю некоторые прямоугольники, которые мне нужно заполнить цветом, так что, если я перетащил два маленьких прямоугольника, он также должен заполнить весь прямоугольник. - person Vskiran; 17.07.2014

Я вижу, что имя класса Exam, поэтому, поскольку это для школы, я не буду давать вам решение кода. Просто несколько логических способов взглянуть на это.

Я заметил, что когда вы перетаскиваете мышь, вы просто получаете точку и рисуете, основываясь на этой точке. Вместо этого вы должны сделать следующее: при первом нажатии мыши создайте Rectangle (и нарисуйте прямоугольник), а пока мышь перетаскивается, увеличьте размер прямоугольника с помощью setRect(). Вы можете увидеть хороший пример здесь.

В зависимости от того, хотите ли вы, чтобы изменение цвета было динамическим (во время перетаскивания или когда перетаскивание выполняется), у вас есть два варианта:

  1. При перетаскивании выполните итерацию по списку прямоугольников и проверьте, пересекается ли каждый прямоугольник в списке или содержится ли он в перетаскиваемом прямоугольнике. Rectangle наследует методы intersects() и contains() от Shape.

  2. Если вы просто хотите изменить цвет после завершения перетаскивания, сделайте то же самое, что и выше, когда мышь будет отпущена.


Также обратите внимание, что вы никоим образом не должны использовать getGraphics() для создания пользовательского рисунка. Все рисование должно выполняться в контексте объекта Graphics, предоставленного в методе paintComponent.


ОБНОВЛЕНИЕ

Вот пример, основанный на пунктах, которые я сделал выше. Пример расширяет пример, приведенный в ссылке выше.

введите здесь описание изображения

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class RectangleDrawWithDrag extends JPanel{

    private static final int D_W = 400;
    private static final int D_H = 400;
    private static final Color DEFAULT_COLOR = Color.GRAY;
    private static final Color SELECT_COLOR = Color.BLUE;
    private static final Color CURSOR_COLOR = new Color(100, 100, 100, 100);

    private Point p1;
    private Point p2;
    private Rectangle2D rectangle;
    private List<ColoredRectangle> rectangles;

    public RectangleDrawWithDrag() {
        rectangles = createRectangleList();
        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent e) {
                p1 = e.getPoint();
                rectangle = new Rectangle2D.Double(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
            }
        });
        addMouseMotionListener(new MouseMotionAdapter(){
            public void mouseDragged(MouseEvent e) {
                p2 = e.getPoint();
                if (isPointTwoInQuadOne(p1, p2)) {
                    rectangle.setRect(p2.x, p2.y, p1.x - p2.x, p1.y - p2.y);
                } else {
                    rectangle.setRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);  
                }
                checkRectangleContainment();
                repaint();
            }
        });
    }

    public void checkRectangleContainment() {
        for (ColoredRectangle rects: rectangles) {
            if (rectangle.contains(rects.getRectangle())) {
                rects.setColor(SELECT_COLOR);
            } else {
                rects.setColor(DEFAULT_COLOR);
            }
        }
    }

    public boolean isPointTwoInQuadOne(Point p1, Point p2) {
        return p1.x >= p2.x && p1.y >= p2.y;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        for (ColoredRectangle rect: rectangles) {
            rect.draw(g2);
        }
        if (rectangle != null) {
            g2.setColor(CURSOR_COLOR);
            g2.fill(rectangle);
        }
    }

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

    private List<ColoredRectangle> createRectangleList() {
        List<ColoredRectangle> rects = new ArrayList<>();
        Random rand= new Random();
        for (int i = 0; i < 20; i++) {
            rects.add(new ColoredRectangle(rand.nextInt(D_W), rand.nextInt(D_H)));
        }
        return rects;
    }

    public class ColoredRectangle {
        Rectangle2D rectangle;
        Color color = DEFAULT_COLOR;
        double size = 20;

        public ColoredRectangle(double x, double y) {
            rectangle = new Rectangle2D.Double(x, y, size, size);
        }

        public ColoredRectangle(double x, double y, double size) {
            this.size = size;
            rectangle = new Rectangle2D.Double(x, y, size, size);
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public Rectangle2D getRectangle() {
            return rectangle;
        }

        public void draw(Graphics2D g2) {
            g2.setColor(color);
            g2.fill(rectangle);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new RectangleDrawWithDrag());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
person Paul Samsotha    schedule 17.07.2014
comment
Нет, спасибо за эту помощь, но приведенный пример совсем не связан с моим выводом. Мне нужно использовать метод цвета пересечения или метод содержит в прямоугольнике. Можете ли вы привести примеры этих методов для рисования прямоугольников. - person Vskiran; 18.07.2014
comment
Вы видите, как, когда вы перетаскиваете мышь, вы просто получаете точку, а затем рисуете прямоугольник на основе точки? Что делает пример, так это то, что он создает Rectangle из начальной точки и расширяет Rectangle при перетаскивании мыши. То, что рисуется, - это Rectangle, в отличие от вашего примера, где вы рисуете на основе точки, а не прямоугольника. Разница в том, что с Rectangle вы можете использовать rectangle.contains(anotherRetangle), которые возвращают логическое значение, если внутренний прямоугольник содержится во внешнем. - person Paul Samsotha; 18.07.2014
comment
Таким образом, вы можете просмотреть свой массив Rectangle в mouseDragged, чтобы увидеть, содержится ли каждый прямоугольник. Если он содержится, вы можете изменить его цвет в методе painComponent. - person Paul Samsotha; 18.07.2014
comment
Возможно, через пару часов, когда у меня будет время, я попытаюсь расширить этот пример, чтобы показать вам - person Paul Samsotha; 18.07.2014
comment
Ознакомьтесь с моим ОБНОВЛЕНИЕМ. Это пример с техникой, которую я описал - person Paul Samsotha; 18.07.2014
comment
о, хорошо, это очень помогло мне в моем требовании, но дело в том, что теперь я частично получаю свое требование, когда я выбираю прямоугольники, я заполняю пересекающиеся прямоугольники, но первый прямоугольник заполняется, и я не хочу видеть пунктирную линию, не могли бы вы помогите в этом, я обновляю свой код, пожалуйста, проверьте его - person Vskiran; 18.07.2014
comment
ваш g2.fill не должен быть в методе mouseXxx. Как я уже сказал, вся отрисовка должна выполняться в методе paintComponent. Чтобы внести изменения, вы звоните repaint(). Но вам нужно предвидеть, что будет нарисовано, и уже иметь это в методе paintComponent. Пожалуйста, просмотрите мой код, чтобы понять, о чем я говорю - person Paul Samsotha; 18.07.2014
comment
@peeskillet: Ага, хорошо, что вы придерживаетесь концепции Abstraction при ответе (хорошее использование концепций объектно-ориентированного программирования при ответе) - person nIcE cOw; 18.07.2014
comment
Спасибо @peeskillet, когда я помещаю код заливки в метод paintComponent, он не работал ранее, и еще одна вещь: после перетаскивания я заливаю цвет, но я не хочу отображать перетаскиваемый прямоугольник после заливки цветом. Можете ли вы предложить мне сделать, как я могу Я делаю это? - person Vskiran; 21.07.2014
comment
В последней части я бы поместил переменную isSelected в класс ColoredRectangle и, если она содержится, присвоил бы ей значение true. В методе рисования рисуйте только в том случае, если прямоугольник isSelected. Что касается избавления от прямоугольника, вы можете установить для него значение null, когда мышь отпущена. - person Paul Samsotha; 21.07.2014
comment
Насчет первой части не могу сказать. Вы должны были бы сделать свою собственную отладку. Я использовал другой подход, используя Rectangle и Graphics2D.fill(Rectangle). .fillRect() — это метод класса Graphics. Вы можете привести его к Grapchics2D, как я сделал в своем коде. - person Paul Samsotha; 21.07.2014
comment
Все становится намного проще поддерживать, если вы создаете класс-оболочку для всех свойств, как это сделал я. Вы можете просто использовать метод рисования в этом классе - person Paul Samsotha; 21.07.2014
comment
Да, я понял, но мне нужно, чтобы я не хотел отображать перетаскиваемый прямоугольник после перетаскивания, его нужно отключить, как я могу это сделать. - person Vskiran; 22.07.2014
comment
Я только что тебе сказал. Установите прямоугольник в нуль, когда мышь будет отпущена. Вы можете видеть в моей программе, когда она впервые запускается, прямоугольник перетаскивания равен нулю. Вот почему вы не видите его при запуске программы. Сделайте то же самое в mouseReleased, установите для него значение null - person Paul Samsotha; 22.07.2014
comment
Я использую это, чтобы установить прямоугольник, но он не работает new Rectangle(x, y, width, height).setRect(null); в мыши выпущен - person Vskiran; 22.07.2014
comment
В моем коде я использую тот же прямоугольник класса. Я только инициализирую его в mousePressed. в выпущенной мыши просто выполните rectangle = null, repaint(). Попробуйте с моим кодом. Я не проверял это, но из того, что я помню о коде, эта простая строка в public void mouseReleased должна помочь. Если это работает с моим кодом, сравните его со своим и посмотрите, что отличается - person Paul Samsotha; 22.07.2014
comment
как это я делаю, но это не работает, где, как в вашем коде, это работает Rectangle ggg=new Rectangle(x, y, width, height); for(Rectangle rect3d: rect){ if(ggg.intersects(rect3d)){ g2.fill(rect3d);} else System.out.println(не содержит); } ггг=нуль; перекрасить(); - person Vskiran; 22.07.2014
comment
Давайте продолжим обсуждение в чате. - person Vskiran; 22.07.2014

Я наткнулся на ваш вопрос, когда искал что-то похожее, что мне нужно. Я немного настроил код Пола под свои требования. Я пишу здесь, потому что мне не разрешено оставлять комментарии здесь моя версия

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.util.HashSet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;

public class TimetableFrame extends javax.swing.JFrame {

Point p1, p2;
Rectangle2D rectangle;
int mode = 0;
HashSet<JLabel> all = new HashSet<JLabel>();
HashSet<JLabel> selected = new HashSet<JLabel>();
HashSet<JLabel> current_selection = new HashSet<JLabel>();
Color empty_color = Color.WHITE;
Color fill_color = Color.RED;
Color empty_select = Color.GRAY;
Color fill_select = Color.PINK;

JPanel grid;
JPanel jPanel1;
JScrollPane jScrollPane1;

public TimetableFrame() {
    initComponents();
    setTitle("Swing grid selector example halimoglu.com");
    String[] col_titles = new String[]{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

    String[] row_titles = new String[24];
    for (int i = 0; i < row_titles.length; i++) {
        row_titles[i] = (i) + "-" + (i + 1);
    }

    for (int y = 0; y < row_titles.length + 1; y++) {
        for (int x = 0; x < col_titles.length + 1; x++) {
            if (y == 0 && x == 0) {
                grid.add(new JLabel(""));
            } else if (y == 0) {
                JLabel col = new JLabel(col_titles[x - 1]);
                col.setHorizontalAlignment(SwingConstants.CENTER);
                grid.add(col);
            } else if (x == 0) {
                grid.add(new JLabel(row_titles[y - 1]));
            } else {
                JLabel mylabel = new JLabel(" ");

                mylabel.setOpaque(true);
                mylabel.setBackground(empty_color);
                all.add(mylabel);
                grid.add(mylabel);
            }
        }
    }

    grid.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent me) {
            for (JLabel j : all) {
                if (j.getBounds().contains(me.getPoint())) {

                    if (selected.contains(j)) {
                        selected.remove(j);
                        j.setBackground(empty_color);
                    } else {
                        selected.add(j);
                        j.setBackground(fill_color);
                    }
                }
            }
        }

        @Override
        public void mousePressed(MouseEvent me) {
            p1 = me.getPoint();
            rectangle = new Rectangle2D.Double(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
        }

        @Override
        public void mouseReleased(MouseEvent me) {

            if (mode == 1) {
                selected.addAll(current_selection);

            } else if (mode == -1) {
                selected.removeAll(current_selection);

            }
            for (JLabel j : all) {
                if (selected.contains(j)) {
                    j.setBackground(fill_color);
                } else {
                    j.setBackground(empty_color);
                }
            }
            current_selection.clear();
            mode = 0;
        }

        @Override
        public void mouseEntered(MouseEvent me) {
        }

        @Override
        public void mouseExited(MouseEvent me) {
        }

    });

    grid.addMouseMotionListener(new MouseMotionListener() {
        @Override
        public void mouseDragged(MouseEvent me) {
            p2 = me.getPoint();

            Point lu;

            int minx = Math.min(p1.x, p2.x);
            int miny = Math.min(p1.y, p2.y);
            int maxx = Math.max(p1.x, p2.x);
            int maxy = Math.max(p1.y, p2.y);

            lu = new Point(minx, miny);// left upper point

            rectangle.setRect(lu.x, lu.y, maxx - minx, maxy - miny);

            //set mode 
            //1 = if first selected cell is empty set mode to fill
            //-1 = otherwise clear 
            if (mode == 0) {
                for (JLabel j : all) {
                    if (j.getBounds().intersects(rectangle)) {
                        if (selected.contains(j)) {
                            mode = -1;
                        } else {
                            mode = 1;
                        }
                        break;
                    }
                }
            }

            for (JLabel j : all) {

                if (selected.contains(j) == (mode != 1)) {
                    if (j.getBounds().intersects(rectangle)) {
                        current_selection.add(j);
                    } else {
                        if (current_selection.contains(j)) {
                            current_selection.remove(j);
                            if (mode == 1) {
                                if (selected.contains(j) == false) {
                                    j.setBackground(empty_color);
                                }
                            } else {
                                if (selected.contains(j) == true) {
                                    j.setBackground(fill_color);
                                }
                            }
                        }
                    }
                }
            }

            for (JLabel j : current_selection) {
                if (mode == 1) {
                    j.setBackground(fill_select);
                } else if (mode == -1) {
                    j.setBackground(empty_select);
                }
            }

        }

        @Override
        public void mouseMoved(MouseEvent me) {
        }
    });
}

private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    jPanel1 = new javax.swing.JPanel();
    grid = new javax.swing.JPanel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setLayout(new java.awt.BorderLayout());

    grid.setLayout(new java.awt.GridLayout(25, 0, 2, 2));
    jPanel1.add(grid, java.awt.BorderLayout.CENTER);

    jScrollPane1.setViewportView(jPanel1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 465, Short.MAX_VALUE)
    );

    pack();
}

public static void main(String args[]) {

    new TimetableFrame().setVisible(true);

}

}

person Fatih Halimoglu    schedule 15.12.2018