我有一个带有两个按钮的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();
}
}
}
我不确定这是否可行。如果我的逻辑错了,那就很抱歉。请为我提供另一种解决此问题的方法。感谢任何指导。
谢谢!
答案 0 :(得分:2)
没有包括Coordinates和Number类,所以我不得不稍微修改一下代码。
这是我创建的GUI。
我做的第一件事就是为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中显示的文本发生变化。如果是这样,那么您的代码看起来方式对于作业而言过于复杂。建议包括:
setText(String text)
,允许外部类更改它显示的文本。text
,并调用repaint()
。paintComponent
而不是paint
方法,并在覆盖范围内调用超级方法。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中显示文本,因为它更容易使文本居中。