所以我正在开发一个需要GUI的项目;目前,我有一个类,它创建了一个JFrame,其中包含一群代理,这些代理在环境中飞行。我需要为这个JFrme添加一个GUI,这样我就可以控制flock的大小以及其他项目。 我在eclipse中使用WindowBuilder来创建GUI,我现在需要附加'这个GUI到另一个类的框架,或者至少有这个GUI窗口与另一个类同时运行,这样当我在eclipse中运行应用程序时,我可以使用滑块控制flock大小然后运行flock模拟,从GUI中获取变量。
我一直在网上搜索相当长的一段时间,试图弄清楚如何做到这一点,但我还没有找到答案。
Emre代码 - >感谢你目前的帮助!我已经设法让所有关于JPanel的工作都有效但我仍然遇到关于" Run"的动作滑动器的问题。按钮...我已经包含了修改后的代码,该代码在主类" Boids"中包含了btnRun的actionlistener。 - 对我来说,看起来一切都是正确的,当按下它时,它应该按预期运行,但无论出于何种原因,这个按钮仍然不起作用,我无法弄清楚为什么......
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
import static java.lang.Math.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
import javax.swing.Timer;
import java.util.Random;
import javax.swing.JButton;
public class Boids extends JPanel {
Flock flock;
Flock flock2;
final int w, h;
public Boids() {
w = 1200;
h = 600;
setPreferredSize(new Dimension(w, h));
setBackground(Color.black);
spawnFlock();
spawnFlock2();
new Timer(17, (ActionEvent e) -> {
if (flock.hasLeftTheBuilding(w))
spawnFlock();
repaint();
}).start();
new Timer(18, (ActionEvent e) -> {
if (flock2.hasLeftTheBuilding(w) && (flock.hasLeftTheBuilding(w)))
spawnFlock2();
repaint();
}).start();
//need to wait for the rest of the flock to leavebuilding before respawning leader, spawning is out of sync
}
public void spawnFlock() {
Random rand = new Random();
int n = rand.nextInt(599) + 1;
//implement random for width as well as height
flock = Flock.spawn(100, h - n, 20);
flock2 = Flock.spawn(100, h - n, 1);
}
public void spawnFlock2() {
Random rand = new Random();
int n = rand.nextInt(599) + 1;
//implement random for width as well as height
// flock2 = Flock.spawn(100, h - n, 1);
}
@Override
public void paintComponent(Graphics gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
SimGUI buttonx = new SimGUI();
buttonx.btnRun.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event1) {
flock.run(g, w, h);
}
});
// flock.
// flock2.run(g, w, h);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Simulator v0.6");
f.setResizable(false);
f.add(new Boids(), BorderLayout.CENTER);
// f.add(new Boids(), BorderLayout.CENTER); to add another flock to environment
//leaders will also be added in this fashion
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
// SimGUI.getFrames();
// SimGUI test = new SimGUI();
// test.panel.setVisible(true);
SimGUI test = new SimGUI();
f.getContentPane().add(test, BorderLayout.EAST); //just positions a slither to the right, dont understand why it wont display jpanel -->
//COULD THIS BE BECAUSE OF ME SETTING PREFERRED SIZE AND WIDTH/HEIGHT OUTSIDE OF MAIN? SEE "public Boids"...
//SimGUI tempt = new SimGUI();
// tempt.setVisible(true);
});
}
// private void printPanelCompPoints(JPanel f) {
// f.getComponentAt(600, 500);
//currently working on this = voting system
//see psuedocode!
}
//}
class Boid {
static final Random r = new Random();
static final Vec migrate = new Vec(0.02, 0);
static final int size = 3;
static final Path2D shape = new Path2D.Double();
static {
shape.moveTo(0, -size * 2);
shape.lineTo(-size, size * 2);
shape.lineTo(size, size * 2);
shape.closePath();
}
final double maxForce, maxSpeed;
Vec location, velocity, acceleration;
private boolean included = true;
Boid(double x, double y) {
acceleration = new Vec();
velocity = new Vec(r.nextInt(3) + 1, r.nextInt(3) - 1);
location = new Vec(x, y);
maxSpeed = 3.0;
maxForce = 0.05;
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
location.add(velocity);
acceleration.mult(0);
}
void applyForce(Vec force) {
acceleration.add(force);
}
Vec seek(Vec target) {
Vec steer = Vec.sub(target, location);
steer.normalize();
steer.mult(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
return steer;
}
void flock(Graphics2D g, List<Boid> boids) {
view(g, boids);
Vec rule1 = separation(boids);
Vec rule2 = alignment(boids);
Vec rule3 = cohesion(boids);
rule1.mult(2.5);
rule2.mult(1.5);
rule3.mult(1.3);
applyForce(rule1);
applyForce(rule2);
applyForce(rule3);
applyForce(migrate);
}
void view(Graphics2D g, List<Boid> boids) {
double sightDistance = 100;
double peripheryAngle = PI * 0.85;
for (Boid b : boids) {
b.included = false;
if (b == this)
continue;
double d = Vec.dist(location, b.location);
if (d <= 0 || d > sightDistance)
continue;
Vec lineOfSight = Vec.sub(b.location, location);
double angle = Vec.angleBetween(lineOfSight, velocity);
if (angle < peripheryAngle)
b.included = true;
}
}
Vec separation(List<Boid> boids) {
double desiredSeparation = 25;
Vec steer = new Vec(0, 0);
int count = 0;
for (Boid b : boids) {
if (!b.included)
continue;
double d = Vec.dist(location, b.location);
if ((d > 0) && (d < desiredSeparation)) {
Vec diff = Vec.sub(location, b.location);
diff.normalize();
diff.div(d); // weight by distance
steer.add(diff);
count++;
}
}
if (count > 0) {
steer.div(count);
}
if (steer.mag() > 0) {
steer.normalize();
steer.mult(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
return steer;
}
return new Vec(0, 0);
}
Vec alignment(List<Boid> boids) {
double preferredDist = 50;
Vec steer = new Vec(0, 0);
int count = 0;
for (Boid b : boids) {
if (!b.included)
continue;
double d = Vec.dist(location, b.location);
if ((d > 0) && (d < preferredDist)) {
steer.add(b.velocity);
count++;
}
}
if (count > 0) {
steer.div(count);
steer.normalize();
steer.mult(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
Vec cohesion(List<Boid> boids) {
double preferredDist = 50;
Vec target = new Vec(0, 0);
int count = 0;
for (Boid b : boids) {
if (!b.included)
continue;
double d = Vec.dist(location, b.location);
if ((d > 0) && (d < preferredDist)) {
target.add(b.location);
count++;
}
}
if (count > 0) {
target.div(count);
return seek(target);
}
return target;
}
/* Vec avoid(List<Boid> boids) {
int up = 0;
int down = 0;
for (Boid b : boids) {
if (b.location.x + 100 > 600 ) {
up = 1;
}
}
return velocity = new Vec (0,1);
} */
void draw(Graphics2D g) {
AffineTransform save = g.getTransform();
g.translate(location.x, location.y);
g.rotate(velocity.heading() + PI / 2);
g.setColor(Color.green);
g.fill(shape);
g.setColor(Color.green);
g.draw(shape);
g.setTransform(save);
g.drawOval(600, 500, 75, 75);
}
void run(Graphics2D g, List<Boid> boids, int w, int h) { //similair method to run leader
flock(g, boids);
update();
draw(g);
//may need additional run method for leader
}
}
class Flock {
List<Boid> boids;
Flock() {
boids = new ArrayList<>();
}
void run(Graphics2D g, int w, int h) {
for (Boid b : boids) {
b.run(g, boids, w, h);
}
}
boolean hasLeftTheBuilding(int w) {
int count = 0;
for (Boid b : boids) {
if (b.location.x + Boid.size > w) //will also be used to calculate votes based on whether boids is near food
count++;
}
return boids.size() == count;
}
void addBoid(Boid b) {
boids.add(b);
}
static Flock spawn(double w, double h, int numBoids) {
Flock flock = new Flock();
for (int i = 0; i < numBoids; i++)
flock.addBoid(new Boid(w, h));
return flock;
}
}
class Vec {
double x, y;
Vec() {
}
Vec(double x, double y) {
this.x = x;
this.y = y;
}
void add(Vec v) {
x += v.x;
y += v.y;
}
void sub(Vec v) {
x -= v.x;
y -= v.y;
}
void div(double val) {
x /= val;
y /= val;
}
void mult(double val) {
x *= val;
y *= val;
}
double mag() {
return sqrt(pow(x, 2) + pow(y, 2));
}
double dot(Vec v) {
return x * v.x + y * v.y;
}
void normalize() {
double mag = mag();
if (mag != 0) {
x /= mag;
y /= mag;
}
}
void limit(double lim) {
double mag = mag();
if (mag != 0 && mag > lim) {
x *= lim / mag;
y *= lim / mag;
}
}
double heading() {
return atan2(y, x);
}
static Vec sub(Vec v, Vec v2) {
return new Vec(v.x - v2.x, v.y - v2.y);
}
static double dist(Vec v, Vec v2) {
return sqrt(pow(v.x - v2.x, 2) + pow(v.y - v2.y, 2));
}
static double angleBetween(Vec v, Vec v2) {
return acos(v.dot(v2) / (v.mag() * v2.mag()));
}
工作JPanel! - &GT;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
import javax.swing.JToolBar;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JSlider;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.Color;
import com.jgoodies.forms.layout.FormSpecs;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.Font;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
public class SimGUI extends JPanel {
/**
* Create the panel.
*/
//JPanel panel = new JPanel();
public JPanel panel_1 = new JPanel();
private JTextField textField;
private JTextField textField_1;
public JButton btnRun = new JButton("Run");
public SimGUI() {
JSlider sizeOfFlock = new JSlider();
sizeOfFlock.setValue(10);
sizeOfFlock.setMaximum(20);
sizeOfFlock.setMinimum(1);
JLabel lblNewLabel = new JLabel("Settings");
lblNewLabel.setFont(new Font("Sitka Banner", Font.BOLD, 18));
JLabel lblFlockSize = new JLabel("Flock Size");
lblFlockSize.setFont(new Font("Sitka Heading", Font.BOLD, 16));
JLabel label = new JLabel("1");
label.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel label_1 = new JLabel("20");
label_1.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel lblTypesOfLeader = new JLabel("Types of Leader:");
lblTypesOfLeader.setFont(new Font("Sitka Heading", Font.BOLD, 16));
JLabel lblNewLabel_1 = new JLabel("Spawn a leader inside the Flock");
lblNewLabel_1.setFont(new Font("Sitka Subheading", Font.PLAIN, 14));
JLabel lblSpawnAPersistant = new JLabel("Spawn a persistant leader");
lblSpawnAPersistant.setFont(new Font("Sitka Subheading", Font.PLAIN, 14));
JCheckBox checkBox = new JCheckBox("");
JCheckBox checkBox_1 = new JCheckBox("");
JSlider noOfRuns = new JSlider();
textField = new JTextField();
textField.setColumns(10);
textField.setText("" + noOfRuns.getValue());
textField_1 = new JTextField();
textField_1.setColumns(10);
textField_1.setText("" + sizeOfFlock.getValue());
/**
* Handle change event for sizeOfFlock slider.
*/
sizeOfFlock.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e) {
textField_1.setText(String.valueOf(sizeOfFlock.getValue()));
}
});
textField_1.addKeyListener(new KeyAdapter(){
@Override
public void keyReleased(KeyEvent ke) {
String typed = textField_1.getText();
sizeOfFlock.setValue(0);
if(!typed.matches("\\d+") || typed.length() > 3) {
return;
}
int value = Integer.parseInt(typed);
sizeOfFlock.setValue(value);
}
});
/**
* Handle change event for noOfRuns slider.
*/
noOfRuns.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e) {
textField.setText(String.valueOf(noOfRuns.getValue()));
}
});
textField.addKeyListener(new KeyAdapter(){
@Override
public void keyReleased(KeyEvent ke) {
String typed = textField.getText();
noOfRuns.setValue(0);
if(!typed.matches("\\d+") || typed.length() > 3) {
return;
}
int value = Integer.parseInt(typed);
noOfRuns.setValue(value);
}
});
JLabel label_2 = new JLabel("1");
label_2.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel label_3 = new JLabel("100");
label_3.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel lblNoOfSimulation = new JLabel("No. of runs");
lblNoOfSimulation.setFont(new Font("Sitka Heading", Font.BOLD, 16));
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(83)
.addComponent(lblNewLabel)
.addGap(82)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(label, GroupLayout.PREFERRED_SIZE, 11, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(sizeOfFlock, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(label_1, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblFlockSize)))
.addContainerGap())
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblNoOfSimulation)
.addContainerGap(207, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(label_2, GroupLayout.PREFERRED_SIZE, 11, GroupLayout.PREFERRED_SIZE)
.addGap(2)
.addComponent(noOfRuns, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(label_3, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 10, Short.MAX_VALUE)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
.addGap(6))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblTypesOfLeader)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblNewLabel_1)
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(checkBox_1, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
.addComponent(checkBox)))
.addComponent(lblSpawnAPersistant, GroupLayout.PREFERRED_SIZE, 178, GroupLayout.PREFERRED_SIZE))
.addContainerGap(53, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addGap(86)
.addComponent(btnRun, GroupLayout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE)
.addContainerGap(136, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(5)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(5)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblNewLabel)))
.addPreferredGap(ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
.addComponent(lblFlockSize)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(label, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addComponent(sizeOfFlock, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(label_1, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addGap(28)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblTypesOfLeader)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblNewLabel_1))
.addComponent(checkBox))
.addGap(11)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblSpawnAPersistant, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE)
.addComponent(checkBox_1, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE))
.addGap(30)
.addComponent(lblNoOfSimulation, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(noOfRuns, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(label_2, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(label_3, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addComponent(btnRun, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
.addGap(225))
);
setLayout(groupLayout);
};
}
当&#34; Run&#34;按下按钮它应该执行flock.run(x,x,x),但尽管我的努力,这仍然不会按预期执行。我希望你能够弄清楚为什么会这样,因为我已经玩了很长时间了但是还没有按预期工作
答案 0 :(得分:0)
将要添加到JFrame的GUI设置为JPanel。使用它作为容器来保存要添加到GUI的组件(按钮,标签,文本区域等)。之后调用
frame.getContentPane().add(panel);
JFrame的默认布局是边框布局。因此,如果不修改默认行为,JPanel将被deafult置于中心位置。
如果要将多个JPanel添加到同一个JFrame,那么您应该明确指定哪个面板转到哪个区域
frame.getContentPane().add(panel1, BorderLayout.CENTER);
frame.getContentPane().add(panel2, BorderLayout.LEFT);
如果您未指定布局区域,则只会在中心显示添加的最后一个面板。
对于多个容器,我建议使用一个JPanel作为主容器并相应地设置其布局。接下来,将其他组件添加到主JPanel,然后仅将该JPanel添加到JFrame。