为什么这个 JMenu 显示在这个 JPanel 上?
Why is the this JMenu being displayed on this JPanel?
This illustrates my problem
我正在尝试复制类似绘画的程序,但每当我单击屏幕时,菜单栏都会显示在面板区域中。除非我点击屏幕(绘制),否则它不会这样做。菜单栏添加在面板之前,任何帮助将不胜感激。
public class Main {
public static Frame frame;
public static Panel panel;
public static MenuBar menubar;
public static void main(String[] args) {
frame = new Frame();
panel = new Panel();
menubar = new MenuBar();
frame.setJMenuBar(menubar);
frame.addMouseMotionListener(panel);
frame.add(panel);
frame.setVisible(true);
}
}
public class Frame extends JFrame {
public Frame() {
setTitle("Paint");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
}
}
public class Panel extends JPanel implements MouseMotionListener {
public boolean isMouseDown = false;
public int x1,y1, x2, y2;
public Color colour = Color.BLACK;
public int size = 3;
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.setStroke(new BasicStroke(size));
g2.drawLine(x1 - 10, y1 - 80, x2 - 10, y2 - 80);
}
public void mouseDragged(MouseEvent arg0) {
x1 = x2;
y1 = y2;
x2 = arg0.getX();
y2 = arg0.getY();
repaint();
}
public void mouseMoved(MouseEvent arg0) {
x1 = x2;
y1 = y2;
x2 = arg0.getX();
y2 = arg0.getY();
}
public void mouseClicked(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
}
public class MenuBar extends JMenuBar {
JMenu file = new JMenu("File");
JMenu brush = new JMenu("Pen");
JMenu colour = new JMenu("Colour");
Font font = new Font("Times New Romans", Font.PLAIN, 18);
public MenuBar() {
//JMenuBar Code here, left black as very long
}
}
一个问题:您需要在 paintComponent 方法中调用 super.paintComponent(g);
。否则,JPanel 无法 house-keeping 自己绘制。
如果您希望绘图持续存在,那么要么创建一个线条的 ArrayList,然后在 for 循环中的 paintComponent 中绘制这些线条,要么更好地绘制到 BufferedImage 上,然后在 paintComponent 方法中显示该图像。
例如,
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyMain {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
MyPainting mainPanel = new MyPainting();
MenuCreator menuCreator = new MenuCreator(mainPanel);
JFrame frame = new JFrame("MyPainting");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.setJMenuBar(menuCreator.getMenubar());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
@SuppressWarnings("serial")
class MyPainting extends JPanel {
private static final int IMG_W = 600;
private static final int IMG_H = 450;
private static final int STROKE_W = 3;
private static final Stroke STROKE = new BasicStroke(STROKE_W);
private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
private Color drawColor = Color.BLACK;
public MyPainting() {
setPreferredSize(new Dimension(IMG_W, IMG_H));
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
private class MyMouse extends MouseAdapter {
private Graphics2D g2 = null;
private Point p0;
@Override
public void mousePressed(MouseEvent e) {
if (img == null) {
return;
}
g2 = img.createGraphics();
g2.setStroke(STROKE);
g2.setColor(drawColor);
p0 = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (p0 == null) {
return;
}
drawLine(e);
}
@Override
public void mouseReleased(MouseEvent e) {
if (p0 == null) {
return;
}
drawLine(e);
g2.dispose();
p0 = null;
}
private void drawLine(MouseEvent e) {
Point p1 = e.getPoint();
g2.drawLine(p0.x, p0.y, p1.x, p1.y);
repaint();
p0 = p1;
}
}
public void setDrawColor(Color drawColor) {
this.drawColor = drawColor;
}
public void clear() {
img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
repaint();
}
}
class MenuCreator {
private JMenuBar menubar = new JMenuBar();
private MyPainting myPainting;
public MenuCreator(MyPainting myPainting) {
JMenuItem clearDrawing = new JMenuItem(new AbstractAction("Clear Drawing") {
@Override
public void actionPerformed(ActionEvent arg0) {
if (myPainting != null) {
myPainting.clear();
}
}
});
JMenu fileMenu = new JMenu("File");
fileMenu.add(clearDrawing);
JMenu colourMenu = new JMenu("Colour");
for (MyColor myColor : MyColor.values()) {
colourMenu.add(new JMenuItem(new ColorAction(myColor)));
}
menubar.add(fileMenu);
menubar.add(new JMenu("Pen"));
menubar.add(colourMenu);
this.myPainting = myPainting;
}
public JMenuBar getMenubar() {
return menubar;
}
private class ColorAction extends AbstractAction {
private MyColor myColor;
public ColorAction(MyColor myColor) {
super(myColor.getText());
this.myColor = myColor;
}
@Override
public void actionPerformed(ActionEvent e) {
if (myPainting != null) {
myPainting.setDrawColor(myColor.getColor());
}
}
}
}
enum MyColor {
BLACK("Black", Color.BLACK), RED("Red", Color.RED), ORANGE("Orange", Color.ORANGE), BLUE("Blue", Color.BLUE);
private String text;
private Color color;
private MyColor(String text, Color color) {
this.text = text;
this.color = color;
}
public String getText() {
return text;
}
public Color getColor() {
return color;
}
}
您未能满足油漆链的要求...
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.setStroke(new BasicStroke(size));
g2.drawLine(x1 - 10, y1 - 80, x2 - 10, y2 - 80);
}
除了不需要public
,paintComponent
的工作之一就是准备Graphics
绘画的上下文。因此,您应该做的第一件事就是在进行任何自定义绘画之前致电 super.paintComponent
。
protected void paintComponent(Graphics g) {
super. paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.setStroke(new BasicStroke(size));
g2.drawLine(x1 - 10, y1 - 80, x2 - 10, y2 - 80);
}
Graphics
是一个共享上下文,它在需要绘制的其他组件之间共享,因此在绘制之前确保它已正确准备非常重要。
同样重要的是,在方法存在之前,您对上下文所做的任何重大修改(如转换或渲染提示)都会被撤消
我建议看一下 Performing Custom Painting and Painting in Swing 以更好地了解绘画系统的实际工作原理
This illustrates my problem
我正在尝试复制类似绘画的程序,但每当我单击屏幕时,菜单栏都会显示在面板区域中。除非我点击屏幕(绘制),否则它不会这样做。菜单栏添加在面板之前,任何帮助将不胜感激。
public class Main {
public static Frame frame;
public static Panel panel;
public static MenuBar menubar;
public static void main(String[] args) {
frame = new Frame();
panel = new Panel();
menubar = new MenuBar();
frame.setJMenuBar(menubar);
frame.addMouseMotionListener(panel);
frame.add(panel);
frame.setVisible(true);
}
}
public class Frame extends JFrame {
public Frame() {
setTitle("Paint");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
}
}
public class Panel extends JPanel implements MouseMotionListener {
public boolean isMouseDown = false;
public int x1,y1, x2, y2;
public Color colour = Color.BLACK;
public int size = 3;
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.setStroke(new BasicStroke(size));
g2.drawLine(x1 - 10, y1 - 80, x2 - 10, y2 - 80);
}
public void mouseDragged(MouseEvent arg0) {
x1 = x2;
y1 = y2;
x2 = arg0.getX();
y2 = arg0.getY();
repaint();
}
public void mouseMoved(MouseEvent arg0) {
x1 = x2;
y1 = y2;
x2 = arg0.getX();
y2 = arg0.getY();
}
public void mouseClicked(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
}
public class MenuBar extends JMenuBar {
JMenu file = new JMenu("File");
JMenu brush = new JMenu("Pen");
JMenu colour = new JMenu("Colour");
Font font = new Font("Times New Romans", Font.PLAIN, 18);
public MenuBar() {
//JMenuBar Code here, left black as very long
}
}
一个问题:您需要在 paintComponent 方法中调用 super.paintComponent(g);
。否则,JPanel 无法 house-keeping 自己绘制。
如果您希望绘图持续存在,那么要么创建一个线条的 ArrayList,然后在 for 循环中的 paintComponent 中绘制这些线条,要么更好地绘制到 BufferedImage 上,然后在 paintComponent 方法中显示该图像。
例如,
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyMain {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
MyPainting mainPanel = new MyPainting();
MenuCreator menuCreator = new MenuCreator(mainPanel);
JFrame frame = new JFrame("MyPainting");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.setJMenuBar(menuCreator.getMenubar());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
@SuppressWarnings("serial")
class MyPainting extends JPanel {
private static final int IMG_W = 600;
private static final int IMG_H = 450;
private static final int STROKE_W = 3;
private static final Stroke STROKE = new BasicStroke(STROKE_W);
private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
private Color drawColor = Color.BLACK;
public MyPainting() {
setPreferredSize(new Dimension(IMG_W, IMG_H));
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
private class MyMouse extends MouseAdapter {
private Graphics2D g2 = null;
private Point p0;
@Override
public void mousePressed(MouseEvent e) {
if (img == null) {
return;
}
g2 = img.createGraphics();
g2.setStroke(STROKE);
g2.setColor(drawColor);
p0 = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (p0 == null) {
return;
}
drawLine(e);
}
@Override
public void mouseReleased(MouseEvent e) {
if (p0 == null) {
return;
}
drawLine(e);
g2.dispose();
p0 = null;
}
private void drawLine(MouseEvent e) {
Point p1 = e.getPoint();
g2.drawLine(p0.x, p0.y, p1.x, p1.y);
repaint();
p0 = p1;
}
}
public void setDrawColor(Color drawColor) {
this.drawColor = drawColor;
}
public void clear() {
img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
repaint();
}
}
class MenuCreator {
private JMenuBar menubar = new JMenuBar();
private MyPainting myPainting;
public MenuCreator(MyPainting myPainting) {
JMenuItem clearDrawing = new JMenuItem(new AbstractAction("Clear Drawing") {
@Override
public void actionPerformed(ActionEvent arg0) {
if (myPainting != null) {
myPainting.clear();
}
}
});
JMenu fileMenu = new JMenu("File");
fileMenu.add(clearDrawing);
JMenu colourMenu = new JMenu("Colour");
for (MyColor myColor : MyColor.values()) {
colourMenu.add(new JMenuItem(new ColorAction(myColor)));
}
menubar.add(fileMenu);
menubar.add(new JMenu("Pen"));
menubar.add(colourMenu);
this.myPainting = myPainting;
}
public JMenuBar getMenubar() {
return menubar;
}
private class ColorAction extends AbstractAction {
private MyColor myColor;
public ColorAction(MyColor myColor) {
super(myColor.getText());
this.myColor = myColor;
}
@Override
public void actionPerformed(ActionEvent e) {
if (myPainting != null) {
myPainting.setDrawColor(myColor.getColor());
}
}
}
}
enum MyColor {
BLACK("Black", Color.BLACK), RED("Red", Color.RED), ORANGE("Orange", Color.ORANGE), BLUE("Blue", Color.BLUE);
private String text;
private Color color;
private MyColor(String text, Color color) {
this.text = text;
this.color = color;
}
public String getText() {
return text;
}
public Color getColor() {
return color;
}
}
您未能满足油漆链的要求...
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.setStroke(new BasicStroke(size));
g2.drawLine(x1 - 10, y1 - 80, x2 - 10, y2 - 80);
}
除了不需要public
,paintComponent
的工作之一就是准备Graphics
绘画的上下文。因此,您应该做的第一件事就是在进行任何自定义绘画之前致电 super.paintComponent
。
protected void paintComponent(Graphics g) {
super. paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.setStroke(new BasicStroke(size));
g2.drawLine(x1 - 10, y1 - 80, x2 - 10, y2 - 80);
}
Graphics
是一个共享上下文,它在需要绘制的其他组件之间共享,因此在绘制之前确保它已正确准备非常重要。
同样重要的是,在方法存在之前,您对上下文所做的任何重大修改(如转换或渲染提示)都会被撤消
我建议看一下 Performing Custom Painting and Painting in Swing 以更好地了解绘画系统的实际工作原理