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

时间:2015-11-16 21:53:08

标签: java swing jframe jpanel jbutton

我有一个带有两个按钮的Jframe:' 1'和' 2'。点击按钮' 1'应该在JPanel中显示大写字母A.

我的JFrame代码:

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;

public class DrawFrame extends JFrame{
    private final int WIDTH = 500;
    private final int HEIGHT = 300;

    private JButton number1;
    private JButton number2;

    private JPanel numberPanel;
    private DrawPanel graphicsPanel;

    public DrawFrame()
    {
        createSelectionPanel();
        createGraphicsPanel();

        this.setSize(WIDTH, HEIGHT);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    private void createSelectionPanel()
    {
        numberPanel = new JPanel();

        number1 = new JButton("1");
        number2 = new JButton("2");   

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

        this.add(numberPanel, BorderLayout.WEST);
    }

    private void createGraphicsPanel()
    {
        //instantiate drawing panel
        graphicsPanel = new DrawPanel();
        //add drawing panel to right
        add(graphicsPanel);
    }

    private class Number1ButtonListener implements ActionListener {
        public void actionPerformed (ActionEvent event) {
            Number number = new Number();
            number.setNumber('A');
        }
    }

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

我的JPanel代码

import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class DrawPanel extends JPanel{
    public Coordinates current;

    public DrawPanel(){
        //nothing drawn initially
        current = null;

        //set white background for drawing panel
        setBackground(Color.WHITE);

        //add mouse listeners
        MouseHandler mouseHandler = new MouseHandler();
        this.addMouseListener(mouseHandler);
        this.addMouseMotionListener(mouseHandler);
    }

    public void paint(Graphics g){
        super.paint(g);

        if(current!=null){
  

我想替换" A"与number.getNumber()

            g.drawString("A", current.getX(), current.getY());
        }
    }

    //class to handle all mouse events
    private class MouseHandler extends MouseAdapter implements MouseMotionListener
    {
        public void mousePressed(MouseEvent event)
        {
           current = new Coordinates(event.getX(), event.getY());
        }

        public void mouseReleased(MouseEvent event)
        {
            repaint();
        }
    }
}

我不确定这是否可行。如果我的逻辑错了,那就很抱歉。请为我提供另一种解决此问题的方法。感谢任何指导。

谢谢!

2 个答案:

答案 0 :(得分:2)

没有包括Coordinates和Number类,所以我不得不稍微修改一下代码。

这是我创建的GUI。

Draw Letter

我做的第一件事就是为GUI创建一个模型类。通过创建模型类,我可以使显示字符串和绘图坐标可用于视图和控制器类。这是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类。

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方法。

我将JFrame结构与2个JPanels结构分开。我使用了JFrame,而不是扩展JFrame。您应该扩展任何Java类的唯一时间是您要覆盖一个或多个类方法。

我为两个JButton使用了相同的ButtonListener。我猜你想要什么,但我画了一个“A”或“B”,这取决于你点击的按钮。

让我们看一下DrawPanel类。

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方法是要覆盖的正确方法。

我在DrawPanel构造函数中设置绘图面板的大小。让Swing计算出JFrame的大小要好得多。这就是DrawFrame运行方法中的pack方法。

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

我删除了鼠标移动侦听器代码,因为它不需要。

我希望这对你有所帮助。

答案 1 :(得分:1)

好的,到目前为止我所知道的是,如果按下按钮,您希望JPanel中显示的文本发生变化。如果是这样,那么您的代码看起来方式对于作业而言过于复杂。建议包括:

  • 为DrawingPanel提供一个setter方法,比如setText(String text),允许外部类更改它显示的文本。
  • 在该方法中,设置一个DrawingPanel字段,称为text,并调用repaint()
  • 覆盖DrawingPanel paintComponent而不是paint方法,并在覆盖范围内调用超级方法。
  • 在paintComponent方法中,如果该字段不为null,则调用drawString以绘制文本字段所持有的String。
  • 给你的按钮ActionListeners或AbstractActions调用DrawingPanel的setText(...)方法,设置要显示的文本。

例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class DrawAorB extends JPanel {
    private DrawingPanel drawingPanel = new DrawingPanel(); 

    public DrawAorB() {
        JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 5));
        btnPanel.add(new JButton(new ButtonAction("A")));
        btnPanel.add(new JButton(new ButtonAction("B")));

        setLayout(new BorderLayout());
        add(drawingPanel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private class ButtonAction extends AbstractAction {
        public ButtonAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String text = e.getActionCommand();
            drawingPanel.setText(text);
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("DrawAorB");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new DrawAorB());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

class DrawingPanel extends JPanel {
    private static final int PREF_W = 200;
    private static final int PREF_H = PREF_W;
    private String text = null;

    public void setText(String text) {
        this.text = text;  // set the JPanel's text
        repaint();  // and draw it
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (text != null) {
            int x = getWidth() / 2;
            int y = getHeight() / 2;
            // use FontMetrics if you want to center text better
            g.drawString(text, x, y);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }
}

更简单,更简单,也可能更好的方法是在JLabel中显示文本,因为它更容易使文本居中。