2013-02-16 22 views
-2

我是一名学生,因为我的项目中有一个留下了茬子,这只是我最后一个项目的实际情况而已,但我试图尽可能地对其进行划分。Java:选择已重新绘制的对象

我遇到的具体问题与创建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

的Java!= JavaScript的。这个代码是Java。不是JavaScript。 – 2013-02-16 15:36:55

+3

你的问题是什么?我们是否应该尝试运行这个程序,猜猜什么是不行的,并为您提供固定代码? – 2013-02-16 15:38:45

+0

很抱歉,想知道如何让它在屏幕上有多个球,并且能够选择它们,应该是这个在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

回答

2

具体的问题我已经是关系到创建一个Java应用程序 那显示带有按钮的框架,允许用户在屏幕上创建多个球,然后您可以选择每个球 通过点击它们。

我已经尝试添加小的修改,但与他们不工作我 删除它,以便它给你找到一个解决方案时更多的自由。

你从来不提什么是错的/你想实现......除了以上和标题内容:选择对象,已被粉刷

但是我看到给出代码的几个问题:

1)不要设置JFrame可见,直到所有组件都已经添加(或您将有问题,如不可见的内容)

2)不要叫setSizeJFrame 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.CENTERJFrame#add(Component c)要更换的旧/JPanel与另一个。

6),因为它代表使用JPanel像你这样,如果2个Ball S IN的重叠位置结束前Ball及其JPanel将覆盖底部Ball ......你需要一个透明的面板即JComponent#setOpaque(false)

7)当我做自定义绘画,我很少使用JComponent或其扩展名。我宁愿创建一个Object,它将充当虚拟表示我需要绘制/显示或任何(可能是个人喜好)。这些对象将在我的JPanelpaintComponent(..)中可视化,其将调用它们的draw(..)方法将JPanelGraphics对象传递给每个Ball,其将根据字段数据绘制自己。

下面是一个简单的例子我做了(在考虑以上):

所有绿色balls已选定即点击,而红色却没有。

enter image description here

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; 
    } 
} 
+0

非常感谢,对不起,不擅长解释自己,我下次再努力 – Andrew 2013-02-17 00:18:27