Вызов paint() из другого метода в Java

#java #swing #graphics #components #paint

#java #swing #графика #Компоненты #Краски

Вопрос:

чего я пытаюсь достичь в Java, так это иметь возможность рисовать случайные фигуры из другого метода без необходимости уже рисовать эти фигуры с самого начала (пользователь сам выбирает x, y, w, h)

Вот что у меня есть до сих пор:

 public class Design extends JComponent {
private static final long serialVersionUID = 1L;

public void paint(Graphics g) {
    super.paintComponent(g);
}

public void drawRect(int xPos, int yPos, int width, int height) {
    Graphics g = null;
    g.drawRect(width, height, xPos, yPos);
}
}
  

Как вы можете видеть выше, у меня закодирована функция drawRect, но я не понимаю, как сделать так, чтобы при вызове функции drawRect() она заставляла функцию paint() рисовать прямоугольник вместо этого, что и делает функция paint, внутри нее вы вводите g.drawRect() и ваши x, y, w, h.
Причина, по которой я делаю это, а не просто использую paint(), заключается в том, что я пытаюсь создать компонент, поэтому вместо того, чтобы каждый раз вводить функцию paint(), я просто добавляю этот класс в свой Swing, и все готово.

Надеюсь, вы понимаете, чего я пытаюсь здесь достичь. Спасибо.

Ответ №1:

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

По сути, вы не вызываете paint напрямую, paint вызывается в ответ на RepaintManager желание что-то нарисовать.

Посмотрите на рисование в AWT и Swing и выполнение пользовательского рисования.

Перейдем к вашему коду. Не переопределяйте paint и, конечно же, не обходите процесс рисования, вместо этого он должен выглядеть примерно так…

 @Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    drawRect(g, 10, 10, 10, 10);
}

protected void drawRect(Graphics g, int xPos, int yPos, int width, int height) {
    g.drawRect(xPos, yPos, width, height);
}
  

Graphics#drawRect на самом деле принимает параметры x , y , width , height в таком порядке…

Причина, по которой я делаю это, а не просто использую paint(), заключается в том, что я пытаюсь создать компонент so вместо того, чтобы каждый раз вводить функцию paint()

Не имеет смысла, в этом смысл использования paint методов, поэтому вы можете настроить способ рисования компонента, создать множество его экземпляров и добавить его в свой графический интерфейс … вот как работают все элементы управления Swing…

Кроме того, вы можете найти интересную 2D-графику

Обновлено на основе комментариев

Итак, вам нужен метод, который может вызывать какой-либо другой объект, и это позволит им добавить «прямоугольник» к существующему объекту / компоненту…

Начните с определения переменной экземпляра Rectangle

 private Rectangle rectangle;
  

В вашем paintComponent проверьте, есть ли rectangle это null или нет, и если это не так, нарисуйте его…

 protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (rectangle != null)  {
        Graphics2D g2d = (Graphics2D)g;
        g2d.draw(rectangle);
    }
}
  

Теперь обновите свой drawRect метод, чтобы создать экземпляр Rectangle и запросить перерисовку компонента

 public void drawRect(int xPos, int yPos, int width, int height) {
    rectangle = new Rectangle(xPos, yPos, width, height);
    repaint();
}
  

Например…

 public class Design extends JComponent {

    private Rectangle rectangle;

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (rectangle != null)  {
            Graphics2D g2d = (Graphics2D)g;
            g2d.draw(rectangle);
        }
    }

    public void drawRect(int xPos, int yPos, int width, int height) {
        rectangle = new Rectangle(xPos, yPos, width, height);
        repaint();
    }
}
  

Теперь, если вы хотите поддерживать наличие нескольких прямоугольников, вы можете просто использовать a List и добавлять столько экземпляров Rectangle , сколько хотите, повторяя List in paintComponent метод

Комментарии:

1. Спасибо за ввод, как и в методе paintComponent(), который вы написали drawRect(g, 10, 10, 10, 10); но то, что я пытаюсь сделать, это иметь возможность выполнить это из другого класса, все, что я делаю, — это то, что во вторую секунду, когда я вызываю метод, он заставитсам по себе, чтобы нарисовать прямоугольник, я хочу контролировать выполнение этого, как я хочу, почти как экземпляр класса. Меня не заставляют таким образом рисовать прямоугольник, я делаю это так, как мне нравится.

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

Ответ №2:

Вам нужно выполнить все рисования внутри paintComponent() метода с помощью вызова super.paintComponent() .

Я предлагаю вам сохранить все необходимые фигуры List и нарисовать их все paintComponent() . Вместо drawRect того, чтобы использовать что-то подобное addRect , добавляющее новую форму к вашему List repaint() методу and call. Рассмотрим следующий простой пример:

 import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class TestFrame extends JFrame {

    public TestFrame() {
        System.out.println("as".equalsIgnoreCase(null));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        init();
        pack();
        setVisible(true);
    }

    private void init() {
        final Design d = new Design();
        d.addRect(0,0,10,20);

        JButton b = new JButton("add");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Random r = new Random();
                int w = r.nextInt(100);
                int h = r.nextInt(100);
                d.addRect(0,0,w,h);
            }
        });
        add(d);
        add(b,BorderLayout.SOUTH);
    }

    public static void main(String... strings) {
        new TestFrame();
    }

    private class Design extends JComponent {
        private static final long serialVersionUID = 1L;

        private List<Shape> shapes = new ArrayList<Shape>();

        public void paint(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            for(Shape s : shapes){
                g2d.draw(s);
            }
        }

        public void addRect(int xPos, int yPos, int width, int height) {
            shapes.add(new Rectangle(xPos,yPos,width,height));
            repaint();
        }

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

    }

}
  

Комментарии:

1. Спасибо всем за быструю помощь! Итак, попробовал то, что вы сделали здесь, и это действительно сработало именно так, как ожидалось! Теперь просто нужно добавить больше фигур, хотя, когда я пытаюсь его выполнить, прямоугольник состоит из 4 строк, отображается только 2??

2. Возможно, вы захотите рассмотреть требования к начальным потокам 😉

3. Спасибо, тоже разобрался с проблемой, это просто предпочтительный размер, в любом случае я могу сделать его бесконечным, чтобы вы могли сделать прямоугольник любого размера, который вы хотите??

4. После добавления нового прямоугольника любого размера вы можете пересчитать предпочтительный размер для соответствующей ширины / высоты.