作为一个更大项目的一部分,我正在尝试创建一个基本 UI,允许用户单击 JButton 以选择所需的颜色,然后允许该用户单击另一个 JButton 以指定要显示的形状,根据填充之前选择的颜色。我明白我必须利用动作事件。
请注意我引用了这个类似的问题:
到目前为止,我的代码是:
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class GUI extends JFrame implements ActionListener, WindowListener
{
private final JButton circleButton, rectangleButton, redButton;
private final JButton greenButton, blueButton, exitButton;
private final JTextArea textArea;
private final JLabel label1;
private final JPanel colorPane;
private String shapeColor = "black";
private String actualShape = "rectangle";
private static final int ROWS = 2, COLS = 3;
public GUI (String title)
{
super(title);
//setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
colorPane = new JPanel();
label1 = new JLabel("current date here");
label1.setVerticalAlignment(SwingConstants.BOTTOM);
label1.setHorizontalAlignment(SwingConstants.LEFT);
label1.setPreferredSize(new Dimension(200,0));
getContentPane().add(label1, BorderLayout.WEST);
colorPane.setLayout(new GridLayout(ROWS,COLS));
getContentPane().add(colorPane, BorderLayout.CENTER);
redButton = makeButton("Red");
colorPane.add(redButton);
greenButton = makeButton("Green");
colorPane.add(greenButton);
blueButton = makeButton("Blue");
colorPane.add(blueButton);
rectangleButton = makeButton("Rectangle");
colorPane.add(rectangleButton);
circleButton = makeButton("Circle");
colorPane.add(circleButton);
exitButton = makeButton("Exit");
colorPane.add(exitButton);
textArea = new JTextArea(0,20);
getContentPane().add(textArea, BorderLayout.EAST);
pack();
}
public void paint(Graphics g, String color)
{
if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("rectangle"))
{
g.setColor(Color.BLUE);
g.fillRect(50, 90, 100, 50);
}
else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("circle"))
{
g.setColor(Color.GREEN);
g.fillOval(50, 180, 55, 55);
}
else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("rectangle"))
{
g.setColor(Color.RED);
g.fillRect(50, 90, 100, 50);
}
else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("rectangle"))
{
g.setColor(Color.GREEN);
g.fillRect(50,90,100,50);
}
else if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("circle"))
{
g.setColor(Color.BLUE);
g.fillOval(50, 180, 55, 55);
}
else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("circle"))
{
g.setColor(Color.RED);
g.fillOval(50, 180, 55, 55);
}
}
//method designed to create new JButtons while avoiding code duplication
private JButton makeButton(String text)
{
JButton b = new JButton(text);
b.setHorizontalAlignment(SwingConstants.LEFT);
b.addActionListener(this);
b.setPreferredSize(new Dimension(125,55));
return b;
}
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println( ( (JButton)e.getSource() ).getText() + " button pressed ");
if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Red")) )
{
setShapeColor("Red");
System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
//paint(this.getGraphics());
}
else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Blue")) )
{
setShapeColor("Blue");
System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
//paint(this.getGraphics());
}
else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Green")) )
{
setShapeColor("Green");
System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
//paint(this.getGraphics());
}
if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Rectangle")) )
{
setActualShape("rectangle");
System.out.println("selected shape is: " + actualShape + " selected color is: " + shapeColor);
paint(this.getGraphics(), shapeColor);
}
else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Circle")) )
{
setActualShape("circle");
System.out.println("selected shape is: " + actualShape + " selected color is: " + shapeColor);
paint(this.getGraphics(), shapeColor);
}
}
public String getShapeColor() {
return shapeColor;
}
public void setShapeColor(String shapeColor) {
this.shapeColor = shapeColor;
}
public String getActualShape() {
return actualShape;
}
public void setActualShape(String actualShape) {
this.actualShape = actualShape;
}
public static void main(String[] args)
{
new GUI("My Gui").setVisible(true);
}
}
到目前为止,我已经实现了一个输出,它显示了所选颜色以及要以所选颜色呈现的所选形状。
此外,我已经成功地输出了一个形状,其位置是硬编码的,但其类型(圆形或正方形)和颜色(红色、蓝色或绿色)在用户点击后正确输出。
我正在努力的最后一个阶段是形状输出的实现,以便用户的点击序列确定形状输出到屏幕的位置和尺寸。
目标是实现此处演示的功能:
我比较确定正确的解决方案类似于以下代码:
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
* Note: Normally the ButtonPanel and DrawingArea would not be static
classes.
* This was done for the convenience of posting the code in one class and
to
* highlight the differences between the two approaches. All the
differences
* are found in the DrawingArea class.
*/
public class DrawOnComponent
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
DrawingArea drawingArea = new DrawingArea();
ButtonPanel buttonPanel = new ButtonPanel( drawingArea );
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Draw On Component");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add(drawingArea);
frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
frame.setSize(400, 400);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
static class ButtonPanel extends JPanel implements ActionListener
{
private DrawingArea drawingArea;
public ButtonPanel(DrawingArea drawingArea)
{
this.drawingArea = drawingArea;
add( createButton(" ", Color.BLACK) );
add( createButton(" ", Color.RED) );
add( createButton(" ", Color.GREEN) );
add( createButton(" ", Color.BLUE) );
add( createButton(" ", Color.ORANGE) );
add( createButton(" ", Color.YELLOW) );
add( createButton("Clear Drawing", null) );
}
private JButton createButton(String text, Color background)
{
JButton button = new JButton( text );
button.setBackground( background );
button.addActionListener( this );
return button;
}
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
if ("Clear Drawing".equals(e.getActionCommand()))
drawingArea.clear();
else
drawingArea.setForeground( button.getBackground() );
}
}
static class DrawingArea extends JPanel
{
private final static int AREA_SIZE = 400;
private ArrayList<ColoredRectangle> coloredRectangles = new ArrayList<ColoredRectangle>();
private Rectangle shape;
public DrawingArea()
{
setBackground(Color.WHITE);
MyMouseListener ml = new MyMouseListener();
addMouseListener(ml);
addMouseMotionListener(ml);
}
@Override
public Dimension getPreferredSize()
{
return isPreferredSizeSet() ?
super.getPreferredSize() : new Dimension(AREA_SIZE, AREA_SIZE);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
// Custom code to paint all the Rectangles from the List
Color foreground = g.getColor();
g.setColor( Color.BLACK );
g.drawString("Add a rectangle by doing mouse press, drag and release!", 40, 15);
for (DrawingArea.ColoredRectangle cr : coloredRectangles)
{
g.setColor( cr.getForeground() );
Rectangle r = cr.getRectangle();
g.drawRect(r.x, r.y, r.width, r.height);
}
// Paint the Rectangle as the mouse is being dragged
if (shape != null)
{
Graphics2D g2d = (Graphics2D)g;
g2d.setColor( foreground );
g2d.draw( shape );
}
}
public void addRectangle(Rectangle rectangle, Color color)
{
// Add the Rectangle to the List so it can be repainted
ColoredRectangle cr = new ColoredRectangle(color, rectangle);
coloredRectangles.add( cr );
repaint();
}
public void clear()
{
coloredRectangles.clear();
repaint();
}
class MyMouseListener extends MouseInputAdapter
{
private Point startPoint;
public void mousePressed(MouseEvent e)
{
startPoint = e.getPoint();
shape = new Rectangle();
}
public void mouseDragged(MouseEvent e)
{
int x = Math.min(startPoint.x, e.getX());
int y = Math.min(startPoint.y, e.getY());
int width = Math.abs(startPoint.x - e.getX());
int height = Math.abs(startPoint.y - e.getY());
shape.setBounds(x, y, width, height);
repaint();
}
public void mouseReleased(MouseEvent e)
{
if (shape.width != 0 || shape.height != 0)
{
addRectangle(shape, e.getComponent().getForeground());
}
shape = null;
}
}
class ColoredRectangle
{
private Color foreground;
private Rectangle rectangle;
public ColoredRectangle(Color foreground, Rectangle rectangle)
{
this.foreground = foreground;
this.rectangle = rectangle;
}
public Color getForeground()
{
return foreground;
}
public void setForeground(Color foreground)
{
this.foreground = foreground;
}
public Rectangle getRectangle()
{
return rectangle;
}
}
}
}
我知道我必须重写“paint”方法,并且作为硬编码练习,我在代码中包含了以下内容:
public void paint(Graphics g, String color)
{
if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("rectangle"))
{
g.setColor(Color.BLUE);
g.fillRect(50, 90, 100, 50);
}
else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("circle"))
{
g.setColor(Color.GREEN);
g.fillOval(50, 180, 55, 55);
}
else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("rectangle"))
{
g.setColor(Color.RED);
g.fillRect(50, 90, 100, 50);
}
else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("rectangle"))
{
g.setColor(Color.GREEN);
g.fillRect(50,90,100,50);
}
else if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("circle"))
{
g.setColor(Color.BLUE);
g.fillOval(50, 180, 55, 55);
}
else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("circle"))
{
g.setColor(Color.RED);
g.fillOval(50, 180, 55, 55);
}
}
}
我不确定如何记录用户按钮单击的坐标,然后将这些坐标传递给所需形状的构造函数。