Java n(){ 返回e->{ 开关(((JToggleButton)e.getSource()).getText()){ 案例“圆圈”: 形状=形状。圆; 打破 案例“矩形”: shape=shape.RECTANGLE; 打破 默认值:系统退出(0); } frame.repaint(); }; } 私有void setDefaults(){ colorGroup.getElements().nextElement().setSelected(true); color=colors.get(colorGroup.getElements().nextElement().getText()); shapeGroup.getElements().nextElement().setSelected(true); shape=shape.RECTANGLE; } 公共静态void main(字符串[]args){ 调用器(()->new GUI().createAndShowGUI(“我的GUI”); } 类Draw扩展了JPanel{ 私有最终点[]点;//用于保存单击点的数组 私有int mouseClicks=0; 私有静态最终整数点_SIZE=2; 画(){ setLayout(新的BorderLayout()); 挫折地面(颜色:白色); setPreferredSize(新尺寸(200200)); JLabel help=新建JLabel(“单击2点绘制”); help.setHorizontalAlignment(SwingConstants.CENTER); 添加(帮助,BorderLayout.PAGE_START); JLabel timeLabel=新的JLabel(“此处的当前时间”); 时间标签设置水平对齐(SwingConstants.左); 添加(timeLabel,BorderLayout.PAGE_END); 点=新点[2]; addMouseListener(新的MouseAdapter(){ @凌驾 公共无效mouseClicked(MouseEvent e){ addPoint(e.getX(),+e.getY()); } }); } @凌驾 公共组件(图形g){ 超级组件(g); g、 设置颜色(颜色); 用于(点:点) 如果(点!=null){ g、 drawOval(点x、点y、点_尺寸、点_尺寸); } 拉伸形状((图2d)g); } 专用无效添加点(整数x,整数y){ 如果(鼠标点击==2){ mouseClicks=0; 点[1]=空; } 点[mouseClicks++]=新点(x,y); 重新油漆(); } 专用空心图纸形状(Graphics2D g2d){ 如果(点[0]==null | |点[1]==null)返回; if(shape==shape.RECTANGLE){ 绘图矩形(g2d); }否则{ 拉丝圈(g2d); } } 专用空心绘图矩形(Graphics2D g2D){ int minX=Math.min(点[0].x,点[1].x); int minY=Math.min(点[0].y,点[1].y); int maxX=Math.max(点[0].x,点[1].x); int maxY=Math.max(点[0].y,点[1].y); int width=maxX-minX; 整数高度=最大-最小; 矩形2D.Double矩形=新矩形2D.Double(最小值、最小值、宽度、高度); g2D.绘制(矩形); } 专用空心绘图圈(Graphics2D g2D){ int minX=Math.min(点[0].x,点[1].x); int minY=Math.min(点[0].y,点[1].y); int maxX=Math.max(点[0].x,点[1].x); int maxY=Math.max(点[0].y,点[1].y); 双dx=最大值-最小值; 双dy=最大-最小; 双半径=数学sqrt(dx*dx+dy*dy)/2; 双中心x=minX+dx/2; 双中心=minY+dy/2; g2D.draw(新椭圆2D.Double(centerX-半径,centerY-半径,2*半径,2*半径)); } } 枚举形状{ 矩形、圆形 } }
我只会与Java n(){ 返回e->{ 开关(((JToggleButton)e.getSource()).getText()){ 案例“圆圈”: 形状=形状。圆; 打破 案例“矩形”: shape=shape.RECTANGLE; 打破 默认值:系统退出(0); } frame.repaint(); }; } 私有void setDefaults(){ colorGroup.getElements().nextElement().setSelected(true); color=colors.get(colorGroup.getElements().nextElement().getText()); shapeGroup.getElements().nextElement().setSelected(true); shape=shape.RECTANGLE; } 公共静态void main(字符串[]args){ 调用器(()->new GUI().createAndShowGUI(“我的GUI”); } 类Draw扩展了JPanel{ 私有最终点[]点;//用于保存单击点的数组 私有int mouseClicks=0; 私有静态最终整数点_SIZE=2; 画(){ setLayout(新的BorderLayout()); 挫折地面(颜色:白色); setPreferredSize(新尺寸(200200)); JLabel help=新建JLabel(“单击2点绘制”); help.setHorizontalAlignment(SwingConstants.CENTER); 添加(帮助,BorderLayout.PAGE_START); JLabel timeLabel=新的JLabel(“此处的当前时间”); 时间标签设置水平对齐(SwingConstants.左); 添加(timeLabel,BorderLayout.PAGE_END); 点=新点[2]; addMouseListener(新的MouseAdapter(){ @凌驾 公共无效mouseClicked(MouseEvent e){ addPoint(e.getX(),+e.getY()); } }); } @凌驾 公共组件(图形g){ 超级组件(g); g、 设置颜色(颜色); 用于(点:点) 如果(点!=null){ g、 drawOval(点x、点y、点_尺寸、点_尺寸); } 拉伸形状((图2d)g); } 专用无效添加点(整数x,整数y){ 如果(鼠标点击==2){ mouseClicks=0; 点[1]=空; } 点[mouseClicks++]=新点(x,y); 重新油漆(); } 专用空心图纸形状(Graphics2D g2d){ 如果(点[0]==null | |点[1]==null)返回; if(shape==shape.RECTANGLE){ 绘图矩形(g2d); }否则{ 拉丝圈(g2d); } } 专用空心绘图矩形(Graphics2D g2D){ int minX=Math.min(点[0].x,点[1].x); int minY=Math.min(点[0].y,点[1].y); int maxX=Math.max(点[0].x,点[1].x); int maxY=Math.max(点[0].y,点[1].y); int width=maxX-minX; 整数高度=最大-最小; 矩形2D.Double矩形=新矩形2D.Double(最小值、最小值、宽度、高度); g2D.绘制(矩形); } 专用空心绘图圈(Graphics2D g2D){ int minX=Math.min(点[0].x,点[1].x); int minY=Math.min(点[0].y,点[1].y); int maxX=Math.max(点[0].x,点[1].x); int maxY=Math.max(点[0].y,点[1].y); 双dx=最大值-最小值; 双dy=最大-最小; 双半径=数学sqrt(dx*dx+dy*dy)/2; 双中心x=minX+dx/2; 双中心=minY+dy/2; g2D.draw(新椭圆2D.Double(centerX-半径,centerY-半径,2*半径,2*半径)); } } 枚举形状{ 矩形、圆形 } },java,swing,user-interface,shapes,custom-painting,Java,Swing,User Interface,Shapes,Custom Painting,我只会与系统争论。退出(0)调用,我会使用frame.dispose()。@Frakcool感谢您的评论。为什么要使用frame.dispose()?我想这取决于你想要实现什么。总体来说,这更安全,System.exit(0)强制退出应用程序,frame.dispose()以更安全的方式退出应用程序。由于JFrame被告知在关闭时退出,一旦您处置它,它将自动终止。下面是关于这个问题的更多信息:特别是Sri Harsha的回答是我最喜欢的,Tomas Zato在接受的回答中的评论。我实际上是指“关
系统争论。退出(0)
调用,我会使用frame.dispose()
。@Frakcool感谢您的评论。为什么要使用frame.dispose()
?我想这取决于你想要实现什么。总体来说,这更安全,System.exit(0)
强制退出应用程序,frame.dispose()
以更安全的方式退出应用程序。由于JFrame
被告知在关闭时退出,一旦您处置它,它将自动终止。下面是关于这个问题的更多信息:特别是Sri Harsha的回答是我最喜欢的,Tomas Zato在接受的回答中的评论。我实际上是指“关闭所有窗口并终止应用程序”,包括线程。对于关闭所有窗口,我同意JFrame.dispose()
更合适。SO中的策略是帖子中的一个问题。有关更多问题,请发表一篇新帖子。@TrixietheCat我实际上向您展示了一个更好的选择,即使用枚举
进行形状设置,以及如何直接使用三元运算符设置颜色
,从而显著减少了代码。顺便说一句,您一次只能标记一个人,我没有收到您对c0der答案的回复通知,他收到通知,因为这是他的答案,所以您应该先标记我,在@
和我的名字之间没有空格。对于序列化,请将其包含在模型中。我没有在这里使用与您相同的GUI,因为您的问题历史显示您一直在询问如何执行程序的每个步骤。。。试着先做序列化部分,然后来问什么不起作用我并不是说你在烦我或其他人,那些帖子可能被否决的原因可能是:1)缺少一个合适的(比如我发布的那篇,很短,很完整,你可以在你的计算机上验证相同的结果),这就是我们要问你的。即使UI与您的“大”程序中的UI不同,您也可以从每个不同的小问题/答案中获取知识,将它们分离出来,这就是您学习的方式。分而治之。我了解到,我的第一个问题也很糟糕,而且被否决了
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;
}
}
}
}
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);
}
}
}
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.awt.event.*;
public class PaintExample {
private JFrame frame;
private JPanel pane;
private JPanel buttonsPane;
private CustomShape customShape;
private JButton squareButton;
private JButton circleButton;
private JButton purpleButton;
private JButton blueButton;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PaintExample().createAndShowGUI());
}
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName()); //Create a new JFrame with a title = this class name
pane = new JPanel();
buttonsPane = new JPanel();
buttonsPane.setLayout(new GridLayout(2, 2, 5, 5)); // We generate a grid layout of 2 x 2 for our JButtons
squareButton = new JButton("Square");
circleButton = new JButton("Circle");
purpleButton = new JButton("Purple");
blueButton = new JButton("Blue");
squareButton.addActionListener(listener);
circleButton.addActionListener(listener);
purpleButton.addActionListener(listener);
blueButton.addActionListener(listener);
buttonsPane.add(squareButton);
buttonsPane.add(circleButton);
buttonsPane.add(purpleButton);
buttonsPane.add(blueButton);
customShape = new CustomShape(); // We create an instance of our custom JPanel class
pane.setLayout(new BorderLayout());
pane.add(customShape);
pane.add(buttonsPane, BorderLayout.SOUTH);
frame.add(pane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
ActionListener listener = e -> { //Java 8+, for Java 7- add the actionPerformed method instead of the lambda expression
// We check which button was clicked and set the shape / color for our custom class
if (e.getSource().equals(squareButton)) {
customShape.setShape(ShapeToDraw.SQUARE);
} else if (e.getSource().equals(circleButton)) {
customShape.setShape(ShapeToDraw.CIRCLE);
} else if (e.getSource().equals(purpleButton)) {
customShape.setColor(Color.MAGENTA);
} else if (e.getSource().equals(blueButton)) {
customShape.setColor(Color.BLUE);
}
};
enum ShapeToDraw {
SQUARE, CIRCLE // You can define here other properties for each enum option
}
class CustomShape extends JPanel {
private Color color;
private ShapeToDraw shape;
public CustomShape() {
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
this.repaint(); // Everytime we set the color we ask the component to repaint itself
}
public ShapeToDraw getShape() {
return shape;
}
public void setShape(ShapeToDraw shape) {
this.shape = shape;
this.repaint(); // Everytime we set the shape we ask the component to repaint itself
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200); // We define the panel's size
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(color != null ? color : Color.BLACK); //If we haven't set the Color yet, we default it to black, otherwise we set the color to the one chosen by the user.
if (shape == ShapeToDraw.SQUARE) { //If the shape is a square, we draw a square
g2d.draw(new Rectangle2D.Double(50, 50, 100, 100)); // Change the coordinates that you get by user click using the MouseListener
} else if (shape == ShapeToDraw.CIRCLE) { // Or we draw a circle
g2d.draw(new Ellipse2D.Double(50, 50, 100, 100));
}
}
}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class GUI
{
private final ButtonGroup colorGroup; //group buttons
private final ButtonGroup shapeGroup; //so only one can be selected at any given time
private final Map<String, Color> colors; //map colors to it names.
private Color color; // color for painting
private Shape shape; //shape to paint
private JFrame frame;
private JPanel buttonsPane;
private JTextArea textArea;
private static final int ROWS = 2, COLS = 3;
private static final String[] BUTTONS_LABELS = {"Rectangle", "Circle", "Exit"};
public GUI()
{
shapeGroup = new ButtonGroup(); colorGroup = new ButtonGroup();
colors = new HashMap<>();
colors.put("Red", Color.RED); colors.put("Green", Color.GREEN); colors.put("Blue", Color.BLUE);
}
private void createAndShowGUI(String title) {
frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//use a GridLayout for the buttons pane
buttonsPane = new JPanel();
buttonsPane.setLayout(new GridLayout(ROWS, COLS));
frame.getContentPane().add(buttonsPane, BorderLayout.CENTER);//each BorderLayout position can hold ONE component
for(String colorName : colors.keySet()){
JToggleButton button = makeButton(colorName);
buttonsPane.add(button);
colorGroup.add(button);
button.addActionListener(changeColorAction());
}
for(String text : BUTTONS_LABELS){
JToggleButton button = makeButton(text);
buttonsPane.add(button);
shapeGroup.add(button);
button.addActionListener(changeShapeAction());
}
setDefaults();
frame.getContentPane().add(new Draw(), BorderLayout.WEST);
textArea = new JTextArea(0,20);
frame.getContentPane().add(textArea, BorderLayout.EAST);
frame.pack();
frame.setVisible(true);
}
private JToggleButton makeButton(String text) {
JToggleButton b = new JToggleButton(text); //use toggle buttons
b.setHorizontalAlignment(SwingConstants.LEFT);
b.setPreferredSize(new Dimension(100, 80)); //set preferred and let Layout manager do its work
return b;
}
private ActionListener changeColorAction() {
return e->{
color = colors.get(((JToggleButton)e.getSource()).getText());
frame.repaint();
};
}
private ActionListener changeShapeAction() {
return e->{
switch (((JToggleButton)e.getSource()).getText()){
case "Circle":
shape = Shape.CIRCLE;
break;
case "Rectangle":
shape = Shape.RECTANGLE;
break;
default: System.exit(0);
}
frame.repaint();
};
}
private void setDefaults() {
colorGroup.getElements().nextElement().setSelected(true);
color = colors.get(colorGroup.getElements().nextElement().getText());
shapeGroup.getElements().nextElement().setSelected(true);
shape = Shape.RECTANGLE;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new GUI().createAndShowGUI("My Gui"));
}
class Draw extends JPanel{
private final Point[] points; // an array to hold clicked points
private int mouseClicks = 0;
private static final int POINT_SIZE = 2;
Draw(){
setLayout(new BorderLayout());
setBackground(Color.WHITE);
setPreferredSize(new Dimension(200, 200));
JLabel help = new JLabel("Click 2 points to draw");
help.setHorizontalAlignment(SwingConstants.CENTER);
add(help, BorderLayout.PAGE_START);
JLabel timeLabel = new JLabel("current time here");
timeLabel.setHorizontalAlignment(SwingConstants.LEFT);
add(timeLabel, BorderLayout.PAGE_END);
points = new Point[2];
addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e) {
addPoint(e.getX(), +e.getY() );
}
});
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(color);
for(Point point : points)
if(point != null){
g.drawOval(point.x, point.y, POINT_SIZE, POINT_SIZE);
}
drawShape((Graphics2D)g);
}
private void addPoint(int x, int y) {
if(mouseClicks ==2){
mouseClicks = 0;
points[1] = null;
}
points[mouseClicks++] = new Point(x, y);
repaint();
}
private void drawShape(Graphics2D g2d) {
if(points[0] == null || points[1] == null) return;
if(shape == Shape.RECTANGLE) {
drawRectangle(g2d);
}else{
drawCircle(g2d);
}
}
private void drawRectangle(Graphics2D g2D) {
int minX = Math.min(points[0].x, points[1].x);
int minY = Math.min(points[0].y, points[1].y);
int maxX = Math.max(points[0].x, points[1].x);
int maxY = Math.max(points[0].y, points[1].y);
int width = maxX - minX;
int height = maxY - minY;
Rectangle2D.Double rectangle = new Rectangle2D.Double(minX, minY, width, height);
g2D.draw(rectangle);
}
private void drawCircle(Graphics2D g2D) {
int minX = Math.min(points[0].x, points[1].x);
int minY = Math.min(points[0].y, points[1].y);
int maxX = Math.max(points[0].x, points[1].x);
int maxY = Math.max(points[0].y, points[1].y);
double dx = maxX - minX;
double dy = maxY - minY;
double radius = Math.sqrt(dx*dx + dy*dy)/2;
double centerX = minX + dx/2;
double centerY = minY + dy/2;
g2D.draw(new Ellipse2D.Double(centerX - radius , centerY - radius, 2* radius, 2* radius));
}
}
enum Shape {
RECTANGLE, CIRCLE
}
}