Java 随机函数在重新绘制时不会再次执行吗?
我正在编写一个代码,在这个代码中,我在JPanel上绘制多个形状,然后调用repaint。我认为当我调用repaint时,JPanel中的形状应该移动到一个新位置,因为随机函数现在将提供不同的值。但这些形状根本不移动。你知道为什么会这样吗Java 随机函数在重新绘制时不会再次执行吗?,java,swing,jpanel,repaint,Java,Swing,Jpanel,Repaint,我正在编写一个代码,在这个代码中,我在JPanel上绘制多个形状,然后调用repaint。我认为当我调用repaint时,JPanel中的形状应该移动到一个新位置,因为随机函数现在将提供不同的值。但这些形状根本不移动。你知道为什么会这样吗 import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.eve
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
@SuppressWarnings("serial")
public class Filter extends JFrame
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Filter mainFrame = new Filter();
mainFrame.setVisible(true);
}
});
}
public Filter()
{
//Creating the JFrame main window
setSize(800, 500);
setTitle("Particle Filter");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocation(100, 100);
getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.X_AXIS));
//creates two panels content and sidebar. Sidebar has null layout
JPanel content = new JPanel();
content.setPreferredSize(new Dimension(700,500));
content.setBackground(Color.LIGHT_GRAY);
this.getContentPane().add(content);
JPanel sidebar = new JPanel();
sidebar.setBackground(Color.LIGHT_GRAY);
sidebar.setPreferredSize(new Dimension(100,500));
this.getContentPane().add(sidebar);
sidebar.setLayout(null);
//creates three buttons in sidebar
JButton start_button = new JButton("START");
start_button.setBounds(10, 75, 77, 23);
start_button.addActionListener(new MainPanel());
sidebar.add(start_button);
JButton stop_button = new JButton("STOP");
stop_button.setBounds(10, 109, 77, 23);
sidebar.add(stop_button);
JButton reset_button = new JButton("RESET");
reset_button.setBounds(10, 381, 77, 23);
sidebar.add(reset_button);
//calls the content_Walls class and sends the number of ovals to be generated
content.add( new MainPanel());
}
}
@SuppressWarnings("serial")
class MainPanel extends JPanel implements ActionListener
{
public MainPanel()
{
setPreferredSize(new Dimension(680,450));
setBackground(Color.WHITE);
setBorder(BorderFactory.createLineBorder(Color.black));
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("START"))
{
repaint();
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawParticles(g);
createObstacles(g,150,225,100,40);
createObstacles(g,500,300,40,100);
createRobot(g);
}
private void createRobot(Graphics g)
{
int x=0, y=0;
int robot_radius=50;
ArrayList<Integer> robot_list= new ArrayList<Integer>();
robot_list=positionRobot(x,y);
drawRobot(g,robot_list.get(0),robot_list.get(1),robot_radius);
}
private void drawParticles(Graphics g)
{
int n=1000; // n denotes the number of particles
ArrayList<Integer> list;
list = new ArrayList<Integer>(Collections.nCopies(n, 0));
for(int i=0;i<list.size();i++)
{
generateParticles(g);
}
}
private void generateParticles(Graphics g)
{
int x=0;
int y=0;
int radius = 4;
ArrayList<Integer> list= new ArrayList<Integer>();
list=positionParticles(x,y);
g.setColor(Color.RED);
g.fillOval(list.get(0),list.get(1), radius, radius);
}
private ArrayList<Integer> positionParticles(int x, int y)
{
int radius = 4;
ArrayList<Integer> list= new ArrayList<Integer>();
x=randomInteger(2,678); // bounds of x between which the particles should be generated
y=randomInteger(2,448); // bounds of y between which the particles should be generated
x=x-(radius/2);
y=y-(radius/2);
if((x<251&&x>=150)&&(y<266&&y>=225))
{
x=0;
y=0;
positionParticles(x,y);
}
if((x<541&&x>499)&&(y<401&&y>299))
{
x=0;
y=0;
positionParticles(x,y);
}
list.add(x);
list.add(y);
return list;
}
private ArrayList<Integer> positionRobot(int x, int y)
{
int robot_radius=50;
ArrayList<Integer> list= new ArrayList<Integer>();
x=randomInteger(25,655);//so that it stays inside the content_Walls panel
y=randomInteger(25,425); //so that it stays inside the content_Walls panel
x=x-(robot_radius/2);
y=y-(robot_radius/2);
if((x<250&&x>=150)&&(y<=265&&y>=225))
{
x=0;
y=0;
positionRobot(x,y);
}
if((x<=540&&x>=500)&&(y<=400&&y>=300))
{
x=0;
y=0;
positionRobot(x,y);
}
list.add(x);
list.add(y);
return list;
}
private void createObstacles(Graphics g, int x, int y, int width, int height)
{
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
}
private void drawRobot(Graphics g, int x, int y, int radius)
{
g.setColor(Color.GREEN);
g.fillOval(x, y, radius, radius);
}
private static int randomInteger(int min, int max)
{
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.Random;
导入javax.swing.BorderFactory;
导入javax.swing.BoxLayout;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
导入javax.swing.WindowConstants;
@抑制警告(“串行”)
公共类筛选器扩展JFrame
{
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable()
{
公开募捐
{
过滤器主机=新过滤器();
mainFrame.setVisible(true);
}
});
}
公共过滤器()
{
//创建JFrame主窗口
设置大小(800500);
setTitle(“粒子过滤器”);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
设置位置(100100);
getContentPane().setLayout(新的BoxLayout(this.getContentPane(),BoxLayout.X_轴));
//创建两个面板内容和侧栏。侧栏的布局为空
JPanel content=新的JPanel();
content.setPreferredSize(新维度(700500));
内容。背景(颜色。浅灰色);
this.getContentPane().add(内容);
JPanel侧边栏=新的JPanel();
侧边栏.背景(颜色.浅灰色);
侧栏。设置首选尺寸(新尺寸(100500));
this.getContentPane().add(侧栏);
侧栏.setLayout(空);
//在侧边栏中创建三个按钮
JButton start_按钮=新JButton(“开始”);
开始按钮。后退(10,75,77,23);
启动按钮。添加ActionListener(新的主面板());
侧边栏。添加(开始按钮);
JButton stop_按钮=新JButton(“stop”);
停止按钮。立根(10、109、77、23);
添加(停止按钮);
JButton reset_按钮=新JButton(“reset”);
重置按钮。立根(10381,77,23);
侧栏。添加(重置按钮);
//调用content_Walls类并发送要生成的椭圆数
添加(新的主面板());
}
}
@抑制警告(“串行”)
类MainPanel扩展JPanel实现ActionListener
{
公共主面板()
{
setPreferredSize(新尺寸(680450));
挫折地面(颜色:白色);
setboorder(BorderFactory.createLineBorder(Color.black));
}
已执行的公共无效操作(操作事件e)
{
如果(例如getActionCommand().equals(“开始”))
{
重新油漆();
}
}
@凌驾
公共组件(图形g)
{
超级组件(g);
颗粒(g);
(g,150225100,40);
(g,500300,40100);
createRobot(g);
}
私有void createRobot(图形g)
{
int x=0,y=0;
int机器人_半径=50;
ArrayList robot_list=新建ArrayList();
机器人列表=定位机器人(x,y);
drawRobot(g,robot_list.get(0),robot_list.get(1),robot_半径);
}
私有空心粒子(图形g)
{
int n=1000;//n表示粒子数
数组列表;
list=newarraylist(Collections.nCopies(n,0));
对于(int i=0;i而言,基本问题是,响应JButton
的MainPanel
实例与屏幕上的MainPanel
实例不同
// Instance one...
start_button.addActionListener(new MainPanel());
//...
// Instance two...
//calls the content_Walls class and sends the number of ovals to be generated
content.add(new MainPanel());
相反,创建一个实例并在两种情况下使用它
MainPanel mainPanel = new MainPanel();
start_button.addActionListener(mainPanel);
//...
//calls the content_Walls class and sends the number of ovals to be generated
content.add(mainPanel);
当你准备插入stop按钮的功能时,再次使用同一个实例。这可能是因为你没有为Random的cunstructor使用种子值。但不确定这是否也是Java语言还是其他语言。(阅读文档,可能是另一种语言)
您可以将时间用作种子值:
Random rand = new Random(System.currentTimeMillis());
此外,可以将rand设置为字段,并且只对其进行一次cunstruct:
private static Random rand;
private static int randomInteger(int min, int max)
{
if (rand == null)
rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
代码未测试。抱歉,我快睡着了。您应该将代码精简到实际相关的内容。避免使用null
布局,像素完美的布局在现代ui设计中是一种幻觉。有太多的因素会影响组件的单个大小,您无法控制。Swing的设计目的在于h布局管理器的核心是,丢弃这些将导致无止境的问题,您将花费越来越多的时间试图解决这些问题rectify@MadProgrammer因此,这是由于空布局造成的?重新绘制技术正确吗?@user3097157不,这是因为您正在创建多个MainPanel
实例关于null
layouts的建议只是一般性的观察和最佳实践的建议…@MadProgrammer那么,除了null layout之外,我应该如何编写需要自定义设置的东西。哇。非常感谢。我在这个问题上坚持了这么久。另外,请参阅GiCo关于不要每次都创建一个新的random实例的回答!(虽然不是问题,但这是一个很好的建议!)根据,随机
的默认构造函数将“创建一个新的随机数生成器。此构造函数将随机数生成器的种子设置为一个很可能与此构造函数的任何其他调用不同的值。”…所以我看不出这会是个什么问题…是的,我读过。我记得有这个问题,但是
private static Random rand;
private static int randomInteger(int min, int max)
{
if (rand == null)
rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}