且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

单击JFrame中的按钮会将数据传递到JPanel

更新时间:2023-12-03 16:00:22

不包含Coordinates和Number类,因此我不得不对代码进行一些修改.

The Coordinates and Number classes weren't included, so I had to modify the code somewhat.

这是我创建的GUI.

我做的第一件事是为GUI创建一个模型类.通过创建模型类,我可以使显示字符串和图形坐标可用于视图和控制器类.这是模型/视图/控制器的简单示例模式.

The first thing I did was create a model class for the GUI. By creating a model class, I could make the display string and the drawing coordinate available to the view and the controller classes. This is a simple example of the model / view / controller pattern.

package com.ggl.drawing;

import java.awt.Point;

public class GUIModel {

    private String displayString;

    private Point coordinate;

    public GUIModel(String displayString) {
        this.displayString = displayString;
    }

    public Point getCoordinate() {
        return coordinate;
    }

    public void setCoordinate(int x, int y) {
        this.coordinate = new Point(x, y);
    }

    public void setCoordinate(Point coordinate) {
        this.coordinate = coordinate;
    }

    public void setDisplayString(String displayString) {
        this.displayString = displayString;
    }

    public String getDisplayString() {
        return displayString;
    }

}

现在我们有了一个模型,让我们看一下DrawFrame类.

Now that we have a model, lets look at the DrawFrame class.

package com.ggl.drawing;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DrawFrame implements Runnable {
    private final int WIDTH = 500;
    private final int HEIGHT = 300;

    private JFrame frame;

    private GUIModel model;

    public DrawFrame() {
        this.model = new GUIModel("A");
    }

    @Override
    public void run() {
        frame = new JFrame("Draw Letters");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createSelectionPanel(), BorderLayout.WEST);
        frame.add(new DrawPanel(WIDTH, HEIGHT, model), BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);
    }

    private JPanel createSelectionPanel() {
        JPanel numberPanel = new JPanel();
        ButtonListener listener = new ButtonListener();

        JButton number1 = new JButton("A");
        number1.addActionListener(listener);

        JButton number2 = new JButton("B");
        number2.addActionListener(listener);

        numberPanel.setLayout(new GridLayout(0, 2));
        numberPanel.add(number1);
        numberPanel.add(number2);

        return numberPanel;
    }

    private class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            model.setDisplayString(event.getActionCommand());
        }
    }

    // creates a drawing frame
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DrawFrame());
    }
}

我在Event Dispatch线程上启动了Java Swing应用程序,并调用了SwingUtilities invokeLater方法.

I started the Java Swing application on the Event Dispatch thread with the call to the SwingUtilities invokeLater method.

我将JFrame构造与2个JPanels构造分开.我使用了JFrame,而不是扩展JFrame.唯一应该扩展任何Java类的情况是,如果您想覆盖一个或多个类方法.

I separated the JFrame construction from the 2 JPanels construction. I used a JFrame, rather than extend a JFrame. The only time you should extend any Java class is if you want to override one or more of the class methods.

我为两个JButton使用了相同的ButtonListener.我在猜测您要什么,但是我画了一个"A"或"B",具体取决于您左键单击的按钮.

I used the same ButtonListener for both JButtons. I'm guessing what you want, but I drew either an "A" or a "B", depending on which button you left clicked.

让我们看一下DrawPanel类.

Let's look at the DrawPanel class.

package com.ggl.drawing;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JPanel;

public class DrawPanel extends JPanel {

    private static final long serialVersionUID = 3443814601865936618L;

    private GUIModel model;

    public DrawPanel(int width, int height, GUIModel model) {
        this.setPreferredSize(new Dimension(width, height));
        this.model = model;
        // add mouse listeners
        MouseHandler mouseHandler = new MouseHandler();
        this.addMouseListener(mouseHandler);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        if (model.getCoordinate() != null) {
            Point p = model.getCoordinate();
            Font font = g.getFont().deriveFont(48F);
            g.setFont(font);
            g.drawString(model.getDisplayString(), p.x, p.y);
        }
    }

    // class to handle all mouse events
    private class MouseHandler extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent event) {
            model.setCoordinate(event.getPoint());
        }

        @Override
        public void mouseReleased(MouseEvent event) {
            DrawPanel.this.repaint();
        }

    }
}

我在此类中所做的主要更改是使用paintComponent方法,而不是paint方法. paintComponent方法是要重写的正确方法.

The major change I made in this class was to use the paintComponent method, rather than the paint method. The paintComponent method is the correct method to override.

我在DrawPanel构造函数中设置绘图面板的大小.***让Swing弄清楚JFrame的大小.这就是DrawFrame run方法中的pack方法.

I set the size of the drawing panel in the DrawPanel constructor. It's much better to let Swing figure out the size of the JFrame. That's what the pack method in the DrawFrame run method does.

我增加了字体大小,以便您可以更好地看到绘制的字母.

I increased the font size so you can see the drawn letter better.

我删除了鼠标运动侦听器代码,因为它不是必需的.

I removed the mouse motion listener code, as it wasn't needed.

我希望这对您有所帮助.

I hope this was helpful to you.