#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. После добавления нового прямоугольника любого размера вы можете пересчитать предпочтительный размер для соответствующей ширины / высоты.