使用监听器 class 来处理所有监听
Using a listener class to handle all listening
我完成了我的 Java 家庭作业,但它们都被合并到一个主要的 class 中(有几个私人 classes)。我试图通过使用单独的 classes 来处理事情来使我的代码更优雅。我无法让听众与现有面板互动。
我正在查看的主要部分在 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**
}
}
这里的一些想法:
- 目前您有 多个 个监听器实例 class。那可能不是你想要的。
- 与此相关:您的代码表明您的监听器 class 应该在某个面板上绘制。如果是这样...那个监听器不知何故需要 access 到那个面板。
一种方法:将构造函数更改为
private final Panel drawingBoard;
public Listener(Panel drawingBoard) {
this.drawingBoard = drawingBoard;
)
然后您的 actionPerformed() 方法可以借鉴。
要了解的核心内容:您必须(在您的脑海中)创建一个关于您拥有哪些组件的清晰模型;以及他们如何相互依赖。因为这会推动您的实施;例如,关于创建不同对象的顺序。以我的示例为例,您需要首先 创建一个 Panel 对象;这样您就可以然后为该面板创建一个侦听器。
这是我完成的项目的代码。我想我让它变得更干净了,只调用了 "listener" 和 "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));
}
}
}
Button.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;
}
}
我完成了我的 Java 家庭作业,但它们都被合并到一个主要的 class 中(有几个私人 classes)。我试图通过使用单独的 classes 来处理事情来使我的代码更优雅。我无法让听众与现有面板互动。
我正在查看的主要部分在 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**
}
}
这里的一些想法:
- 目前您有 多个 个监听器实例 class。那可能不是你想要的。
- 与此相关:您的代码表明您的监听器 class 应该在某个面板上绘制。如果是这样...那个监听器不知何故需要 access 到那个面板。
一种方法:将构造函数更改为
private final Panel drawingBoard;
public Listener(Panel drawingBoard) {
this.drawingBoard = drawingBoard;
)
然后您的 actionPerformed() 方法可以借鉴。
要了解的核心内容:您必须(在您的脑海中)创建一个关于您拥有哪些组件的清晰模型;以及他们如何相互依赖。因为这会推动您的实施;例如,关于创建不同对象的顺序。以我的示例为例,您需要首先 创建一个 Panel 对象;这样您就可以然后为该面板创建一个侦听器。
这是我完成的项目的代码。我想我让它变得更干净了,只调用了 "listener" 和 "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));
}
}
}
Button.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;
}
}