2016-12-09 151 views
0

我完成了我的Java Homework,但它全部都是一个主类(有几个私有类)。我试图通过让不同的类来处理事情来让代码更加优雅。听众与现有面板交互时遇到问题。使用一个监听器类来处理所有的监听

我正在看的主要部分是在Listener.java中。鼠标点击和动作监听器。我能够获得被点击的按钮的名称来触发监听器,这很有帮助,但是我无法使其与添加到面板的“DrawBoard”面板交互。

我想知道什么来解决这个互动的最佳方式是:

Window.java:

import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class Window extends JFrame { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -8255319694373975038L; 

    public static void main(String[] args){ 

     new Window(); 
    } 


    public Window(){ 


     // Adds the custom panel 
     Panel Panel = new Panel(); 
     this.add(Panel); 


     // Basic Window Features 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setSize(800,800); 
     this.setLocationRelativeTo(null); 
     this.setVisible(true); 
    } 


} 

Panel.java:

public class Panel extends JPanel{ 

    public Panel(){ 
     Button testButton = new Button("Test"); 
     DrawBoard drawBoard = new DrawBoard(); 
     Listener listener = new Listener(); 



     this.add(testButton); 
     this.add(drawBoard); 


    } 
} 

Button.java

import java.awt.Dimension; 

import javax.swing.JButton; 

public class Button extends JButton{ 


    public Button(String name) { 
     this.setText(name); 
     this.setName((String) name); 
     buttonSettings(); 
    } 

    private void buttonSettings(){ 
     Listener listener = new Listener(); 
     this.addActionListener(listener); 

     int width = 200; 
     int height = 50; 
     Dimension dim = new Dimension(width,height); 
     this.setPreferredSize(dim); 
    } 

} 

DrawBoard。 java的

import java.awt.Color; 
import java.awt.Dimension; 

import javax.swing.JPanel; 

public class DrawBoard extends JPanel{ 

    public DrawBoard(){ 
     DrawBoardSettings(); 
    } 

    private void DrawBoardSettings(){ 
     int width = 600; 
     int height = 600; 
     Dimension dim = new Dimension(width,height); 
     this.setPreferredSize(dim); 
     this.setBackground(Color.WHITE); 
    } 
} 

Listener.java

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.JComponent; 

public class Listener implements ActionListener, MouseListener { 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     **// Draw a dot at the mouse location of the DrawBoard JPanel that was added by the Panel JPanel that was added by the Window JFrame** 

    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     String name = ((JComponent) e.getSource()).getName(); 
     **// Draw a rectangle on the DrawBoard JPanel that was added by the Panel JPanel that was added by the Window JFrame** 
    } 

} 

回答

0

的几点思考在这里:

  • 目前你有Listener类的几个实例。这可能不是你想要的。
  • 与此相关:你的代码表明你的Listener类应该在某个面板上绘制。如果是这样的话...听众需要访问该面板。

的一种方式到那里:你改变你的构造函数

private final Panel drawingBoard; 
public Listener(Panel drawingBoard) { 
    this.drawingBoard = drawingBoard; 
) 

,然后你的actionPerformed()方法有一些借鉴。要了解的核心内容是:你必须在你的脑海中创建一个清晰的模型,了解你拥有哪些组件;以及他们如何相互依赖。因为这会推动你的实施;例如关于您必须创建不同对象的顺序。以我的例子,你需要第一个创建一个Panel对象;所以你可以然后为该面板创建一个监听器。

+0

谢谢。我只是需要确保我只启动一次类,然后有其他类调用它是第一个实例。 –

0

这是我完成的项目的代码。我想我做到了更清洁,只有所谓的 “监听器” 和 “drawBoard” 一次,这澄清了我的问题:

Window.java:

import javax.swing.JFrame; 


public class Window extends JFrame { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -8255319694373975038L; 

    // initiates the program 
    public static void main(String[] args){ 

     new Window(); 
    } 


    public Window(){ 


     // Adds the custom panel 
     Panel Panel = new Panel(); 
     this.add(Panel); 


     // Basic Window Features 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setSize(800,800); 
     this.setLocationRelativeTo(null); 
     this.setVisible(true); 
    } 


} 

Panel.java:

import java.awt.FlowLayout; 
import java.util.ArrayList; 

import javax.swing.JPanel; 

    public class Panel extends JPanel{ 

     /** 
     * 
     */ 
     private static final long serialVersionUID = 5509155261502497671L; 



     public Panel(){ 
      // This is the area where stuff will be drawn 
      DrawBoard drawBoard = new DrawBoard(); 


      // This is the only instance of listener. Buttons now call this variable 
      Listener listener = new Listener(drawBoard); 


      // Invisible Overlay allows me to get mouse listener coordinates for drawing 
      JPanel overlay = new JPanel(); 

      //gets rid of the padding on the invisible overlay layer; 
      FlowLayout layout = (FlowLayout)overlay.getLayout(); 
      layout.setVgap(0); 
      layout.setHgap(0); 

      // The mouse listener is added to the overlay layer rather than the panel to ensure that X,Y coords match the drawboard panel underneath 
      // I could not add the listener to the drawboard panel because the listener requires the drawboard panel to perform. 
      overlay.addMouseListener(listener); 
      overlay.addMouseMotionListener(listener); 
      overlay.add(drawBoard); 


      // Buttons that will appear on the top of the panel 
      ArrayList<Button> TopButtons = new ArrayList<Button>(); 
      TopButtons.add(new Button("Blue", listener)); 
      TopButtons.add(new Button("Green", listener)); 
      TopButtons.add(new Button("Red", listener)); 
      TopButtons.add(new Button("Black", listener)); 


      // Buttons that will appear on the bottom of the pannel 
      ArrayList<Button> BotButtons = new ArrayList<Button>(); 
      BotButtons.add(new Button("Small", listener)); 
      BotButtons.add(new Button("Medium", listener)); 
      BotButtons.add(new Button("Large", listener)); 
      BotButtons.add(new Button("Clear", listener)); 


      // Using for loops to clean up code a bit. 
      for (int i = 0; i < TopButtons.size(); i++){ 
       this.add(TopButtons.get(i)); 
      } 

      // add the overlay rather than the drawboard, to ensure that mouse functions work 
      this.add(overlay); 

      for (int i = 0; i < BotButtons.size(); i++){ 
       this.add(BotButtons.get(i)); 
      } 
     } 
    } 

按钮。java的

import java.awt.Dimension; 
import javax.swing.JButton; 

public class Button extends JButton{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -819700115106662958L; 

    private final Listener listener; 
    public Button(String name, Listener listener) { 
     this.listener = listener; 
     this.setText(name); 
     this.setName((String) name); 
     buttonSettings(); 
    } 

    private void buttonSettings(){ 
     this.addActionListener(listener); 
     int width = 150; 
     int height = 50; 
     Dimension dim = new Dimension(width,height); 
     this.setPreferredSize(dim); 
    } 

} 

DrawBoard.java:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.util.ArrayList; 
import javax.swing.JPanel; 

public class DrawBoard extends JPanel{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1368365222404381200L; 


    // ArrayList will store all points drawn on the canvas 
    public ArrayList<Point> points = new ArrayList<Point>(); 

    // Constructor initiates the settings for the board 
    public DrawBoard(){ 
     DrawBoardSettings(); 

    } 

    // Painting of the points happens here 
    @Override 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     // draws a point for every point in the "points" array. 
     for (int i = 0; i < points.size(); i++){ 
      Point thisPoint = points.get(i); 
      g.setColor(thisPoint.color); 
      g.fillOval(thisPoint.x,thisPoint.y,thisPoint.size,thisPoint.size); 
     } 

    } 

    private void DrawBoardSettings(){ 
     // Sets the preferred window size 
     int width = 700; 
     int height = 600; 
     Dimension dim = new Dimension(width,height); 
     this.setPreferredSize(dim); 

     // background color and visibility 
     this.setBackground(Color.WHITE); 
     this.setVisible(true); 
     this.setOpaque(true); 
    } 
} 

Listener.java:

import java.awt.Color; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import javax.swing.JComponent; 

public class Listener implements ActionListener, MouseListener, MouseMotionListener { 

    private final DrawBoard drawBoard; 

    //sets default color and size 
    private Color color; 
    private int size; 




    public Listener(DrawBoard drawBoard) { 
     this.drawBoard = drawBoard; 

     this.color = Color.BLACK; 
     this.size = 10; 
    } 


    // Contains settings for creating a new point 
    private void drawPoint(MouseEvent e){ 
     Point point = new Point(e.getX(), e.getY(), this.color, this.size); 
     drawBoard.points.add(point); 
     drawBoard.repaint(); 
    } 


    // Contains settings for all of the buttons 
    private void setButton(String name){ 
     // Colors 
     if (name == "Blue"){ 
      this.color = Color.BLUE; 
     } 
     if (name == "Red"){ 
      this.color = Color.RED; 
     } 
     if (name == "Green"){ 
      this.color = Color.GREEN; 
     } 
     if (name == "Black"){ 
      this.color = Color.BLACK; 
     } 

     // Sizes 
     if (name == "Large"){ 
      this.size = 15; 
     } 
     if (name == "Medium"){ 
      this.size = 10; 
     } 
     if (name == "Small"){ 
      this.size = 5; 
     } 


     // Clear 
     if (name == "Clear"){ 
      drawBoard.points.clear(); 
      drawBoard.repaint(); 
     } 

    } 




    // Draws a point when the mouse is pressed down 
    @Override 
    public void mousePressed(MouseEvent e) { 
     drawPoint(e); 

    } 

    // Draws a point when the mouse is dragged (at every location it is dragged at) 
    @Override 
    public void mouseDragged(MouseEvent e) { 
     drawPoint(e); 
    } 

    // Changes the settings of buttons 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     String name = ((JComponent) e.getSource()).getName(); 
     setButton(name); 


    } 



    //Unused Listeners 
    @Override 
    public void mouseClicked(MouseEvent e) { 

    } 
    @Override 
    public void mouseReleased(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

} 

Point.java

import java.awt.Color; 

public class Point { 

    protected int x, y, size; 
    protected Color color; 

    public Point(int x, int y, Color color, int size){ 

     this.x = x; 
     this.y = y; 
     this.color = color; 
     this.size = size; 
    } 

}