Я новичок в Java, и на этот раз я пытаюсь узнать больше, находя примеры кода и редактируя их, например, с этого сайта. У меня есть JFrame, и каждый раз, когда на него (точнее, на JPanel в нем) нажимают, рисуется круг, который будет расти/расширяться наружу, как водная рябь. Каждый круг начинается с определенного радиуса и будет удаляться или перерисовываться при достижении большего радиуса (я выбрал радиус r от 10 до 200). У меня есть две программы для этого, которые почти работают, но чего-то не хватает. Если я прав, я также могу знать, в чем их проблемы, но я не могу понять, как их решить:
Один генерирует растущие круги, но все они имеют одинаковый размер, независимо от того, когда они созданы, так как я не могу понять, как назначить радиус одному кругу. Код взят из здесь:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Ripples extends JPanel implements ActionListener{
public int r = 10;
private ArrayList<Point> p;
public Ripples() {
p = new ArrayList<>();
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getX(), e.getY()));
}
});
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.CYAN);
for (Point pt : p) {
g2.drawOval(pt.x-r, pt.y-r, 2*r, 2*r);
}
}
@Override
public void actionPerformed(ActionEvent evt) {
if(r<200){
r++;
} else {
r = 10;
}
repaint();
}
public static void Gui() {
JFrame f = new JFrame();
Ripples p = new Ripples();
p.setBackground(Color.WHITE);
f.setContentPane(p);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500,300);
f.setVisible(true);
Timer t = new Timer(20,p);
t.start();
}
public static void main(String[] args) {
Gui();
}
}
В другой программе (забыл откуда взял) есть круги с разным радиусом в зависимости от того, когда они были сгенерированы, однако круги мерцают, потому что - насколько я понимаю - все они обрабатываются одновременно, т.к. код не включает массив для хранения и обновления каждого круга по отдельности, как это сделано выше:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Ripples extends JPanel {
int x,y;
int r = 10;
public Ripples(int x, int y) {
this.x = x;
this.y = y;
Timer t = new Timer(20, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (r<200) {
r++;
} else {
r=10;
}
revalidate();
repaint();
}
});
t.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.CYAN);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawOval(x-r,y-r,2*r,2*r);
}
public static void Gui() {
JFrame f = new JFrame("Water Ripples");
JPanel p0 = new JPanel();
p0.setBackground(Color.WHITE);
f.add(p0);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(100,100,600,500);
f.setVisible(true);
f.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Ripples rG = new Ripples(e.getX(), e.getY());
rG.setBackground(Color.WHITE);
f.add(rG);
}
});
}
public static void main(String[] args) {
Gui();
}
}
Итак, как я могу решить эту проблему, чтобы круги росли независимо друг от друга? Я бы предпочел решение/улучшение/подсказку для верхнего кода, потому что я думаю, что он структурирован лучше, чем второй. Кроме того, я приношу свои извинения за то, что не разделил код на несколько классов и, возможно, не придерживаюсь соглашений об именах. Я ценю вашу помощь, большое спасибо!
r
— константа, поэтому круги будут одинакового размера. Вам нужно будет изменитьr
в зависимости от того, где находится ваша мышь. - person NomadMaker   schedule 08.09.2020f.add(rG)
следует удалить все предыдущие панели из BorderLayout панели содержимого JFrame перед добавлением новой. - person VGR   schedule 08.09.2020