使用按钮和鼠标控制画板
Use Buttons and mouse to control draw-board
我正在做一个应该像画图应用程序一样工作的 GUI。我当前的问题是向我的绘制线添加适当的功能并绘制矩形按钮。它们目前无法像我预期的那样工作。帮助将不胜感激。
我搜索了许多关于学习如何绘制形状的代码片段,但其中 none 展示了如何根据按钮是否激活它们来使它们工作,以及如何从绘制线条到绘制矩形。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class paintGUI extends JComponent {
// Image in which we're going to draw
private Image image;
// Graphics2D object ==> used to draw on
private Graphics2D g2;
// Mouse coordinates
private int currentX, currentY, oldX, oldY;
public paintGUI() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// save coord x,y when mouse is pressed
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
// coord x,y when drag mouse
currentX = e.getX();
currentY = e.getY();
if (g2 != null) {
// draw line if g2 context not null
//g2.drawLine(oldX, oldY, currentX, currentY);
//Need to implement these to their button
//g2.drawRect(oldX, oldY, currentX, currentY);
//g2.fillRect(oldX, oldY, currentX, currentY);
// refresh draw area to repaint
repaint();
// store current coords x,y as olds x,y
oldX = currentX;
oldY = currentY;
}
}
});
}
@Override
protected void paintComponent(Graphics g) {
if (image == null) {
// image to draw null ==> we create
image = createImage(getSize().width, getSize().height);
g2 = (Graphics2D) image.getGraphics();
// clear draw area
clear();
}
g.drawImage(image, 0, 0, null);
}
// now we create exposed methods
public void clear() {
g2.setPaint(Color.white);
// draw white on entire draw area to clear
g2.fillRect(0, 0, getSize().width, getSize().height);
g2.setPaint(Color.black);
repaint();
}
public void thin() {
g2.setStroke(new BasicStroke(3));
}
public void thick() {
g2.setStroke(new BasicStroke(10));
}
public void red() {
// apply red color on g2 context
g2.setPaint(Color.red);
}
public void black() {
g2.setPaint(Color.black);
}
public void magenta() {
g2.setPaint(Color.magenta);
}
public void drawLine() {
g2.drawLine(oldX, oldY, currentX, currentY);
}
public void drawRectangle() {
g2.drawRect(oldX, oldY, currentX, currentY);
g2.fillRect(oldX, oldY, currentX, currentY);
}
}
class GUIPaint {
JButton clearBtn, blackBtn, redBtn, magentaBtn, filledRectangleBtn, lineBtn, thinBtn, thickBtn;
paintGUI paintGUI;
ActionListener actionListener = e -> {
if (e.getSource() == clearBtn) {
paintGUI.clear();
} else if (e.getSource() == thinBtn) {
paintGUI.thin();
} else if (e.getSource() == thickBtn) {
paintGUI.thick();
} else if (e.getSource() == blackBtn) {
paintGUI.black();
} else if (e.getSource() == redBtn) {
paintGUI.red();
} else if (e.getSource() == magentaBtn) {
paintGUI.magenta();
} else if (e.getSource() == filledRectangleBtn) {
paintGUI.drawLine();
} else if (e.getSource() == lineBtn) {
paintGUI.drawRectangle();
}
};
public static void main(String[] args) {
new GUIPaint().show();
}
public void show() {
// create main frame
JFrame frame = new JFrame("Swing Paint");
Container content = frame.getContentPane();
// set layout on content pane
content.setLayout(new BorderLayout());
// create draw area
paintGUI = new paintGUI();
// add to content pane
content.add(paintGUI, BorderLayout.CENTER);
// create controls to apply colors and call clear feature
JPanel controls = new JPanel();
clearBtn = new JButton("Clear");
clearBtn.addActionListener(actionListener);
blackBtn = new JButton("Black");
blackBtn.addActionListener(actionListener);
redBtn = new JButton("Red");
redBtn.addActionListener(actionListener);
magentaBtn = new JButton("Magenta");
magentaBtn.addActionListener(actionListener);
lineBtn = new JButton("Line");
lineBtn.addActionListener(actionListener);
filledRectangleBtn = new JButton("Filled Rectangle");
filledRectangleBtn.addActionListener(actionListener);
thickBtn = new JButton("Thick Line");
thickBtn.addActionListener(actionListener);
thinBtn = new JButton("Thin Line");
thinBtn.addActionListener(actionListener);
controls.add(lineBtn);
controls.add(filledRectangleBtn);
controls.add(thinBtn);
controls.add(thickBtn);
controls.add(blackBtn);
controls.add(redBtn);
controls.add(magentaBtn);
controls.add(clearBtn);
// add to content pane
content.add(controls, BorderLayout.NORTH);
frame.setSize(800, 800);
// can close frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// show the swing paint result
frame.setVisible(true);
}
}
我需要程序正确响应,如果我单击线按钮能够画线,或者如果按下矩形按钮而不是绘制矩形。
基本思路是让控件(按钮、鼠标)改变属性(颜色、形状、描边、坐标)并调用重绘。
paintComponent
使用这些属性绘制正确的形状。
请注意您的代码的注释修改。
代码是one-file mre:整个代码可以复制粘贴到GUIPaint.java
和运行:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import swing_tests.PaintGUI.SHAPE;
public class GUIPaint {
private PaintGUI paintGUI;
public void showGui() {
JFrame frame = new JFrame("Swing Paint");
Container content = frame.getContentPane();
content.setLayout(new BorderLayout());
paintGUI = new PaintGUI();
content.add(paintGUI, BorderLayout.CENTER);
// create controls to apply colors and call clear feature
JPanel controls = new JPanel();
//todo: reduce duplicate code by having a method that constructs
//and adds a button
//todo: use button groups where only one button can be selected
JButton clearBtn = new JButton("Clear");
JButton blackBtn = new JButton("Black");
JButton redBtn = new JButton("Red");
JButton magentaBtn = new JButton("Magenta");
JButton lineBtn = new JButton("Line");
JButton filledRectangleBtn = new JButton("Filled Rectangle");
JButton thickBtn = new JButton("Thick Line");
JButton thinBtn = new JButton("Thin Line");
//todo: register an Action listner to each button by using lambda
//for example clearBtn.addActionListener(e-> paintGUI.clear());
ActionListener actionListener = e -> {
if (e.getSource() == clearBtn) {
paintGUI.clear();
}else if (e.getSource() == thinBtn) {
paintGUI.thin();
} else if (e.getSource() == thickBtn) {
paintGUI.thick();
} else if (e.getSource() == blackBtn) {
paintGUI.black();
} else if (e.getSource() == redBtn) {
paintGUI.red();
} else if (e.getSource() == magentaBtn) {
paintGUI.magenta();
} else if (e.getSource() == filledRectangleBtn) {
paintGUI.setShape(SHAPE.RECTANGLE);
} else if (e.getSource() == lineBtn) {
paintGUI.setShape(SHAPE.LINE);
}
};
clearBtn.addActionListener(actionListener);
blackBtn.addActionListener(actionListener);
redBtn.addActionListener(actionListener);
magentaBtn.addActionListener(actionListener);
lineBtn.addActionListener(actionListener);
filledRectangleBtn.addActionListener(actionListener);
thickBtn.addActionListener(actionListener);
thinBtn.addActionListener(actionListener);
controls.add(lineBtn);
controls.add(filledRectangleBtn);
controls.add(thinBtn);
controls.add(thickBtn);
controls.add(blackBtn);
controls.add(redBtn);
controls.add(magentaBtn);
controls.add(clearBtn);
content.add(controls, BorderLayout.NORTH);
frame.setSize(800, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()-> new GUIPaint().showGui());
}
}
class PaintGUI extends JComponent {
//states defined by enum
enum SHAPE {RECTANGLE, LINE}
private SHAPE shape; // store state
private static final Color BACKGROUND_COLOR = Color.WHITE;
private int startX, startY, endX, endY; //shape coordinates
private Color color = Color.BLACK; //draw color
private BasicStroke stroke = new BasicStroke(3); //draw stroke
private boolean isClear = false;
public PaintGUI() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
//save coord x,y where mouse was pressed
startX = e.getX();
startY = e.getY();
endX = startX; endY = startY;
clear(); //clear draw board
}
});
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
//update end coord as mouse dragged
endX = e.getX();
endY = e.getY();
repaint(); //keep repainting while drag lasts
}
});
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// draw white on entire draw area to clear
g2.setColor(BACKGROUND_COLOR);
g2.fillRect(0, 0, getSize().width, getSize().height);
if(isClear || shape == null){
isClear = false;
return;
}
//draw using color , stroke and shape attributes
g2.setColor(color);
g2.setStroke(stroke);
switch (shape){
case RECTANGLE:
drawFilledRectangle(g2);
break;
case LINE:
drawLine(g2);
break;
default:
break;
}
}
public void clear() {
isClear = true;
repaint();
}
public void drawLine(Graphics2D g2) {
g2.drawLine( startX, startY, endX, endY);
repaint();
}
public void drawFilledRectangle(Graphics2D g2) {
//to allow rectangle dragged from bottom up and left to right
//use min x and min y as origin
int x = Math.min(startX, endX);
int y = Math.min(startY, endY);
int width = Math.abs(endX-startX); //to account for negative width
int height = Math.abs(endY-startY); //or height
g2.fillRect(x,y,width,height);
}
public void thin() {
setStroke(3);
}
public void thick() {
setStroke(10);
}
public void setStroke(int width) {
stroke = new BasicStroke(width);
repaint();
}
public void red() {
setColor(Color.red);
}
public void black() {
setColor(Color.black);
}
public void magenta() {
setColor(Color.magenta);
}
void setColor(Color color){
this.color = color;
repaint();
}
void setShape(SHAPE shape) {
this.shape = shape;
clear();
}
}
我正在做一个应该像画图应用程序一样工作的 GUI。我当前的问题是向我的绘制线添加适当的功能并绘制矩形按钮。它们目前无法像我预期的那样工作。帮助将不胜感激。
我搜索了许多关于学习如何绘制形状的代码片段,但其中 none 展示了如何根据按钮是否激活它们来使它们工作,以及如何从绘制线条到绘制矩形。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class paintGUI extends JComponent {
// Image in which we're going to draw
private Image image;
// Graphics2D object ==> used to draw on
private Graphics2D g2;
// Mouse coordinates
private int currentX, currentY, oldX, oldY;
public paintGUI() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// save coord x,y when mouse is pressed
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
// coord x,y when drag mouse
currentX = e.getX();
currentY = e.getY();
if (g2 != null) {
// draw line if g2 context not null
//g2.drawLine(oldX, oldY, currentX, currentY);
//Need to implement these to their button
//g2.drawRect(oldX, oldY, currentX, currentY);
//g2.fillRect(oldX, oldY, currentX, currentY);
// refresh draw area to repaint
repaint();
// store current coords x,y as olds x,y
oldX = currentX;
oldY = currentY;
}
}
});
}
@Override
protected void paintComponent(Graphics g) {
if (image == null) {
// image to draw null ==> we create
image = createImage(getSize().width, getSize().height);
g2 = (Graphics2D) image.getGraphics();
// clear draw area
clear();
}
g.drawImage(image, 0, 0, null);
}
// now we create exposed methods
public void clear() {
g2.setPaint(Color.white);
// draw white on entire draw area to clear
g2.fillRect(0, 0, getSize().width, getSize().height);
g2.setPaint(Color.black);
repaint();
}
public void thin() {
g2.setStroke(new BasicStroke(3));
}
public void thick() {
g2.setStroke(new BasicStroke(10));
}
public void red() {
// apply red color on g2 context
g2.setPaint(Color.red);
}
public void black() {
g2.setPaint(Color.black);
}
public void magenta() {
g2.setPaint(Color.magenta);
}
public void drawLine() {
g2.drawLine(oldX, oldY, currentX, currentY);
}
public void drawRectangle() {
g2.drawRect(oldX, oldY, currentX, currentY);
g2.fillRect(oldX, oldY, currentX, currentY);
}
}
class GUIPaint {
JButton clearBtn, blackBtn, redBtn, magentaBtn, filledRectangleBtn, lineBtn, thinBtn, thickBtn;
paintGUI paintGUI;
ActionListener actionListener = e -> {
if (e.getSource() == clearBtn) {
paintGUI.clear();
} else if (e.getSource() == thinBtn) {
paintGUI.thin();
} else if (e.getSource() == thickBtn) {
paintGUI.thick();
} else if (e.getSource() == blackBtn) {
paintGUI.black();
} else if (e.getSource() == redBtn) {
paintGUI.red();
} else if (e.getSource() == magentaBtn) {
paintGUI.magenta();
} else if (e.getSource() == filledRectangleBtn) {
paintGUI.drawLine();
} else if (e.getSource() == lineBtn) {
paintGUI.drawRectangle();
}
};
public static void main(String[] args) {
new GUIPaint().show();
}
public void show() {
// create main frame
JFrame frame = new JFrame("Swing Paint");
Container content = frame.getContentPane();
// set layout on content pane
content.setLayout(new BorderLayout());
// create draw area
paintGUI = new paintGUI();
// add to content pane
content.add(paintGUI, BorderLayout.CENTER);
// create controls to apply colors and call clear feature
JPanel controls = new JPanel();
clearBtn = new JButton("Clear");
clearBtn.addActionListener(actionListener);
blackBtn = new JButton("Black");
blackBtn.addActionListener(actionListener);
redBtn = new JButton("Red");
redBtn.addActionListener(actionListener);
magentaBtn = new JButton("Magenta");
magentaBtn.addActionListener(actionListener);
lineBtn = new JButton("Line");
lineBtn.addActionListener(actionListener);
filledRectangleBtn = new JButton("Filled Rectangle");
filledRectangleBtn.addActionListener(actionListener);
thickBtn = new JButton("Thick Line");
thickBtn.addActionListener(actionListener);
thinBtn = new JButton("Thin Line");
thinBtn.addActionListener(actionListener);
controls.add(lineBtn);
controls.add(filledRectangleBtn);
controls.add(thinBtn);
controls.add(thickBtn);
controls.add(blackBtn);
controls.add(redBtn);
controls.add(magentaBtn);
controls.add(clearBtn);
// add to content pane
content.add(controls, BorderLayout.NORTH);
frame.setSize(800, 800);
// can close frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// show the swing paint result
frame.setVisible(true);
}
}
我需要程序正确响应,如果我单击线按钮能够画线,或者如果按下矩形按钮而不是绘制矩形。
基本思路是让控件(按钮、鼠标)改变属性(颜色、形状、描边、坐标)并调用重绘。
paintComponent
使用这些属性绘制正确的形状。
请注意您的代码的注释修改。
代码是one-file mre:整个代码可以复制粘贴到GUIPaint.java
和运行:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import swing_tests.PaintGUI.SHAPE;
public class GUIPaint {
private PaintGUI paintGUI;
public void showGui() {
JFrame frame = new JFrame("Swing Paint");
Container content = frame.getContentPane();
content.setLayout(new BorderLayout());
paintGUI = new PaintGUI();
content.add(paintGUI, BorderLayout.CENTER);
// create controls to apply colors and call clear feature
JPanel controls = new JPanel();
//todo: reduce duplicate code by having a method that constructs
//and adds a button
//todo: use button groups where only one button can be selected
JButton clearBtn = new JButton("Clear");
JButton blackBtn = new JButton("Black");
JButton redBtn = new JButton("Red");
JButton magentaBtn = new JButton("Magenta");
JButton lineBtn = new JButton("Line");
JButton filledRectangleBtn = new JButton("Filled Rectangle");
JButton thickBtn = new JButton("Thick Line");
JButton thinBtn = new JButton("Thin Line");
//todo: register an Action listner to each button by using lambda
//for example clearBtn.addActionListener(e-> paintGUI.clear());
ActionListener actionListener = e -> {
if (e.getSource() == clearBtn) {
paintGUI.clear();
}else if (e.getSource() == thinBtn) {
paintGUI.thin();
} else if (e.getSource() == thickBtn) {
paintGUI.thick();
} else if (e.getSource() == blackBtn) {
paintGUI.black();
} else if (e.getSource() == redBtn) {
paintGUI.red();
} else if (e.getSource() == magentaBtn) {
paintGUI.magenta();
} else if (e.getSource() == filledRectangleBtn) {
paintGUI.setShape(SHAPE.RECTANGLE);
} else if (e.getSource() == lineBtn) {
paintGUI.setShape(SHAPE.LINE);
}
};
clearBtn.addActionListener(actionListener);
blackBtn.addActionListener(actionListener);
redBtn.addActionListener(actionListener);
magentaBtn.addActionListener(actionListener);
lineBtn.addActionListener(actionListener);
filledRectangleBtn.addActionListener(actionListener);
thickBtn.addActionListener(actionListener);
thinBtn.addActionListener(actionListener);
controls.add(lineBtn);
controls.add(filledRectangleBtn);
controls.add(thinBtn);
controls.add(thickBtn);
controls.add(blackBtn);
controls.add(redBtn);
controls.add(magentaBtn);
controls.add(clearBtn);
content.add(controls, BorderLayout.NORTH);
frame.setSize(800, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()-> new GUIPaint().showGui());
}
}
class PaintGUI extends JComponent {
//states defined by enum
enum SHAPE {RECTANGLE, LINE}
private SHAPE shape; // store state
private static final Color BACKGROUND_COLOR = Color.WHITE;
private int startX, startY, endX, endY; //shape coordinates
private Color color = Color.BLACK; //draw color
private BasicStroke stroke = new BasicStroke(3); //draw stroke
private boolean isClear = false;
public PaintGUI() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
//save coord x,y where mouse was pressed
startX = e.getX();
startY = e.getY();
endX = startX; endY = startY;
clear(); //clear draw board
}
});
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
//update end coord as mouse dragged
endX = e.getX();
endY = e.getY();
repaint(); //keep repainting while drag lasts
}
});
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// draw white on entire draw area to clear
g2.setColor(BACKGROUND_COLOR);
g2.fillRect(0, 0, getSize().width, getSize().height);
if(isClear || shape == null){
isClear = false;
return;
}
//draw using color , stroke and shape attributes
g2.setColor(color);
g2.setStroke(stroke);
switch (shape){
case RECTANGLE:
drawFilledRectangle(g2);
break;
case LINE:
drawLine(g2);
break;
default:
break;
}
}
public void clear() {
isClear = true;
repaint();
}
public void drawLine(Graphics2D g2) {
g2.drawLine( startX, startY, endX, endY);
repaint();
}
public void drawFilledRectangle(Graphics2D g2) {
//to allow rectangle dragged from bottom up and left to right
//use min x and min y as origin
int x = Math.min(startX, endX);
int y = Math.min(startY, endY);
int width = Math.abs(endX-startX); //to account for negative width
int height = Math.abs(endY-startY); //or height
g2.fillRect(x,y,width,height);
}
public void thin() {
setStroke(3);
}
public void thick() {
setStroke(10);
}
public void setStroke(int width) {
stroke = new BasicStroke(width);
repaint();
}
public void red() {
setColor(Color.red);
}
public void black() {
setColor(Color.black);
}
public void magenta() {
setColor(Color.magenta);
}
void setColor(Color color){
this.color = color;
repaint();
}
void setShape(SHAPE shape) {
this.shape = shape;
clear();
}
}