具体的问题我已经是关系到创建一个Java应用程序 那显示带有按钮的框架,允许用户在屏幕上创建多个球,然后您可以选择每个球 通过点击它们。
我已经尝试添加小的修改,但与他们不工作我 删除它,以便它给你找到一个解决方案时更多的自由。
你从来不提什么是错的/你想实现......除了以上和标题内容:选择对象,已被粉刷
但是我看到给出代码的几个问题:
1)不要设置JFrame
可见,直到所有组件都已经添加(或您将有问题,如不可见的内容)
2)不要叫setSize
上JFrame
RA其替代getPreferredSize()
的JPanel
并且返回Dimension
s,其适合Graphics
对象上的图和/或使用适当的LayoutManager
。比我们可以拨打pack()
而不是setSize(...)
JFrame
。
3)Swing组件应在事件调度线程通过SwingUtilities.invokeLater(Runnable r)
块创建和操纵。 Read Concurrency in Swing了解更多。
4)当您使用validate()
时,应该紧接着调用repaint()
来反映所做的更改。
5)您也使用默认JFrame
布局BorderLayout
向其中添加面板,而且比球(默认情况下BorderLayout
使用按钮收听)将因此在每次调用添加到其BorderLayout.CENTER
到JFrame#add(Component c)
要更换的旧球/JPanel
与另一个。
6),因为它代表使用JPanel
像你这样,如果2个Ball
S IN的重叠位置结束前Ball
及其JPanel
将覆盖底部Ball
......你需要一个透明的面板即JComponent#setOpaque(false)
。
7)当我做自定义绘画,我很少使用JComponent
或其扩展名。我宁愿创建一个Object
,它将充当虚拟表示我需要绘制/显示或任何(可能是个人喜好)。这些对象将在我的JPanel
paintComponent(..)
中可视化,其将调用它们的draw(..)
方法将JPanel
的Graphics
对象传递给每个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;
}
}
的Java!= JavaScript的。这个代码是Java。不是JavaScript。 – 2013-02-16 15:36:55
你的问题是什么?我们是否应该尝试运行这个程序,猜猜什么是不行的,并为您提供固定代码? – 2013-02-16 15:38:45
很抱歉,想知道如何让它在屏幕上有多个球,并且能够选择它们,应该是这个在class ButtonClickHandler中实现ActionListener public void actionPerformed(ActionEvent e){0 {0} {0} {0} frame.add(new Ball (1)); frame.validate(); } }' – Andrew 2013-02-16 16:49:59