我是一名学生,并且正在做一个项目,这只是我的最终项目实际上的一点,但我试图尽可能地划分它。
我遇到的具体问题与创建一个java应用程序有关,该应用程序显示一个带有按钮的框架,允许用户在屏幕上创建多个球,然后您可以通过单击它们来选择每个球。
我尝试添加一些小修改,但是如果没有它们正在工作我将其删除,以便在找到解决方案时为您提供更多自由。
以下是Simulation
类的代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Simulation {
int noOfBallClicks = 0;
Simulation() {
buildTheGUI();
}
JFrame frame = new JFrame();
JFrame frame2 = new JFrame();
JPanel panal = new JPanel();
JButton add = new JButton("add a new object");
public void buildTheGUI() {
frame.setVisible(true);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panal);
panal.add(add);
add.addActionListener(new ButtonClickHandler());
}
public static void main(String[] args) {
new Simulation();
}
class ButtonClickHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
noOfBallClicks = noOfBallClicks++;
frame.add(new Ball());
frame.validate();
}
}
}
以下是Ball
类的代码:
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class Ball extends JPanel {
private int x;
private int y;
private int w;
private int h;
Ball() {
this.x = 200;
this.y = 200;
this.w = 100;
this.h = 100;
}
Ball(int a) {
Random rand = new Random();
this.w = 100;
this.h = 100;
this.x = rand.nextInt(300);
this.y = rand.nextInt(300);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillOval(x, y, h, w);
}
}
答案 0 :(得分:2)
我遇到的具体问题与创建java应用程序有关 显示带有按钮的框架,允许用户创建 屏幕上有多个球,然后您可以选择每个球 点击它们。
我已经尝试添加小修改,但不使用它们 将其删除,以便在找到解决方案时为您提供更多自由。
你永远不会提到错误/想要实现的目标......除了以上和标题:选择已经重新绘制的对象
但是我在给出的代码中看到了一些问题:
1)在添加所有组件之前,不要将JFrame
设置为可见(或者您将遇到内容不可见等问题)
2)不要在setSize
上致电JFrame
而是覆盖getPreferredSize()
的{{1}},并返回符合JPanel
对象上图纸的Dimension
和/或使用适当的Graphics
。我们可以在LayoutManager
上拨打pack()
而不是setSize(...)
。
3)应通过JFrame
块在事件调度线程上创建和操作Swing组件。 Read Concurrency in Swing了解更多信息。
4)当您使用SwingUtilities.invokeLater(Runnable r)
时,应该调用validate()
来反映所做的更改。
5)您还使用了repaint()
的默认JFrame
布局添加了一个面板,而默认BorderLayout
的球(使用按钮监听器)将添加到其中BorderLayout
所以每次致电BorderLayout.CENTER
时,您都会将旧的球 / JFrame#add(Component c)
替换为另一个。
6)正如使用JPanel
一样,如果2 JPanel
最终处于重叠位置,则顶部Ball
及其Ball
将覆盖底部JPanel
{1}} ...您需要一个透明的面板,即Ball
。
7)当我进行自定义绘画时,我很少使用JComponent#setOpaque(false)
或其扩展名。我宁愿创建一个JComponent
,它将作为我需要绘制/显示的内容的虚拟表示或任何(可能是个人偏好)。这些对象将在我的Object
JPanel
中显示,而paintComponent(..)
会draw(..)
方法将Graphics
JPanel
对象传递给每个Ball
这将根据字段数据绘制自己。
这是我做的一个简短例子(考虑到上述情况):
所有绿色balls
已被选中,即点击,而红色则没有。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final DrawPanel drawPanel = new DrawPanel();
drawPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
for (Ball b : drawPanel.getBalls()) {//iterate through each ball
if (b.getBounds().contains(me.getPoint())) {//get the ball bounds and check if mouse click was within its bounds
if (!b.isSelected()) {//check if ball has been clicked on
b.setSelected(true);
} else {
b.setSelected(false);
}
drawPanel.repaint();//so ball color change will be shown
}
}
}
});
JPanel controlPanel = new JPanel();
JButton createBallButton = new JButton("Add ball");
createBallButton.addActionListener(new ActionListener() {
Random rand = new Random();
private int counter = 1;
public void actionPerformed(ActionEvent e) {
int ballRadius = 10;
int x = rand.nextInt(drawPanel.getWidth());
int y = rand.nextInt(drawPanel.getHeight());
//check that we dont go offscreen by subtarcting its radius unless its x and y are not bigger than radius
if (y > ballRadius) {
y -= ballRadius;
}
if (x > ballRadius) {
x -= ballRadius;
}
drawPanel.addBall(new Ball(x, y, ballRadius, counter));//add ball to panel to be drawn
counter++;//increase the ball number
}
});
final JTextArea jtf = new JTextArea(5, 10);
jtf.setEditable(false);
JButton printSelectedBallButton = new JButton("Print selected balls");
printSelectedBallButton.addActionListener(new ActionListener() {
Random rand = new Random();
private int counter = 1;
public void actionPerformed(ActionEvent e) {
jtf.setText("");
for (Ball b : drawPanel.getBalls()) {
if (b.isSelected()) {
jtf.append("Selected: " + b.getNumber() + "\n");
}
}
}
});
controlPanel.add(createBallButton);
controlPanel.add(printSelectedBallButton);
JScrollPane jsp = new JScrollPane(jtf);
controlPanel.add(jsp);
frame.add(drawPanel);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
}
class DrawPanel extends JPanel {
ArrayList<Ball> balls = new ArrayList<>();
public void addBall(Ball b) {
balls.add(b);
repaint();
}
public ArrayList<Ball> getBalls() {
return balls;
}
@Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Ball ball : balls) {
ball.draw(g2d);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
class Ball {
private Color color;
private int x, y;
private int radius;
private final int number;
private boolean selected;
Ball(int x, int y, int radius, int counter) {
this.x = x;
this.y = y;
this.radius = radius;
this.number = counter;
selected = false;
this.color = Color.RED;//default color of unselected ball
}
public void draw(Graphics2D g2d) {
Color prevColor = g2d.getColor();
g2d.drawString(number + "", x + radius, y + radius);//draw the number of ball
g2d.setColor(color);
g2d.fillOval(x, y, radius, radius);
g2d.setColor(prevColor);
}
public Rectangle2D getBounds() {
return new Rectangle2D.Double(x, y, radius, radius);
}
public void setSelected(boolean selected) {
this.selected = selected;
if (selected) {
color = Color.GREEN;
} else {
color = Color.RED;
}
}
boolean isSelected() {
return selected;
}
int getNumber() {
return number;
}
}